——————————————————————————————————————————————————————————来自网络1——————————————————————————————————————————————————————————
Java篇※
- Java有没有内存泄露
- Java垃圾收集
- 软引用
- 匿名内部类能不能使用外部类变量
答:能,因为非静态内部类持有外部类的引用。
Android篇※
- Google为什么选择Java
- Android常用的布局
- 进程间如何通讯(腾讯也问过)
答:广播、AIDL(可以启动其他App的服务,即跨进程启动服务。)、ContentProvider、Messager
广播:略(在其中一个App静态注册,另一个发广播时带action)
一。AIDL:
1)
aidl:*.aidl中编写个接口,比如aidlInterface
Server端:Manifest的对应Service的action里自定义一个名字 --> Service中实现onBind(return一个mbinder),mbinder是aidlInterface.Stub的对象,其中实现一些会被调用的函数-->
Client端:创建ServiceConnection对象sc并复写其中的onServiceConnected方法,然后调用bindService(intent,sc,...)即可,Intent要SetAction(),里面写manifest里的action内容
调用函数:在onServiceConnected中通过AidlInterface.Stub.asInterface(iBinder)来获得aidl对象然后就可以直接调用里面定义的方法了
2)支持的数据类型:基本类型、String、ListMap等、AIDL自动生成的接口、实现Parcelable接口的
3)使用场景:允许来自不同的客户端访问你的服务,并且需要处理多线程问题时你才必须使用AIDL。
4)原理:在Binder之上的封装(主要封装了Binder.transact()和Binder.onTransact()),担任RPC的角色。帮我们完成了参数序列化发送以及解析返回数据等工作。相当于是个代理,IDE会为我们在gen目录中创建相应的文件。
抽象层次从底到顶:Asheme->Binder->AIDL->Intent。关于Binder的部分,建议参考job_android.pdf中的部分。
二。Messenger:类似平时用Handler发信息。
http://blog.csdn.net/yanbober/article/details/48373341
1)与AIDL对比:
无需编写接口
Server端:(同)Manifest的对应Service的action里自定义一个名字 --> (类似)Service中实现onBind(return一个mRemoteMessage.iBinder),这个mRemoteMessage是new Messenger(handler)的对象,handler与平时类似在类中new一个并实现handlerMessage
--> (不同)可判断下msg.what(c和s协商好),然后取出msg.replyTo中的Messenger(Client端传过来的,为了给client sendMessage),用这个Messenger对象send (Message)给Client
Client端:(同)创建ServiceConnection对象sc并复写其中的onServiceConnected方法,然后调用bindService(intent,sc,...)即可,Intent要SetAction(),里面写manifest里的action内容;
--> (不同)定义一个Handler用来处理Server返回的message;
调用函数:(不同)在onServiceConnected中通过new Messenger(iBinder)(对就是onBind返回的iBinder)获得一个Messenger,然后用刚才这个Messenger,send一个Message(记得设定msg.replyTo为自己的一个Messenger(Handler handler)给Server
2)实现了IPC通信,实际使用了AIDL进行通信,但是和直接使用AIDL不同的是Messenger利用了Handler处理通信,不支持并发、线程安全。
3)原理(源码):继承parcelable。内含一IMessenger对象
public Messenger(Handler target) {mTarget = target.getIMessenger();} 而Handler中的getIMessenger()返回的是一单例的MessengerImpl对象,它调用了这个Handler的sendMessage方法。(不太懂:mTarget其实就是一个Handler中单例的IMessenger远程IPC接口MessengerImpl。)
public Messenger(IBinder target) {mTarget = IMessenger.Stub.asInterface(target);} 而这也就是在AIDL篇的“调用函数”干的事情
三.ContentProvider:
- 如何解决APP界面卡顿
答:通常原因有,UI线程耗时操作多、布局结构复杂/过度绘制、自定义控件等。此外还可以用ViewStub啥的、缓存等等来优化。(ViewStub可以指定Layout,一旦inflate就不再接受变化) - 举一个内存泄露的例子
答:delay时间超长的Handler,Activity本来该被回收时候就会被泄露(Java非静态内部类会隐式持有外部类的引用,即this$0,静态的不会)
另外举个例子来说,整个引用路径就是GC Roots引用着Thread,Thread引用着我们的Activity,而Activity中包含了Bitmap对象。这时候当前界面已经退出了,但是Thread 仍持有着Activity 的引用,导致Activity 和它引用的内存例如Bitmap不能被回收。 - 数据库升级怎么解决? (不懂)
- AsyncTask
- 用过什么第三方图片加载库
- java进程和虚拟机的关系,java和C++如何相互调用
答:http://blog.csdn.net/mr_raptor/article/details/30115113
每个JVM虚拟机进程在本地环境中都有一个JavaVM结构体
JNIEnv是当前Java线程的执行环境,一个JVM对应一个JavaVM结构.
JNIEnv结构也是一个函数表,在本地代码中通过JNIEnv的函数表来操作Java数据或调用Java方法。也就是说,只要在本地代码中拿到了JNIEnv结构,就可以在本地代码中调用Java代码。
GetIntField,GetMethodID,CallVoidMethod - 看过什么源码
——————————————————————————————————————————————网易传媒秋招· 1面——————————————————————————————————————————————
1.ListView如何优化
1)利用static的ViewHolder内部类,在getView(int position, View convertView, ViewGroup parent)中,若convertView不为空则用getTag()取出ViewHolder,若为空才需要:
new一个ViewHolder里面存View 以及 inflate操作。
2)getView()里不做耗时操作
2.Dp与px区别;一个高分辨率手机相比低分辨率的,1dp代表更多的px还是更少的?
答:Android系统定义了六种像素密度:从ldpixxxhdpi(120、160、240、320、480、640),它们对应的dp到px的系数分别为0.754,这个系数乘以dp就是px.
3.try catch finally 如果try里return了,还会执行finally么?
答:先执行finally里的,再return!!!
注:finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值!!!
4.介绍一下除了强引用之外的引用
答:见job_java.pdf。虚引用很少用;
软引用:如果要oom了它就释放(顺口溜:性格很软,要oom了就大公无私地释放自己)
弱引用:只要一gc()它就释放(顺口溜:非常弱,以至于一回收就挂了)
(我额外提到了可以用弱引用避免内存泄露,她就让我讲android里怎么触发内存泄露,用weakReference如何避免,此问题见搜狐北研-Android篇-第4题)
5.XML如何优化让渲染效率更高?
答:用RelativeLayout代替LinearLayout,用ViewStub等,
6.Handler里的handleMessage是否在主线程、Service的onStart方法是否在主线程?
注:Android2.0之后onStart改为了onStartCommand,此处面试官口误。
答:我理解这个问题就是考Service默认是否运行在UI线程、handleMessage()是否运行在主线程,答案都是:是。
7.intentService和Service区别
答:
注:HandlerThread是个自带Looper的Thread。可以用来替换Thread?
1)IntentService在执行onCreate操作的时候,内部开了一个线程HandlerThread(相当于也建了个Looper和消息队列).
2)具体来说,会在onStartCommand接收intent,然后由内部的Handler把携带intent的msg发到内部的消息队列(跟HandlerThread的Looper关联),用内部的HandlerThread的Looper来处理队列中的Intent,按顺序执行。
3)需要复写onHandleIntent(Intent intent)函数来处理收到的intent请求
4)无需主动结束,会自动结束
5)因为由子线程(HandlerThread)的Handler来执行onHandleIntent()所以适合处理耗时操作。
注:HandlerThread就是帮你搞定了Looper的部分而已。
参考:http://blog.csdn.net/matrix_xu/article/details/7974393
8.如果有多种布局情况下,RecyclerView的onBindViewHolder相关(下次不说用了RecyclerView就好了。。)
答:
1)首先int getItemViewType(int position) 中根据position返回不同的布局
2)依然需要自己定义ViewHolder,在onCreateViewHolder(ViewGroup viewGroup, int type)中根据type不同inflate并返回不同的ViewHolder
3)在onBindViewHolder(MyViewHolder holder, final int position)中,给holder中的控件设置内容
——————————————————————————————————————————————阿里巴巴实习一面——————————————————————————————————————————————
综合的问题※
- 你知道的android新技术(热补丁等,以及涉及到的知识点)
- 遇到过的难题,怎么解决的
- 看过的源码
- 怎么做界面适配的
答:简洁、适应性好的UI(比如用match_parent占满屏幕这种);用相对布局代替绝对布局;百分比布局;dp代替sp;dimens文件;.9png;比较难的可以通过java代码动态调整;提供多尺寸图片。
——————————————————————————————————————————————搜狐快站实习一面——————————————————————————————————————————————
全部是Android※
- 怎么做布局优化:
用RelativeLayout代替过度绘制的;ViewStub懒加载;比如TextView设置上下左右图。
ViewStub的用法很简单:
View view = viewStub.inflate(); - 子线程Looper是怎么搞的?Handler机制是?
答:需要用Looper.prepare()来给线程创建一个消息循环(也就是创建了消息队列,new了Looper),再调用Looper.loop()来使消息循环起作用,结合通常的handler即可.
另外在主线程中,new Handler()时,实际上是通过Looper.myMainLooper()来获取当前主线程中的消息循环,即new Handler() 等价于new Handler(Looper.myLooper()).
参见:http://blog.sina.com.cn/s/blog_5da93c8f0101jfb1.html - 右滑删除的自带控件?
答:
不知道,跟Scroller有关。 - ButterKnife是编译前注入还是编译后?
答:
在生成.class之前就注解好了,编译前注入提高了效率.他编译前就生成了ExampleActivity$$ViewBinder.java.具体见 [注解解析过程.png]
它利用APT(Annotation Process Tool)在编译时生成辅助类,这些类继承特定父类或实现特定接口,程序运行时加载这些辅助类,调用相应接口完成依赖注入。
使用butterknife实现依赖注入的开销仅仅是在编译时刻做的注解处理,程序运行时的开销几乎可以忽略不计。 - (项目相关)XRecyclerView的源码?
- 图片加载库怎么实现?
答:见 [图片加载库.docx] - (项目相关)App里那个点击展开的下拉菜单如何实现的(DropDownMenu)
- 网络加载库以上怎么封装的?(略)
- 从网络上下载个图片怎么显示?(ImageView大概原理)
答:见 [图片加载库.docx].
可参考:http://www.tuicool.com/articles/beYBra http://blog.csdn.net/jxt1234and2010/article/details/50524213(尤其后者) - 给一个100100的,怎么压缩到5050
答:用BitmapFactory.Options的inSampleSize参数(长宽变为1/n)
——————————————————————————————————————————————新美大面试1、2、3轮不会的题——————————————————————————————————————————————
1.进程、线程的区别:
答:
1)一个程序至少有一个进程,一个进程至少有一个线程
2)进程有相互独立的地址空间,线程没有,多个线程共享内存
3)每个线程有自己的执行堆栈和程序计数器为其执行上下文
4)进程间通信需要IPC,线程间通信简单的多。
5)线程是处理器调度的基本单位,但进程不是。
2.给一个数组,把数组分成两部分,要求两部分差最小
答:
这是背包问题的变种。
假设分成两部分的和为sum1,sum2,那么假设sum1<=sum2的话,此题目标可以转化为,使得sum1在isum1<=SUM/2的条件下尽可能的大。
也就转化为了一个容量为SUM/2的01背包问题,体积就是它的值,价值也是它的值。【】
见:http://www.tuicool.com/articles/ZF73Af
3.为什么说Java的每个对象都是一个锁?关于Monitor你知道多少?【】
答:
(已知)Java中每个对象都有唯一的一个monitor,同时只能有一个线程可以获取某个对象的monitor。wait释放monitor。
1)如果在synchronized 范围内,监视器才发挥作用。
※synchronized用到的锁是放在JAVA对象头里面的,包含MarkWord,对象地址和数组长度(数组对象才有)。
其中有个Mark其中有个Mark Word来存储对象的hashcode、分代年龄和锁标记位,
其中锁标记位会产生变化,对应的不同的标记,我们的锁有3种:轻量级锁、重量级锁、偏向锁。
2)对于Lock机制:
所有Lock接口的操作都委派到一个Sync类上,该类继承了AbstractQueuedSynchronizer
http://blog.csdn.net/qq_16811963/article/details/52171764
http://www.importnew.com/21089.html
4.关于AOP
答:
面向切面编程。比如两个类都要记录日志,可以把这个功能抽取出来但是这样这个类跟前两个类又藕合了。
因此,这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
5.Java里如何自己实现一个注解,这个注解可以实现自动赋值
答:
尤其在Orm里用的多,或者@onclick这种,或者@column这种
总之,先声明接口:
public @interface Person{String name();}
用的时候 比如 @Person(name="123") public class A{...}
然后用反射获得数据 A.class.getAnnotation(Person.class).name()
见:http://www.cnblogs.com/xing901022/p/3966799.html
http://www.cnblogs.com/icerainsoft/p/3471749.html
6.Lock和Synchronized的性能对比(Jdk1.5之后)
答:
不同于我们的想法,如果竞争资源不激烈,两者的性能是差不多的。
而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized!!
因为JVM 可以花更少的时候来调度线程。
7.JVM或者说Hotspot内置了几种GC算法
答:
跟之前学的差不多。分Eden+S0/S1(Survivor区域)(这两个一起叫新生代,Eden存在新对象s0s1用来回收) , Old(老年代) , Perm(持久代)。
复制算法适合Eden和S0/S1,标记压缩适合老生代。
8.TCP三次握手、四次挥手及作用:
答:
*记得发送都是SYN回应都是ACK。四次挥手的时候发送都是FIN=1,回应是ACK=1
1)握手:三次握手是因为要保证连接是双工的,以及防止已过期的连接请求报文
2)挥手:收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了
9.HTTP常见状态码
答:
切记,301是永久移动,302是临时的,500是服务器错误,502是网关问题
10.如何避免死锁
答:
死锁有4个基本条件破坏一个即可。
比如规定加锁顺序,比如必须先A后B;比如设置加锁超时,使用带超时的tryLock();还可以进行死锁检测,用类似图的方法检测有没有循环依赖。
11.cookie和Session的区别
答:
cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
12.HashTable和HashMap区别,HashMap和TreeMap区别
答:
1)主要是线程安全VS不安全,以及 不允许null作为KEY/VALUE VS 允许。
2)TreeMap把它保存的记录根据键排序,线程也不安全,不允许KEY是NULL。
13.Sleep和Wait的区别
答:
1)前者是Thread类的,后者是Object类的
2)sleep不释放锁,wait释放锁。
3)
14.(美团相关)App的支付部分要注意什么安全问题
15.ListView的缓存【】
17.HTTP2 VS HTTP1.1 VS 1.0 VS SPDY【】
18.HTTPS的三次握手,SSL与TLS的关系【】
答:
19.不限语言的内存管理机制【】
20.堆排序原理【】
———————————————————————————————————————————————————————Growing IO——————————————————————————
21.singleTask的话,发一个信息是在onNewIntent里收到还是Create里?
22.Java字节码格式
23.OAuth2
24.要想知道当前的请求经过了多少个路由,TCP协议可以实现么?
25.APK包都包含了什么?
————————————————————————————————————————————————小米MIUI部门 1、2面————————————————————————
1.比如有一个sendMessage发送是有延迟的,那么队列中后面的信息会处理么?
2.如果有两个synchronized非静态函数,两个线程可以同时分别调用两个函数么?
3.单链表快排
4.寻找和最大的子序列(注意,元素不可以连续)
5.Binder驱动原理,是如何知道发给谁的,Binder的优点(安全)
6.AIDL.
7.给定一个数,拆成很多数之后,比如10=3+3+4或者2+2+2+2+1+1,找这些数最大的乘积,比如10就是334=36(LeetCode)
8.如何跟一个进程共享一个文件?(用openFile)
——————————————————————————————————————————————一点资讯实习(共4面技术面问题汇总)——————————————————————————————————————————————
注:一点资讯的办公环境不错,而且居然有桌游室,面试官说一般周三下午公司鼓励员工去体育锻炼,游泳啊打球啊啥的还有玩桌游的,如果不是我来面试估计桌游室就在打牌了。
公司不打卡,比较自由,外企的工作氛围,因为创始人是雅虎研究院的前院长而且第一批员工好多是雅虎微软的。
确实,跟腾讯的4轮面试比,他们的4位面试官看得出来心情都不错,给人很舒服的感觉,而且对待面试者也更nice,有的问题回答不上来也没关系,哪怕是4面的面试官也很nice。
不像在腾讯的时候有的面试官非常尖锐,有的面试官没有笑容的感觉。员工也就200人,3年前成立的我觉得做的很不错了。
※Java※
1.反射,可以把一个方法从private的改成public的吗?如何改?
答:可以用getDeclardMethod(name,Class... parameters)方法获得Method,然后用setAccessible(true)来改成Public的,变量同理。
附:如果要改变变量用getDeclaredField,然后用反射构造对象可以直接用mClass.newInstance() / (如果有多个构造函数)先用class.getconstructor()获取Constructor再调用con.newInstance()
2.如何获得一个类的class对象,有几种方法
答:Class.forName、getclass()、.class。
3.某个类A有子类B,如何判断一个类的对象是不是A的还是其他的子类的?反射可以修改这个类父类的方法么?
答:用getClass().getName()判断;
用getClass().getSuperclass()即可获得父类。
1)finally final finalize()的区别
2)final修饰类、对象、方法分别有什么用
3)finalize()是否一定被执行,是否一定被回收;
4)class存在Java的哪个区,Class对象也就是类本身是否会被gc回收。
答:1)略、2)见"蚂蚁金服惨痛的一面"
3)垃圾回收器要回收对象的时候,首先要调用这个类的finalize方法。一般无需手动调用。但jvm不保证finalize()一定被调用。
具体来说,GC有一个Queue,叫做F-Queue,所有对象在变为finalizable(该回收)的时候会加入到该Queue,然后等待GC执行它的finalize方法。有可能还没finalize,jvm就结束了
4)方法区。Class对象的回收涉及到方法区的回收:
方法区的回收有两种:常量池中的常量,无用的类信息,没有引用了常量就可以被回收。对于无用的类进行回收必须保证3点:
类的所有实例都已经被回收、加载类的ClassLoader已经被回收、类对象的Class对象没有被引用(即没有通过反射引用该类的地方)
5.Java的四种引用
答:略,见job_java.pdf
6.==与equals差别,new Integer(1) == new Integer(1)吗?(略)
7.什么样的Exception可以被catch,比如1/0需要被catch吗?
答:Checked异常都是可以被处理的异常,所以Java程序必须显式处理Checked异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误无法编译
Runtime异常产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序,一般不太需要catch。
error无需catch。1/0是arithmeticException,属于RuntimeException。
8.synchronized(obj)和synchronized方法的区别
答:见多线程.docx。
9.Java垃圾回收机制(略)
※Android※
9.Android有几种布局(略)
10.用app过程中突然来了个电话,activity都会执行哪些函数
参考:“按home键执行了什么生命周期”
11.4种launchMode的区别
答:这几个mode都是针对Activity设置的。这里主要讲singleInstance,
所有的singleInstance单独成立一个任务栈,这个栈中Activity的特性同SingleTask(只能有一个实例),其他Activity在原来的栈中同standard。
比如Activity a,b,c,b是singleInstance,那么a->b->c然后按back时是回退到a。
例子如电话拨打界面。参考:http://bbs.itcast.cn/thread-80202-1-1.html。
12.每个线程都有handler吗?(略)
13.如果静态、动态广播都接收同样的intent,请问哪个先处理?即便设置了同样的优先级,哪个先处理?
答:首先动态和静态广播都可以设置优先级。然后看源码可以得知,如果动态广播接收器优先级高于或者等于静态广播接收器,那么就插到前面。
14.bindService是同步的吗?如果bindService,调用Service里的方法是同步的吗?
答:异步的!start和stop也是.startActivity也是。
至于后者我觉得是同步的
15.如果给定一行中三个textview的间距和离边缘的距离,但是为了适配不给定textview具体宽度,怎么保证每个textview宽度相同?
答:用layout_weight
16.Android中的内存泄露的情况
参考:各种笔试.txt-搜狗输入法 + 搜狐北研-Android篇。
17.MeasureSpec是什么,介绍一下。我说了exactly,AtMost还有unspecified等,她又问wrapcontent match_parent 和定值都对应的是什么mode,
MeasureSpec是32位int,封装了父布局传递给子布局的布局要求,包含了模式EXACTLY、ATMOST、Unspecified三种模式以及对应的值。
Exactly:width或height为match_parent时,模式为EXACTLY,即为定值。
atmost:wrap_content时,模式为AT_MOST,即为当前view可以达到的最大尺寸。
unspecified:宽高值设置为0的时候或者没有设置宽高时,任意大小。
在父类的onMeasure中,调用 getDefaultSize(int size, int measureSpec)来根据measureSpec的mode决定是用size,measureSpec.size还是什么。
在子类中需要重写,调用measureChildren()和父类的onMeasure方法
18.RecyclerView在遇到有的元素划出屏幕又划回来时是怎么重用的。#
19.Android中动画有几种
参考:各种笔试。
20.fragment怎么跟Activity通信比较好?
1)我说的用(**Activity)getActivity然后调用函数,面试官说不是太好。
2)最佳实现:在fragment中定义一个回调接口,然后在activity类上实现之。在fragment的onAttach(Actvitity a)中强转获得接口(Listener)a给Activity发信息
在Activity中用getFragmentManager().findFragmentById(R.id.fragment_a)获取fragment给其发信息。详见http://www.cnblogs.com/duanguyuan/p/4006639.html
3)其他:广播、EventBus(缺点是没法获得activity返回信息)、handler(在activity中定义handler,fragment中取得这个handler去发信息。缺点是没有解耦,也没法获得activity返回信息)
参考:http://www.open-open.com/lib/view/open1454298402323.html
21.说说你知道的设计模式或者Android中的设计模式
答:我说常写的有单例;Android里有Adapter,Decorator,工厂模式,Observer。。
他问,工厂模式在哪里用到,有什么优点?
工厂模式:BitmapFactory(静态方法创建Bitmap),优点是可以代替new A(),方便一次统一改动,解耦。
22.Asynctask需要复写哪些函数,哪些在主线程哪些在子线程?(略)
23.自定义View都会经过什么步骤。(略)
※计算机网络※
24.Tcp和Udp区别:见上文“蚂蚁金服惨痛的一面”面经
25.Get和Post区别:见上文“蚂蚁金服惨痛的一面”面经
※算法※
26.先给了一个树,先让写中序遍历的顺序;然后问给定这个树的root,如何把这个树按中序遍历的顺序转化成一个链表并且返回的是中序遍历的第一个节点?
答:中序遍历略。后半道题相当于,把中序遍历时poll()出的node.val加入list的操作,改为先定义一个head和originHead = head, 然后每次让head.next = node; head = head.next;。最后返回originHead.
27.给一个数组,不要求保持原有顺序,使得所有负数在左边正数在右边
答:简单,用类似快排的思路即可,注意细节。
28.真实世界中一个孩子有父母,父母还有父母,现给定两个孩子(即树的根节点),假设这树是有限的,问两个孩子是否有共同的某个亲戚,比如A的爸爸的爷爷是B的爷爷,如果有请找出这个点
答:类似求两个数组交集的题,用一个HashSet存一个树,遍历另一个树的时候每次判断即可。
29.给一个矩阵,提供上下左右走的四个函数(boolean返回值代表是否可以走,因为有墙),还可以获知当前点的坐标(不可以或者上下左右点的坐标),以及获知当前点是否是出口。
请设计算法输出一条通往终点的路径(虽然不能获知上下左右点,但是可以万一走到走过的点,用hashset来存储走过的点,然后判断当前点是否走过,走过就return)
答:此题就是DFS,遍历每一条路径。唯一的麻烦在于可能会走重复的点,解决这个问题也是用HashSet存储当前走过的点,每次走到一个新的点就判断当前点在hashset里有没有,有的话就return回去。
30.给一个数组,包含了几个点比如ABCD,然后还可以获知每个点指向的点,比如A->BC,问这个是否有回路。【】
31.给定一个有序含重复元素的数组,给定一个数p,请求出p是否存在或者重复了多少次
答:(我开始说用二分找起始点再往后遍历,后来说可以改成二分找到任意一个点然后往左右扩展,他说那如果全都是相同的数字会退化严重。
后来告诉我说在遇到p==nums[middle]的时候可以判断左边点是否等于这个点,如果等于再继续二分。)
类似https://leetcode.com/problems/search-for-a-range/
32.多叉树的层次遍历。(以Android的Layout举例说的)
答:LeetCode原题,用队列来做,重点在于如何决定每次循环从队列中取多少个对象。
其他
33.说说你的优点和缺点
34.你的本科成绩怎么样
注:我说研究生成绩一般,他说不重要,主要看本科。
35.能不能来实习
——————————————————————————————————————————————搜狗三面【】——————————————————————————————————————————————
1.targetSDK compileSDK区别
2.如果设置了:remote的service,其他App调用这个服务,Application的oncreate会执行几次
3.onInterception()
4.App的启动机制
5.Android App的签名机制
6.MVC和MVP的区别
7.HTTPS是怎么判断对方的证书是否有效的
——————————————————————————————————————————————腾讯OMG实习一面——————————————————————————————————————————————
Android※
- (Android)自定义View如何实现一个类似tagview的控件(只能用textview),如何重写函数。
答:如果问到具体实现的话,可以参考https://github.com/whilu/AndroidTagView/(比较复杂)。或者参考DropDownMenu
Java与算法※
- Hashmap内部结构
- 快速排序为什么时间复杂度是nlogn
- 写算法,求两个数组交集
- 用过什么设计模式?
答:我答的写过单例。
5(续). 问:如何改成懒加载
——————————————————————————————————————————————今日头条实习一面——————————————————————————————————————————————
算法※
- 100w数组里找100最大的
答:
修改过的快排 或 堆排序。http://blog.csdn.net/v_july_v/article/details/7382693 - 链表加法
答:见https://leetcode.com/problems/add-two-numbers/
(中途考了链表反转)
Java※
ArrayList的内部结构add/remove怎么实现的?HashMap内部结构?如何put和get的?如何扩容的?
答:
1)ArrayList内部结构就是数组。
add(E e)的时候会判断,如果超过当前大小就用System.arrayCopy复制到一个1.5倍大的新数组再添加,否则直接添加;add(index, e)会先移动再添加。
remove(E e)的时候会调用equals()方法判断,如果不属于基本数据类型还没复写equals,比较的就是地址。
2)HashMap内部结构略(Java8是数组+链表/红黑树)
put时,对key先判null,是null放到table[0](这也是为什么输出的时候如果有null一定先输出null);
然后调用对象的hashCode(),用自带的hash()对hashcode重新计算hash,然后寻找存储位置,如果hash相同就用链表存储
每次put时还会调用equals判断key是否相等,相等就会替换。
-get时同理,先判null,是null返回table[0],然后会在对应的位置用equals循着链表查找相同的key:先判hash,再判key==或equals
3)也就是重哈希。
当HashMap中的元素个数超过数组大小loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75。
然后把数组的大小扩展为216=32,即扩大一倍,然后重新计算每个元素在数组中的位置。
而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。Static内部类和非Static内部类的区别
答:
1)静态内部类可以创建静态成员,而非静态的内部类不可以.
2)静态内部类只可以访问外部类中的静态成员变量与成员方法,而非静态的内部类即可以访问所有的外部类成员方法与成员变量
3)创建静态内部类时不需要将静态内部类的实例绑定在外部类的实例上
4)非静态内部类隐式持有外部类的引用
Android※
- 如何自定义View
答:结合http://blog.csdn.net/lmj623565791/article/details/24252901 和 一些小的开源项目,比如https://github.com/dongjunkun/DropDownMenu 或者 - Handler为什么可以给Activity发消息
- (追问)为什么Handler会内存溢出风险
答:见http://blog.csdn.net/zhuanglonghai/article/details/38233069 - 从A点按钮start 到Activity B,生命周期
答:onPause -> oncreate -> onstart -> onresume -> onstop(如果完全覆盖才有这个), 不一定(ondestroy) - 多线程访问同一个变量如何处理
答:final,threadLocal,synchronizeble,lock等
10.(根据简历)Android底层项目
11.(根据简历)Android 缓存你怎么做的,Rest如何设计创建一个文章,
12.(根据简历)MVP是啥,M里一般放啥
13.(根据简历)我提到了intentService,就问了
14.(根据简历)问用了什么网络库:Okhttp,说retrofit的优点是什么
——————————————————————————————————————————————————————————搜狐北研——————————————————————————————————————————————————————————
Java篇※
HashMap如果hashcode函数不好,全放到一个数组格子里了怎么办?你知道Java8里的HashMap是怎么实现的吗?树你了解么?红黑树,AVL树等。
答:
如果链表过长就转为红黑树,这样时间复杂度O(N)->O(logN)。
hash()实现:先判Null再调用key的hashCode方法;
equal():先判地址相等->再判key和value都相等 见https://segmentfault.com/a/1190000003016453
红黑树:增删改查都是O(logN),基础是二叉排序树+平衡二叉树
二叉排序(查找)树:最常用的,左子树<根节点,右子树>根节点。查找O(logN)-O(N)、删除O(1)-O(logN)
平衡二叉树:左右两个子树的高度差的绝对值不超过1,左右两子树都是平衡二叉树ArrayList如果频繁插入为什么会导致GC? 怎么解决?
答:
1)当扩容时,以适当长度新建一个原数组的拷贝,并修改原数组,指向这个新建数组,原数组自动抛弃(java垃圾回收机制会自动回收),因此会导致gc;
2)解决办法:指定更合适的初始容量。详见http://blog.csdn.net/qq_30034681/article/details/47080577ArrayList扩容的默认倍数、默认初始容量分别是多少?
答:
1.5倍+1、初始容量10.HashMap线程不安全,什么是安全的?
答:
Concurrent包HashMap如果想按插入顺序输出怎么办?用什么数据结构代替它?或者用什么数据结构改造HashMap?
答:
1)用LinkedHashMap。它的每一个实体,就是LinkedHashMap.Entry的实现是用了链表形式,实体虽然是以Hash的顺序存放在Map的数组table里面,但是实体之间却用链表的形式保持了存入的先后关系。
2)同上。
6.Java8主要新特性有哪些
答:
1)接口中可以有具体的函数实现 用default关键字
2)Lambda
3)新HashMap(同上)
4)parallelSort()并行排序、多重注解、新的DateAPI等
*5)Java7之后String的改动:(去除了offset和count,在substring时会创建新string而不是引用原String的Char数组)http://www.open-open.com/lib/view/open1417399502627.html
Android篇※
- (项目相关)叙述一下OAuth2.0流程
答:
我们的项目也不算标准的2.0,是 App(Resource Owner)发用户名密码给Authorization Server,拿到token之后交给Client(Java后台),Client拿Token去找验证服务器拿用户资料。
参考:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
名词解释:1用户:Resource Owner(App可以视为User-Agent);2存着用户名密码的服务器:Authorization Server;3为用户提供服务但用户不想让拿到密码的:Client
OAuth2.0举例:比如Google和云冲印,我想用google账户使用云冲印但是又不想把用户名密码给他。 - ViewPager如何做到无限循环
答:
ABCDE->EABCDEA,首位各加一页,在比如翻到最后一个A时候跳到真正的A并且不显示切换动画。 http://blog.csdn.net/oweixiao123/article/details/23459041 - 谈谈用过的图片框架
答:
见单独的WORD。
4.handler可能遇到什么问题?如果你说内存泄露,怎么解决?
答:隐式引用和显式引用都可能导致这个问题。
1)隐式引用:非静态内部类会持有外部类的引用。
此时可以用静态内部类、或另定义一个外部类(top-level class)解决。
2)显式引用:传入了一个参数。
对于这种情况,可以在Runnable中用WeakReference持有那个参数,比如可以是Activity,也可以是一个View;(所以这个其实不算Handler的问题)
或者比如在单例模式里,传入了Activity,作为类内的static变量。
注:WeakReference是当没有StrongReference指向它的时候就会很快被回收。http://blog.csdn.net/FeeLang/article/details/39059705、http://www.tuicool.com/articles/imyueq
另外可以看http://www.csdn.net/article/2015-09-07/2825631这里关于详细的内存泄露的分析 - RecyclerView的优点?
答:
1)LayoutManager(可以实现ListView(横向也可)、GridView、瀑布流等) 2)item增加和移除的动画 3)只管回收与复用View高度解耦
http://www.tuicool.com/articles/aeeaQ3J
http://blog.csdn.net/lmj623565791/article/details/45059587
6.(项目相关)内存泄露用什么检测?
答:LeakCanary - Asynctask做大文件下载怎么做?或者用什么函数更新进度?
答:publishProgress()
——————————————————————————————————————————————————————————搜狗输入法面试————————————————————————————————————————————————————————
注:据说面试官临时有事,换了个人,不过这个人感觉也挺厉害的,深藏不漏的感觉。没有问任何算法、Java基础,就可着简历问的,可能是没准备吧。
1.项目中用的下拉刷新那个控件怎么实现的,以及上拉加载
2.FragmentActivity底部的导航栏怎么实现的
3.用的什么架构(比如MVP啥的)?有什么优点?
4.HTTP和HTTPS区别?哪个快?
答:
见上文,别忘了端口。
在速度方面,肯定https有消耗:
HTTPS除了TCP的三个包,还要加上ssl握手需要的9个包,所以一共是12个包。
因此HTTPS主要慢在建立连接方面。GMAIL改成https之后资源消耗不超过1%。
5.App跟服务器通信要注意什么?【】
6.怎么省电?怎么做性能优化的?【】
7.线程池怎么维护?比如会出现什么问题?【】
8.带大量图片的类似这种listview/recyclerview怎么防止出现一些问题?
答:
我就扯了Fresco内部的那套机制给她。她表示还想知道其他一些比较轻量级的图片库怎么做的
9.怎么出现的这个情况?[开发者选项——调试GPU过度绘制——显示过度绘制区域]
答:
设置-开发者选项-调试GPU过度绘制-显示过度绘制区域。
分为 蓝 绿 粉 红4种颜色:1x过渡绘制 2x 3x 4x
不仅Layout会过渡绘制,View的背景也可能,这样只要让背景色整体统一即可。
参考:http://www.jianshu.com/p/ab0cf2697236
最后我表示更喜欢搜狗的原因是他们的技术底蕴好,产品的用户量巨大,但是他们说其实各个公司都有产品一般的比较闲的组。他们组是做输入法的各个厂商的定制版和适配、bug处理啥的。
——————————————————————————————————————————————————————————微店————————————————————————————————————————————————————————
实际面经※
来自网络的面经※
问我如果需要网络的任务占满线程池,而网络状态不好,那么后来有缓存的任务就拿不到线程执行,应当如何优化
ConcurrentHashMap原理
答:
HashTable是用synchronized锁住了整个表;
这个使用了分段锁技术,可以理解为把一个大的Map拆分成N个小的HashTable,使用了多个锁来控制对hash表的不同部分进行的修改。
比如在put时,根据key.hashCode()来决定把key放到哪个HashTable中,再调用segmentFor(hash)函数然后再调用Put进行put操作。get时同理。
默认是把segments初始化为长度为16的数组、用了位操作来是哪个确定Segment
通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。
get不加锁,写操作锁粒度尽量小。
参考:http://blog.csdn.net/xuefeng0707/article/details/40834595、http://www.iteye.com/topic/1103980Binder原理
答:
- 流程:
- client调用某个代理接口中的方法时,代理接口的方法会将client传递的参数打包成为Parcel对象;
- 代理接口将该Parcel发送给内核中的binder driver.
- server会读取binder driver中的请求数据,如果是发送给自己的,解包Parcel对象,处理并将结果返回;
- 整个的调用过程是一个同步过程,在server处理的时候,client会block住。
- Service Manager:
任何service在被使用之前,均要向SM(Service Manager)注册,同时客户端需要访问某个service时,应该首先向SM查询是否存在该服务。
如果SM存在这个service,那么会将该service的handle返回给client,handle是每个service的唯一标识符。
在ServiceManager.c中:
(初始化binder,打开/dev/binder设备;通知binder driver(BD)使SM成为BD的context manager;
维护一个死循环,在这个死循环中,不停地去读内核中binder driver,查看是否有可读的内容;)
(这里需要声明一下,当service在向SM注册时,该service就是一个client,而SM则作为了server。
而某个进程需要与service通信时,此时这个进程为client,service才作为server。因此service不一定为server,有时它也是作为client存在的。)
参考:http://blog.csdn.net/coding_glacier/article/details/7520199
- 让我讲了下NDK/JNI,我简单说了一些应用,他说如果多线程调用JNI会出现什么问题
答:可以先在java里处理。。。
——————————————————————————————————————————————————————————搜狐焦点(面试官不会android)————————————————————————————————————————————————————————
Java篇※
1.JVM内存模型介绍一下:
答:五个区,线程共享:方法区、Java堆;线程私有:程序计数器、虚拟机栈(管理Java方法)、本地方法栈(管理Native方法)。类的int在堆里,方法的int在虚拟机栈里。
参见:http://www.cnblogs.com/AloneSword/p/4262255.html
2.Java多线程
答:必会,常考,见Word,包括Synchronized, wait¬ify, Lock包里的, Volatile, 以及Atomic(不常用)
3.(因为我项目里写了)以QQ登陆为例介绍一下OAuth2.0流程
答:授权码模式。
1)用户访问客户端,后者将前者导向认证服务器。
2)用户选择是否给予客户端授权。
3)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
重点4)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
重点5)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
参考:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
——————————————————————————————————————————————————————————小米(来自网络)——————————————————————————————————————————————————————————
算法篇※
- 二叉树的层次遍历算法
- 已知二叉树的先序和中序遍历,如何求后序遍历
- 如何判断一个字符串符号是否是对称的,比如([]{})是对称出现的,(&&)不是对称出现的
Android篇※
- AIDL机制
- Handler机制
- 如何求出字符串的回文结构,判断回文结构的优化算法
- 线程如何并发运行,线程间通信问题
- 用过哪些自定义视图
- 安卓事件的分发机制,问的比较细
- Activity生命周期
- Android Activity 的四种启动模式(singletop等)
- ViewPager 与 Fragment 的配合使用
- Touch Event System 的理解
- Bitmap 位图相关处理,例如大图加载、图片内存回收
- View的绘制
- Handler 是如何实现的
- AsyncTask 的实现原理和注意事项
- Activity、Fragment 的生命周期
——————————————————————————————————————————————360实习面试(来自网络,带*的问题不清楚)——————————————————————————————————————————————
Java※
- 有两个线程A和B,A运行到一半以后需要等待B线程运行完以后的结果才能继续,如何做到?
答:
1)第一种最简单:Join()
Thread t1 = new Thread{ public void run() {
t2.join();///等待t2执行完才执行
sysout...}}
2)第二种用Future.get()也可以
static FutureTask futureTask;
public static void main(String[] args){
futureTask = new FutureTask(new Task());
Thread thread2 = new Thread(futureTask);//嵌入到线程中
t1.start();
thread2.start();}
static Thread t1 = new Thread(){
public void run() {
futureTask.get();//类似.join()
System.out.println("456");}};
static class Task implements Callable{
public Object call() throws Exception {
Thread.sleep(6000);return null;}
}
3)用wait¬ify也可以
public class Main {
static Object obj = new Object();
public static void main(String[] args){t1.start();t2.start();}
static Thread t1 = new Thread(){public void run() {
synchronized(obj){ //每个java对象都有一把锁.当前进程需要先获取obj锁。简单来说,就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内
obj.wait();//锁住obj,此时t2还在sleep
System.out.println("t2-overed");
}}};
static Thread t2 = new Thread(){public void run() {
Thread.sleep(5000);
synchronized(obj){ //当前进程需要获取obj锁.synchronized()不需要锁可执行
obj.notify();//释放obj
}}}};}
*2. 假如有几百万条排序好的数据,用户搜索的时候如何快速检索到需要的数据,面试官提示我说有什么数据结构可以做到
答:B树?
3.for循环和迭代器的比较,各自最佳使用场景分别是啥
答:
1)for适合访问顺序结构(如数组),Iterator适合链式结构。
2)Iterator可以方便使用相同方式遍历(比如从List切换到Set就不用改代码)
3)Iterator更简洁,但是没for那么灵活(比如写一些算法的时候)
算法※
- 冒泡排序,并且优化
答:
1)如果内层for某一轮一次交换都没有就直接break(说明已经全部有序);
2)见http://blog.csdn.net/tjunxin/article/details/8711389
Android※
*5. Android共享数据的方式,我答的数据库、文件、SharePreference、ContenProvider、Broadcast。。想到的都说了
- Service是否运行在主进程,我答的一般情况下是,在Manifest文件里指定进程名以后可以运行在单独的进程里。
- 如何长时间保持你的Service在Android系统里不被杀死
答:
Return start_sticky ; onDestroy里重启 ; startForeground ; 收到系统广播就重启
*8. Android进程间通信的机制和Linux进程间通信的方式,答Android是binder,Linux是管道、Socket、共享内存、消息队列、信号量等等,他没有继续问了,其实问了我也不知道,都只是看过就知道名词。。 - 写一个带listview的activity(白纸手写)
- 如何优化listview性能
答:在getView()里用viewholder等 ,见http://blog.csdn.net/dfqin/article/details/7458853 - 写一个读取sd卡某文件的内容用log打出来(白纸手写)
try {
File file = new File(Environment.getExternalStorageDirectory().getCanonicalPath() +"/myfile.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String line = "";
while((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
*12. 安卓数据存储方式有哪些?答:SharedPreference、文件、Sqlite、ContentProvider - 介绍一下二维码扫描功能的实现,有没有对zxing优化过
————————————————————————————————————————————————————————————————————待读——————————————————————————————————————————————————————————————————————————
http://blog.csdn.net/yanbober/article/details/45936145 Handler必读
面经篇※
http://blog.csdn.net/u014497502/article/details/50900447
http://blog.csdn.net/u014497502/article/details/51113646
http://blog.csdn.net/XSF50717/article/details/48529837
http://www.nowcoder.com/discuss/5842
技术篇※
http://blog.csdn.net/xu_fu/article/details/7829721
http://djt.qq.com/article/view/987
http://blog.csdn.net/xiaanming/article/details/17539199