面试过程
小米面试会预约一个时间发邮件这里有个坑,发的邮件不光有约定的地点+时间,后面还有一个确认接受,我没点确认接受,导致我去前台查询说我没有查询到,面试了3个回合,3个小时,没有中间休息,建议大家面试之前带瓶水丶带瓶水丶带瓶水,重要的事情说三遍,最后也没有到HR,我的结果应该是凉凉,过程还是很轻松的
算法题目
生产者和消费者
刚开始我脑袋一懵啥是生产者丶消费者,面试官说你软件工程毕业不知道什么是生产者消费者?面试官还算照顾告诉了我下生产者丶消费者的逻辑,我想起来了,然后让我代码实现下,我是这样实现的
/**
* 生产者队列(最后感觉用队列比较好)
*/
Stack<String> strings = new Stack<>();
/**
* 需要生产的总数
*/
int count = 100;
/**
* 允许缓存的最大数
*/
int cache = 10;
/**
* 已经生产的个数
*/
int value = 0;
public synchronized void produce() throws InterruptedException {
while (value < count) {
if (strings.size() < cache) {
strings.push("生产一个数据");
value++;
notifyAll();
}else {
wait();
}
}
}
public synchronized void consume() throws InterruptedException {
while (value < count) {
if (!strings.isEmpty()) {
String pop = strings.pop();
notifyAll();
}else {
wait();
}
}
}
结果:说是我大体思路是对的,但是生产者消费者不这样写,这是我的答案,也不是准确答案哦
二分查找
过于简单,就不上代码了,我使用递归写的,因为代码量少
其它题目
线程如何通讯
我的答案是通过Handler可以实现线程间通的通讯和共享遍历,然后叙述了共享变量,多线程的安全问题,主要叙述了要保证三要素,如何去保证三要素的问题
View事件传递
我叙述是从Activity事件开始,他突然问我Activity事件从哪里来的?我一脸懵逼,这个我还真不知道,他又说那你就从Activity开始说吧?然后一顿巴拉巴拉
把上面的图片叙述了一遍,外加特殊的情况叙述了下
特殊的情况描述
- 同一时间序列事件是指以down事件开始,中间含有数量不定的move事件,最终以up事件结束。
- 各个View的onTouchEvent方法对DOWN事件的处理,代表了该View对以此DOWN开始的整个手势事件的处理意愿,True代表需要处理此次事件,false则表示不关心,事件会回传到上层View的ontouchEvent中
- 如果ViewGroup一旦决定拦截一个事件,也就是onInterceptTouchEvent返回True,那么后续的同一时间序列事件将会被默认拦截,不会再调用onInterceptTouchEvent方法,后续事件会交给ontouchEvent进行处理
- 事件一旦交给一个View处理,那么它就必须消耗掉,否则同一事件序列中剩下的事件就不再交给他来处理了,如果ontouchEvent中返回false,那么后续事件不会再传递进来
- 如果ViewGroup拦截了一个半路的事件(比如,MOVE),这个事件将会被系统变成一个CANCEL事件,并传递给之前处理该手势(gesture)的子View,而且不会再传递(无论是被拦截的MOVE还是系统生成的CANCEL)给ViewGroup的onTouchEvent方法。只有再到来的事件才会传递到ViewGroup的onTouchEvent方法中。
自定义View完成一个柱状图
题目给了一个集合,集合中存储了每个的数据,自定义一个柱状图的View,View高度固定100dp,宽度占全屏
我的答案是,先获取的屏幕的宽度,宽度/集合长度,得到每个柱子的可以绘制的区域,然后通过Path先画2个坐标轴的线,然后根据上面的宽度,能计算出每个柱子画的左,上,右,下的位置,挨个画矩形即可,理论上是可以行得通的。但是我发现后面叙述过程中我感觉每次都去计算矩形的位置,有点麻烦,可以通过画布平移然后再去取画柱子,应该简单点,我大体只能想到这个思路了
View的绘制流程
问这个问题的我当时其实有点懵的,不是我不知道答案,而是我不知道他想问的是什么?是想问我View的那几个方法吗?我反问他是想叙述View的那几个核心方法,还是说View通过怎样的流程添加到窗口的上的,就是Activcity的PhoneWindow说起,最后我还是叙述的测量,draw,layout
如何自定义一个View
懒得说了
Activity启动流程
这个从startActivity开始说起,AMS->ApplicationThread->ActivityThread等差不多的叙述了一遍
子线程中能不能更新View
我当时回答的是,一般来说是不可以的,因为更新View的规定必须要在主线程中执行,但是也有特殊的情况,这个能不能在子线程更新View,主要是看ViewRootImpl是否被创建了,因为更新View都是调用其requestLayout方法,最终都会调用到ViewRootImpl方法的requestLayout方法,这个方法里面会有checkThread就是检测当前线程是否在主线程中,如果这种情况,在Activity的onCreate方法中,立刻开启执行线程执行更新View,是不会崩溃的,因为ViewRootImpl对象没有创建,具体流程可以去看Avtivity的setCountentView是如何加入到窗体上的过程就可以
详细原因看这里
然后我还叙述了下一些特殊的 SurfaceView是可以在子线程中更新的,相机丶视频都是这样实现的