面试题总结并附上答案2
Java基础
byte,shrot,int字节数,范围什么的
设计模式
- Activity继承BaseActivity的设计模式是模板方法
- 事件分发是责任链模式
Android加载布局流程
提问的是Activity中setContentView的父布局
流程:
-
Activity setContentView—>Window setContentView—>PhoneWindow setContentView—->PhoneWindow installDecor—–>PhoneWindow generateLayout——>PhoneWindow mLayoutInflater.inflate(layoutResID, mContentParent);
-
Activity 类中有一个Window抽象类的实现PhoneWindow类,该类中有个内部类DecorView,继承自FrameLayout,在DecorView容器中添加了根布局,根布局中包含了一个id为 contnet的FrameLayout 内容布局,我们的Activity加载的布局xml最后添加到 id为content的FrameLayout布局当中了。用一个图来描述,如下:
总结:
-
1.关于requestWindowFeature(Window.FEATURE_NO_TITLE); 去除标题栏的疑问,如果你自己的xxxActivity是继承自Activity,那么恭喜你使用以上方法可以去除标题栏,如果你自己的xxxActivity是继承自AppCompatActivity或者ActionBarActivity,那么很遗憾告诉你,此次系统默认的标题栏已经在主题中去除,此时显示的标题栏是ActionBar导航栏,如果需要去除导航栏,你可以通过如下代码:getSupportActionBar().hide();来隐藏导航栏。
-
2.requestWindowFeature(Window.FEATURE_NO_TITLE);方法需要在 setContentView方法之前使用,由上面 Step5分析可得,设置Activity Window 特征是在setContentView方法中设置的,因此,如果需要改变Activity Window窗口特征,需要在setContentView方法之前。其实这里有疑问???为什么设置全屏的方法
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
可以在setContentView之后呢???求解。
从setContentView方法分析Android加载布局流程
Dialog加载绘制
-
AlertDialog和Activity一样,内部有一个Window,我们构造AlertDialog.Builder,通过Builder设置Dialog各种属性,,这些参数会被放在一个名为P(AlertController类型)的变量中,
-
在调用AlertDialog.Builder.create方法的时候,内部首先会new一个 AlertDialog,AlertDialog的父类Dialog的构造函数中会new一个PhoneWindow赋值给AlertDialog中的Window,并且为它设置了回调。
-
AlertDialog创建之后执行apply方法,将P中的参数设置赋值给Dialog,后我们调用Dialog.show方法展示窗口,内部调用dispatchOnCreate,最终会走到setContentView,到此Dialog的Window和Dialog视图关联到了一起,
-
最后执行mWindowManager.addView方法,通过WindowManager将DecorView添加到Window之中,此时Dialog显示在了我们面前。
Android源码解析Window系列第(二)篇—Dialog加载绘制流程
Context的应用场景
提问的是Service能不能创建dialog
自定义View
构造函数方法参数
构造函数参数最多有四个。简单总结下:
-
Context - View中随处都会用到。
-
AttributeSet - XML属性(当从XML inflate的时候)。
-
int defStyleAttr - 应用到View的默认风格(定义在主题中)。
-
int defStyleResource - 如果没有使用defStyleAttr,应用到View的默认风格
除了Context,其它的参数只是用来通过XML属性配置View的初始状态(从布局,style以及theme中)。
自定义View基础
- (1)自定义View基础 - 最易懂的自定义View原理系列
- (2)自定义View Measure过程 - 最易懂的自定义View原理系列
- (3)自定义View Layout过程 - 最易懂的自定义View原理系列
- (4)自定义View Draw过程- 最易懂的自定义View原理系列
为什么handler的runnable函数是在主线程,而thread的runnable的是在子线程,handler创建的2种方法
多进程需要注意和解决的问题
RecyclerView怎么实现一些复杂的效果
我们知道recyclerview实现GridView效果只需配置一下参数就行了
可以看到GridLayoutManager需要传递两个参数,一个是上下文对象,另一个是一行显示几列的参数常量,既然这个常量可以指定那么是不是这个值可以去控制呐,答案当然是yes
我们会注意到GridLayoutManager里边有个setSpanSizeLookup方法,本篇的重点就是这个方法(这个方法具体意义大家可以网上搜索,会有很多相关介绍,以及通过它实现一些复杂的布局,再次不做过多讨论)
其实getSpanSize返回值就是控制每行有几列的,根据这个思路我们不妨试试。因为recyclerview填充数据是根据adapter实现的,我们就把给adapter的数据源同样在setSpanSizeLookup这个方法里边判断一下不就行了吗? 根据这个思路于是有了下面的代码
Android studio的使用,例如debug
手写单例,双层加锁,为什么要双判断
git 命令的使用 打tag
Git-命令行-使用 Tag 标记你的代码 Git 基础 - 打标签
性能优化
WebP与Png的区别
优点
在质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小40%。 根据Google较早的测试,WebP的无损压缩比网络上找到的PNG文件少了45%的文件大小,即使这些PNG文件在使用pngcrush和PNGOUT处理过,WebP还是可以减少28%的文件大小
缺点
- 编解码速度偏慢
目前WEBP与JPG相比较,编码速度慢10倍,解码速度慢1.5倍,实际上对于绝大部分的网络应用而言,图片都是静态文件,所以对于用户使用只需要关心解码速度即可。针对1.5倍的解码速度是否影响用户体验的问题,我们可以看看ebay团队的这个测试,50张同样质量的WEBP与jgp加载的速度对比:[http://www.webpagetest.org/video/view.php?id=130125_7b15e676f5fa0b736f247ff0ed36517e64d9c9ea](http://www.webpagetest.org/video/view.php?id=130125_7b15e676f5fa0b736f247ff0ed36517e64d9c9ea
此测试表明,webp虽然会增加额外的解码时间,但是由于减少了文件体积,缩短了加载的时间,实际上文件的渲染速度反而变快了。
- 浏览器支持不全
移动端Android4.0以上、PC端chorme 10+(14 ~ 16 有渲染bug)、opera 11+ 、safri均支持webp格式图片。firefox曾经拒绝支持webp,今年也重启了关于webp第二次讨论https://bugzilla.mozilla.org/show_bug.cgi?id=856375
- WebP作为一种较新的图片格式,在一定程度上提高了图片的压缩率,但目前压缩表现尤其对于动图,还较不稳定。
而Android对WebP动图支持较差,目前仅有Fresco一个开源库支持,要引入项目中,需进一步分离出无关的功能,并考虑最低仅支持API 9的问题。
程序启动,内存怎么分配的
具体代码的优化,对象不要多创建,因为多创建会导致多引用
(现场写出对具体的代码进行优化,当时考的是对象的多次创建怎么优化,具体情况具体分析)
事件分发
自定义View
Handler+Message+Looper
从Handler+Message+Looper源码带你分析Android系统的消息处理机制 Android Handler机制(一)—Message源码分析
21.移动网络通信机制,对Socket通信、TCP/IP和HTTP
22.sqlite的使用 怎么升级,sqlite不能删除字段
android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
ALTER TABLE table-name ADD COLUMN column-name column-type 例如在student表中添加一列名为name,类型为varchar: alter table student add column name varchar;
alter table student drop column name // 该行在SQlite中不能用,SQlite不支持drop
sqlite中是不支持删除列操作的,所以网上alter table table_name drop column col_name这个语句在sqlite中是无效的,而替代的方法可以如下:
1.根据原表创建一张新表
2.删除原表
3.将新表重名为旧表的名称
示例例子如下
1.创建一张旧表Student,包含id(主码),name, tel
create table student (
id integer primary key,
name text,
tel text
)
2.给旧表插入两个值
insert into student(id,name,tel) values(101,”Jack”,”110”)
insert into student(id,name,tel) values(102,”Rose”,”119”)
结果如图
3.接下来我们删除电话这个列,首先根据student表创建一张新表teacher
create table teacher as select id,name from student
结果如图
可以看到tel这一列已经没有了
4.然后我们删除student这个表
drop table if exists student
5.将teacher这个表重命名为student
alter table teacher rename to student
结果演示:
select * from student order by name desc(desc降序, asc升序)
这样就可以得到我们想要的结果了。
另外:给自己一个提示,在android sqlite中的查询语句如果是text类型的别忘了给他加上””来指明是String类型的,例如:
Cursor c = mSQLiteDatabase.query(TABLE_NAME, null, NAME + “=” + “/”” + name + “/””, null, null,null, null);
23.查看大图功能设计注意的点
- 图片展示优化 缓存
- 缩略图,大图
算法
- int类型的变量 a,b,不能用第三个变量交换a与b
a=a^b
b=a^b
a=a^b
结题关键是:异或运算具有交换性
- 有1元去买桃,两种方案,第一种是买2个桃送一个,第二种是三个桃核换一个桃,问最多能买多少个桃?
public int funCount(int money,int core) { if (core >= 3) { return 1 + funCount(money, core - 3 + 1); } if (money >= 22) { return 3 + funCount(money - 22, core + 3); } else if (money >= 11) { return 1 + funCount(money - 11, core + 1); } return 0; }