From:
再三考虑,决定把今天的面试总结一下,算是对自己的总结,如果能顺便给正在找工作的朋友有所帮助,那就不能再好了。
ps: 今天面试真的好累, 昨晚没睡好,今天早上起床 也没有吃早饭,饿着肚子跑去面试的。话痨了、、
今天面试了两家公司,早上出门前,感觉两家稳稳地可以拿下,but结果并不如人意。。
面试公司:健德门 附近某公司
面试时间:5月25日 11:00 AM.
面试结果:最后聊得工资是 14薪/16K 每天有饭补 。(但是没有当场给offer,详情在下面介绍)
面试过程:
11:00 公司开会(我等,我在等)
12: 00-14:00 跟两位 android程序员+技术总监 pk。
14:00-15:00 :跟两位人事谈人生理想.
面试记录:
11:00 : 到公司,前台后面 摆着桌球, 各种水果,感觉公司气氛还不错。
到公司的时候,已经11.00多了,刚好周一他们团队开会,我就被一个的小哥带到一个会议室等带,给倒了杯水,就把哥丢在那了。在会议室,听到隔壁的会议室,有来参加面试的和人事在那侃大山,略搞笑,依稀记得 还问了,假如 有其他公司 高薪挖你走2828之类的问题。(PPS:面试 技术是一方面,人事也不可以忽略。)
12:00: (一轮PK)终于开会结束了,哥可是饿着肚子呢, 这家公司没有笔试题,直接一个搞Android的哥们进来,简单介绍了一下 ,就聊起来了。首先 J哥 简单介绍了一下 在上一家公司 担任什么角色,平时开发流程 之类的,然后J哥 就说大概在公司开发了有5款APP,自己私下接过一款私活,然后自己没事也做了两款应用,然后J哥 把应用展示给他看,他看了连连称赞不错啊。。。(lalala,其实都是J哥网上巴拉的项目啦。)
(然后大体给他介绍了 项目基本框架,是 v4包里的 SlidingPaneLayout 嵌套了实现了轮询效果 自定义的viewpager 。然后 具体界面是用的瀑布流,项目的关键就是 对 图片的处理,因为有N张 图片,但是并没有卡顿,所以就说了 自己用 了开源的imagedownloader 和 volley 以及自己定义的 lrucache 缓存 bitmap 对象,这里大家一定要把图片的三级缓存 自己了解清楚,基本面试会问到。)
其实 当面试问你 如何避免oom ,内存泄露导致的原因,以及如何处理大图片等等,其实都是 如何优化内存。
可以按照我自己总结的回答,你可以说,这个问题 ,跟 oom 以及 内存泄露,其实是一样的,关键 就是 如何 优化内存,避免不必要的 内存泄露,
而 内存泄露 的原因 ,我总结了 4点,
1. 匿名内部类,和非静态内部类, 举个栗子:我们用handler 进行线程间 假如 我们在activity中这样定义 handler :
然后,我们用 右键 选中工程 运行 lint工具 , android tools---run lint ,就会提示我们这样一个`warning: In Android, Handler classes should be static or leaks might occur.`。
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- mImageView.setImageBitmap(mBitmap);
- }
- }
就是 ,推荐我们 把handler 定义成static,具体 看这里解释的很详细:http://www.linuxidc.com/Linux/2013-12/94065.htm
类似的还有 匿名子线程。
2.还是 拿网上的 栗子来说,
- Vector v = new Vector( 10 );
- for ( int i = 1 ;i < 100 ; i ++ ){
- Object o = new Object();
- v.add(o);
- o = null ;
- }
3, 当我们操作数据库的时候,我们在执行完 相应的crud 方法后,我们没有关闭 cursor .close()或者 db.close(),也同样会占用内存、因为只有关闭连接后,才会被GC 回收。
4.继续举个栗子
J哥 亲自 实践了下,发现问题了,这个网上的栗子 是错的。实际上 是可以remove掉得、真是个悲伤地故事。这个栗子是不正确的。。网上好有一片这样的文章,都是这个栗子。。
- Set<Person> set = new HashSet<Person>();
- Person p1 = new Person("唐僧","pwd1",25);
- Person p2 = new Person("孙悟空","pwd2",26);
- Person p3 = new Person("猪八戒","pwd3",27);
- set.add(p1);
- set.add(p2);
- set.add(p3);
- System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素!
- p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变
- set.remove(p3); //此时remove不掉,造成内存泄漏
- set.add(p3); //重新添加,居然添加成功
- System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素!
这里 看下其他网站上的总结吧 :强烈推荐
http://developer.51cto.com/art/201111/302465.htm。很详细。
OK。还有最后一点,就是 关于图片的,bitmap对象的及时释放,这里 就不细说了,等在图片三级缓存一起去总结。
此时 感觉 对面的android 小哥 已经被我吸引了。好像很认真的在听我讲课一样
。
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
然后, 他问我问题。我大体总结了一下。
面试官01问:有没有自定义过view。
J哥回答:这个很常见,我自己定义过很多,比如 下拉刷新,上拉加载更多数据的listview,类似github 上面的pulltorefreshlistview。
还有图片轮询播放的viewpager,也是 继承viewpager,然后自己开启一个线程,去控制 切换的。还比如,跑马灯效果的textview ,scrollview与 listview 相互嵌套 导致 listview 高度计算不正确,我也是 自定义listview,复写了 onmeaure方法,然后解决冲突的。在比如 一些开源的 可以放大缩小的图片,我也是做过,主要是对onmeasure 方法,onlayout方法,ondraw 方法的复写。以及复写一下 view 自己的 touch事件等等,奥 对了,我们公司当时有需求 做一个 锁屏软件,侧滑解锁的,我也是自己定义的,然后展示给他看了一下,当时 那篇文章在这里。传送门
http://blog.csdn.net/u011733020/article/details/41863861。
面试官01问:listview的优化、
J哥回答:(PS:这种问题,基本上 都快被问烂了,但是没办法 还是要回答。) listview 作为最常见的 用来显示数据的view ,一般 从四个方面 去优化。
1 ,复用convertview, 不然假如有1000条数据,那么我们滑动,就会 产生1000个convertview ,这对内存是很大的浪费,所以 我们一定要复用。
2. 减少 findviewbyid 的次数, 因为 每次 去 执行 findviewbyid 也是要消耗资源的,我们要尽可能的减少,通常 我们定义一个viewholder,去管理 这些id ,然后通过tag 去直接拿到 id。
3, 分页加载,延迟加载 预加载。 这个在我们以前项目,有一个榜单,数据量很大,一次请求过来的数据量很大,这样有两个问题,一个是 请求网络 时间可能会很长,另一个展示数据 上面 体验对不是很好,所以 我们做了 第一次加载 20条,然后每次请求 再去 加载10条新数据。
4.就是 对 listview 中一些 类似头像, 图片的 优化。这里 类似 三级缓存,推荐大家看一下 开源 的universal-image-loader 的源码。或者 这篇文章
http://www.jb51.net/article/38162.htm,J哥有时间 专门写一篇过于 图片缓存的。
面试官01问: 看你简历上面 做过 社交,通信这块是怎么做的。
J哥回答:我看 咱们公司 也用到了 聊天,咱们公司是 自己做的 还是 用的第三方的类似 环信的。结果被J哥猜中,他说 是集成的环信(但是 有丢包现象,所以打算自己做通信)。
OK,J哥说 ,我们 项目中聊天 是基于xmpp协议的做的,在没有android 以前 ,java 有个 开源的 smack ,android 上 现在有一个asmack ,其实 就是移植到android 中来了, 服务端是基于 openfire的 ,我们就是做的 openfire+asmack 的 聊天,这个原理主要 就是 绑定 ip 拿到 connection 然后 connect ,然后进行通信,我说,这个 跟http请求 其实原理上一样,都是 绑定ip,然后 设置一些property,然后通过类似流进行通信的, asmack,其实底层 就是xml通信的。
面试官01问: touch 事件的传递机制,还特意画了,一个 就是 button LinearLayout 嵌套 。
J哥回答:就是这个, 这也难不倒我。因为J哥觉得 这个问题肯定会问到 所以 早有准备,这里 我就大体说下结论,详细原理 给你传送门。
我回答,这个很简单,只要你继承一下 button 和 linearlayout 复写一下 三个方法 dispatchtouchEvent onInterceptTouchEvent 和onTouchEvent .就能很清楚的明白 传递的过程,我给你总的说下结论的,点击这个button,一般是 外面的父控件 先响应这个down 事件,然后 往子类里面传递,让子类 在往子类的下一级子类去传递,让最终的孩子去决定是不要要消费掉这个点击事件,如果消费掉,那么父类将不会响应,如果子类不消费,那么会退回到次级子类,然后看是否要消费,这样,一句话 就是父传子, 子决定要不要,不要 然后传回去。
这里有很详细 很详细的介绍, 包裹事件的分发。所以我就不罗嗦,
http://blog.csdn.net/yanbober/article/details/45887547?ref=myread
面试官01问: 项目中图片的优化。
J哥回答:我给他展示的项目 其中有一款app 是有很多图片 ,但是 很流畅,也没有oom。关于图片 优化,一般我们采用三级缓存,1 。内存加载 2.本地加载 3 网络加载。 首先 我们看 内存中有没有,有直接拿来用,这里 我项目里是这样做的,我先获取一下 分配给我们应用的可用内存是多少,然后 拿1/4 或者 1/8做一个 lrucache. 把我们的bitmap 对象添加进去。有些比较常用的图片,我会保存到本地,避免每次重复联网下载。结合 开源的 afinal universalimageloader 以及 13年谷歌官方推荐的volley(号称是 asynchttpclient 和
universalimageloader)的结合、 所以 在我的项目中基本没有遇到过图片导致的oom 问题,对于单张的 大图片,我也会利用bitmapFactory,进行计算大小,然后 计算手机分辨率,进行定量的 压缩 处理。
面试官问: GC的回收
J哥回答:我说。GC 回收 应该不只是按照一种方式,应该有多种不同的算法,我看过谷歌 官网介绍的一点,有这样一块区域,他分为 latest(最近) middle(中等)permanent(永久的),这样三块子区域。里面分别存放,刚刚被创建的,以及 时间 靠后的,很久的,对象,不断地新对象 往latest里面添加,当达到相应对象区域的阀值的时候,就会触发GC,GC 进行回收的时候,对于latest 中回收的速度是最快的,而permanent 相对是最久的,而时间 也跟 每块区域中对象的个数有关系, 还有一种算法,是根据最近被引用的时间,或者 被引用的次数 去进行 GC的、、这里随便扯就是了。GC 回收并不是立即执行的。是不定时的。GC回收的时候 会阻塞线程,所以代码中要避免创建不必要的对象,例如for循环中 创建大量对象 就会容易引起GC。 当我们也可以主动 在方法中执行system.gc() 去手动释放一些资源。
面试官01问: 怎么避免 viewpager 预加载 fragment的、
J哥回答:这个问题 我也碰到过,我们都知道,viewpager 它本身会预加载 左右两个 和当前一个对象、而 我们viewpager setOffscreenPageLimit(0) 不生效因为看源码知道 这个方法 默认最少也要加载一个。所以 这个fragment 还没有被当前页面显示出来,已经夹在好了,有可能数据不是最新的,我是在 setuservisibilityhint() 这个方法中跟参数 动态去判断 要不要刷新的。
问了一圈,这个哥们大概没什么问的了,然后 就让我等一下,说让他们技术总监过来 。 我就等。。。
然后等了几分钟,进来一小姑娘,坐下,看了我简历,我以为是人事,来跟我谈人生理想。结果,没说几句话,让我讲一下我的项目。我qu,惊呆我了。我问,你也是做android的,我去,是这样的、、把J哥吓到, 然后问了J哥几个问题。
Android 小姑娘问: 看你项目中的listview 中item类型 是统一的,而加入 item 差别挺大的 你怎么复用。
J哥回答:J哥装作很牛的样子说,我暂时想到两种方法,1.给这个对象 加一个type 然后 根据 type 去复用,或者 把这几种类型 一起加载,然后控制显示隐藏。然后 我反问小姑娘,假如 我这里 有一百条数据,这一百条是无序的,包含了 10种 item类型,你有没有什么好方法 去处理这个问题,
小姑娘说,你不是定义了类型吗,我们就是 通过type 去判断的。
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
Android 小姑娘问: onAttch onDetach 还是 onAttachedToWindow onDetachedFromWindow
J哥回答
:其实 那个小姑娘忘记这两个方法了。我说什么方法,她说onAttachIntent() 和 onDetachIntent(). 反正 J哥是没听说过, 我只见过 onAttach , 但是 这个方法 我也没用过。我就问她,这两个方法是做什么的,小姑娘跟我说 是 把子view绑定到界面上的,那么的话 应该是
onAttachedToWindow
onDetachedFromWindow方法了,小姑娘说: 在这个方法 可以计算子 view的高度宽度,在 oncreate 里面不能计算,其实虽然刚开始 在oncreate里面是不能计算,但是还是有方法计算的,(本人觉得面试 问你 API 是 最2的了,忍不住吐槽下,我遇到过,Camera 拍照,问我获取 一个图片 还是 视频的 方法,我去百度 一下,随便就知道,真是不懂 为什么会问方法。随便一个程序员 都会百度。。)
跟小姑娘聊得其他问题 不太记得了,感觉这个女程序员啊。。就问方法 给我的印象不太好,不管方法用没用到,我觉得面试 直接问你方法 好2 好2...
总监: 问我 做没做过通信这块,能不能做这一块。
J哥回答:
,我说做过,通信有几种协议的,我们用的 是xmpp协议的 ,服务器 是 基于apache的 openfire 搭建的,客户端 是用的asmack。还有一些 其他协议的 ,比如我知道有些项目中用的 soap协议的,还有ip 协议的。PS:反正就是扯
我说 通信 客户端这一块 我没问题,但是 服务端 我 从工作以来 一直偏向 android 移动端开发,后台这一块,如果数据量大了,还要考虑并发之类的,我是做不了,让我做个tomcat搭建的demo 我可能可以。
![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
其他也是随便聊了下,然后 就说,让人事来跟我谈理想了。
总监: 问我 什么时候能上班
J哥回答:
我说 这个看公司需求啦。
![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
其他也是随便聊了下,然后 就说,让人事来跟我谈理想了。
这里 感觉应该没问题了。差不多能拿下了。
人事1:一进来,就问东问西。问加班看法啊,他们公司技术 一般都八九点走啊。说七点基本没有走的啊、、、
J哥回答
:我说,一般遇到项目加功能 ,版本升级,等等 这些加班都没什么,只要不是一直在加班。。。。这里每个人自己看法就好了、、
反正人事 是一直跟我强调这个,她不停强调 我就暗暗下决心,薪资 我是不会要低了。
人事1:看你还年轻啊,还能拼一拼啊、、、、
J哥回答
:我说现在 这几年对我人生规划也算比较重要的时期,也是过一年少一年了,其实她的意思 还是侧面强调加班。。。。日了UZI了。
中间一堆废话,然后 我问了她 公司一般上下班时间啊。。之类的有没有技术交流啊,之类的。。。
最后到关键问题上啦,最关心的,薪资问题。
人事1:期望薪资
J哥回答
:我说16K左右吧。她问 你以前公司多少 握手 15K。她说她们公司 是 14薪。反正 我还是说16K。她说 那好,你等下,然后就出去了。
不知道 跟什么人 讨论了许久,然后又来一个 可能是人事吧。又进来,问了一遍,也问了薪资。。哥还是说16K 。 。。估计是她们公司想要我,但是又觉得有点超出她们薪资期望吧,当场被没有给什么offer。然后就有点婉拒的说,两天给我答复,心里很气愤,饿着肚子 面试到三点,竟然婉拒、、、
反正我是很生气,我说,好,然后我就走。结果,没过一个小时,人事又打电话来,非要约我 见一下她们CEO。这是什么鬼,难道她们CEO要给我煲汤 了?我说可以,然后时间定在后天了,,反正心灵鸡汤对我是没用了、
OK ,这家面试 先写到这里,下面 下午还有一家,等下在写。准备睡觉。今天面试回来,累的就睡着了,晚上十点多才醒过来,想了想还是 把今天面试的过程总结一下。
-------------------------------待续 -------------------------
=====================================================================================