饮一杯茶,刷刷题听听别人的建议,面试足矣

前言

其实对于不少人来讲,都和我原来有一样一个疑虑:到底去大厂仍是创业型公司?去大公司一个萝卜一个坑,要往上走须要运气+实力足够好才能脱颖而出,创业型公司,可能更容易实现本身的想法和舞台,能把能力表现的淋漓尽致,但是会碰到更多的问题,公司经营不下去了怎么办?薪资待遇不如大厂?java

一丶大厂offer?

我相信每一个程序员的梦想都是获得大厂的offer,我以为这很正常,这并非咱们的饭后谈资而是每一个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度仍是要明显优于一些创业型公司/小公司,若是说可以在这样的公司锻炼几年,相信对本身能力的提高仍是很是大的。但不是每一个人都可以进入大厂的,这每每取决于咱们的能力、学历、面试表现等因素。git

如今面试大公司你说你没有架构开发经验估计都拿不出手,热修复,框架,glide,OKHTTP,flutter,NDK,音视频~源码原理等等已然大厂面试所必须的知识。可是,你真进入大厂了,可能几年都用不上这些知识,仍是老老实实去写代码。程序员

二丶抱怨不如努力提高自我

相比于前几年来讲,如今的面试难度提高了很多。你说说如今程序员这么多,你投递的公司可能与你一块儿投递的就有300人,可人家只招5人,那怎么办?简历PASS掉一大批,而后面试再PASS掉一大批。从这样来看,如今流行说的:“面试造火箭,工做拧螺丝”仍是颇有道理的,提升面试难度只是为了从不少人中招到本身须要的那些人。github

不少人都抱怨如今工做愈来愈难找了,的确,互联网行业如今确实没有以前好找工做了。我以为有面试

1丶很大一部分对本身的技术的认识还停留在过去的那一两年,
2丶是半路出家的人的基础确定是没有大学习踏实学习计算机知识的人好的,这就形成不少培训班出生的人很难往前走;
3丶是互联网行业确实对年轻的人有一部分偏心,毕竟刚毕业的大学生仍是比较廉价的,可是互联网行业并非吃青春饭。
4.市场逐渐趋于完善,每一个岗位对技术的要求愈来愈严谨,形成一种饱和不缺人的现象。
5.高级开发越来却越缺人,中低级市场饱和

因此,无论是应届生仍是工做几年的小伙伴都要对本身有一个清晰的认识,搞清楚你本身所欠缺的能力,搞清楚你本身的优点(企业为何要招你)。知道本身不足的地方以后,就要去努力!算法

互联网行业其实仍是挺公平的,虽然面试的时候会将你的学历做为参考,可是若是你的能力真的厉害,你的简历真的丰富的话,面试官仍是会很欣赏这样的应聘者的。api

三丶如何清晰的认知本身的不足,提高我的实力

我在这里所说的我的硬实力更多的指的是我的的专业能力,好比构建高质量网站的能力或者是对专业知识的掌握程度。缓存

我以为不管是对于新手仍是老手,想要提升我的硬实力最重要的就是不断深刻学习而且将理论实践,最好能够将理论在具体项目中实践一下。安全

给还在学校的同窗们一个建议:若是条件容许的话尽可能去参加一些比赛,可能你的技术并不太好,你的心里还很犹豫本身是否是具有参加比赛的能力,可是我仍是推荐你去尝试一下。服务器

为何呢?一个比赛的准备时间,说长点就是 5 ~ 6 个月,说短点也就是 2 ~ 3 个月。在参加这个比赛以前,比赛用到的不少技术你可能没有实际应用过,甚至连听都没有听过。可是这几个月的时间应该足够让你去学习了,若是你的态度好而且自学能力不差的话通常是没有问题的。

到了最后,你可能并无收获到一个优秀的名次,可是我以为参加比赛的经历对你的帮助才是最大的。若是后面你还会参加其余比赛的话,我以为你必定会作的愈来愈好。

除了比赛,实际项目对本身的我的能力提高与锻炼也是很是大的。

多去实践,将学到的东西运用到实际项目中去。不少人都找我抱怨过没有实际项目让本身去作。下面我会介绍到几种让你能够有项目经验的方式,项目经验对于技术能力的提高和面试都是很重要的。

想要提升我的硬实力,那么学习一门新技术的方法必定是相当重要了。


必定要有本身的技术优点,可能你懂得不是最多的,可是别人不会的你却会,那么你就是厉害的!

四丶写简历的时候项目经验这栏,怎么才有项目经验

若是实在没有实际项目让你去作,我以为你能够经过下面几种方式:

1.在网上找一个符合本身能力与找工做需求的实战项目视频或者博客跟着老师一块儿作。作的过程当中,你要有本身的思考,不要浅尝辄止,对于不少知识点,别人的讲解可能只是知足项目就够了,你本身想多点知识的话,对于重要的知识点就要本身学会去往深出学。
2.Github或者码云上面有不少实战类别项目,你能够选择一个来研究,为了让本身对这个项目更加理解,在理解原有代码的基础上,你能够对原有项目进行改进或者增长功能。
3.本身动手去作一个本身想完成的东西,遇到不会的东西就临时去学,现学现卖。

简历

华为Android开发工程师

阿里

公司到底想要什么样的人才?
我的方面:人品好,与公司以及团队文化契合,学习能力不错,抗压;
能力方面: 能力与你要应聘的岗位所匹配(不少时候不要认为本身能力很强公司就会招聘你,这意味着公司可能会花更多的钱聘用你。若是你的能力达不到的话,公司通常还会考虑你的潜力如何);

面试注意:

1.提早准备好自我介绍
2.提早准备技术面试
3.面试以前作好定向复习
4.面试复盘
5.提早知道有哪些技术问题常问,以及非技术问题

五丶面试,刷题

1.Glide的缓存机制

Glide的缓存机制,主要分为2种缓存,一种是内存缓存,一种是磁盘缓存。

使用内存缓存的缘由是: 防止应用重复将图片读入到内存,形成内存资源浪费。

使用磁盘缓存的缘由是: 防止应用重复的从网络或者其余地方下载和读取数据。

具体来说,缓存分为加载和存储:

  • 当加载一张图片的时候,获取顺序:Lru算法缓存-》弱引用缓存-》磁盘缓存(若是设置了的话)。

当想要加载某张图片时,先去LruCache中寻找图片,若是LruCache中有,则直接取出来使用,并将该图片放入WeakReference中,若是LruCache中没有,则去WeakReference中寻找,若是WeakReference中有,则从WeakReference中取出图片使用,若是WeakReference中也没有图片,则从磁盘缓存/网络中加载图片。

  • 将缓存图片的时候,写入顺序:弱引用缓存-》Lru算法缓存-》磁盘缓存中。当图片不存在的时候,先从网络下载图片,而后将图片存入弱引用中,glide会采用一个acquired(int)变量用来记录图片被引用的次数, 当acquired变量大于0的时候,说明图片正在使用中,也就是将图片放到弱引用缓存当中;若是acquired变量等于0了,说明图片已经再也不被使用了,那么此时会调用方法来释放资源,首先会将缓存图片从弱引用中移除,而后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

另: 从Glide4.x开始,读取图片的顺序有所改变:弱引用缓存-》Lru算法缓存-》磁盘缓存

2.ThreadLocal的使用场景?与Synchronized相比有什么特性?

ThreadLocalSynchronized虽然都和多线程有关.
可是ThreadLocal是为了多线程时,每一个线程对变量的独立访问.线程间该变量值互不影响.内部是由一个ThreadLocalMap,key为当前线程的弱引用,value为变量值.

Synchronized则是另外一个意思.多线程时经过同步锁实现多个线程同时只能有一个线程对变量/方法访问.

3.Kotlin中集合遍历有哪几种方式?

for,foreach,while,do while,递归,还有集合的高阶方法

4.对于GIF 图片加载有什么思路和建议

gif图实际上就是多帧合并的图

参考Fresco内部实现:

  • View层使用一个Drawable,包含bitmap,并依据gif的信息不断的更新并绘制bitmap
  • C层提供api功能,例如:输入gif数据流,提供解析gif信息、更新bitmap等功能
5.为何说Http是可靠的数据传输协议

HTTP是属于应用层的协议,TCP(传输控制协议)和UDP(用户数据报协议)是属于传输层的协议。

咱们都知道TCP协议是面向链接的,每次进行链接都要进行三次握手和四次挥手,因此它的链接是可靠的。而HTTP是在TCP上层的协议,因此它也是可靠的。

那为何TCP可靠?
首先来说一下网络的分层,因特网协议能够分为五层,分别是:

应用层->传输层->网络互联层->网络访问层->物理层

或许你以为很抽象,可是经过栗子你就会发现并无那么复杂
如访问一个Http请求:

怎么访问到这个网站呢?首先咱们须要经过网络,多是移动网或者宽带网等(这就是物理层,它是一个传输介质),而后找到对应那一台被咱们访问的服务器的mac地址(网络访问层)进行链接,再匹配它的IP(网络互联层)是否对应,肯定了主机后,再经过端口号9090(传输层)访问对应的进程,因为一个进程里面有不少业务模块,而咱们须要访问main模块(应用层),最终经过不一样层来实现网站的访问。

每一个层都是相互独立,而且向下依赖,而传输层是能肯定惟一主机的,由于咱们能够经过mac地址、host和端口来肯定惟一的一台访问主机上面的进程。或许有的人会问,那若是网络中断呢?那不就不可靠了吗,咱们常说的网络中断是属于物理层,因为是向下依赖,传输层的创建是依赖于下面的三层(网络互联层、网络访问层、物理层)已经链接成功,若是下面的层都没有链接成功,也就没有传输层这一说了,因此传输层协议是一个“靠谱”的协议。

咱们经过分层了解了传输层是“靠谱”的协议,那么怎么保证它是可靠的呢?

那就要讲到三次握手和四次挥手的做用了。

三次握手就是在创建链接以前须要客户端须要先给服务端发出SYN(c)报文,当服务器收到后须要返回客户端ACK=SYN(c)+1,而且传输本身生成的SYN(s)给客户端,客户端收到后进入已链接状态,须要再回一个ACK=SYN(s)+1给服务器,服务器收到ACK后也进入了链接状态,这就是一个三次握手的过程,经过双方进行三次通讯保证此时双方都已经进入准备状态。

四次挥手就是在结束链接的时候,客户端会发送FIN(c)给服务器,服务器收到后回复客户端ACK=FIN(c)+1告知客户端收到客户端的结束请求了,这时客户端就会进入CLOSING(半关闭状态),等待服务器的结束请求。 在一段小延迟时间后,服务器也会发送一个FIN(s)请求给客户端,客户端收到后发送ACK=FIN(s)+1给服务器,服务器收到ACK后就进入技术状态。客户端在等待2个MSL(避免服务器收不到ACK)后也进入结束状态。

在每次进行链接和断开链接都须要通过复杂的三次握手和四次握手,从而保证了每一个链接都是可靠的,因此TCP协议是可靠的,而HTTP就是TCP上层的协议,全部链接都是基于TCP协议的。

在咱们可以肯定每一个请求对应的惟一主机和端口号,而且经过Http协议添加响应的请求数据信息(如模块名字等)肯定请求的代码位置,而且在每次请求都经过三次握手和四次挥手保证链接的可靠性,因此一个Http请求是可靠的。

在咱们可以肯定每一个请求对应的惟一主机和端口号,而且经过Http协议添加响应的请求数据信息(如模块名字等)肯定请求的代码位置,而且在每次请求都经过三次握手和四次挥手保证链接的可靠性,因此一个Http请求是可靠的。

6.如何绕过Android9.0针对反射的限制

双重反射,即利用反射调用反射API,这个时候系统进行栈回溯,发现直接调用者是反射API,反射API也是系统API,就直接经过了

7.谈一谈Activity,View,Window三者的关系

在activity中调用attach,建立window;

建立的window是其子类phonewindow,在attach中建立phonewindow;

在activity中调用setcontentview(R.layout.xx);其实就是调用getwindow.setcontentview()

建立parentview;将指定的R.layout.xx布局进行填充

调用viewgroup,调用viewGroup先移除removeAllview();在进行添加新的view --addview().

8.如何进行单元测试的?以及如何应用在MVP和MVVM中?

单元测试库 junit mockito Rebolectric

说下mvp工程中的测试方法 测试主要有 三大部分

1. 普通工具类 使用 junit 直接测试
2. mvp的p 使用 @mock标注view的接口, 初始化真正的p, 直接调用p的方法 看看 verify view的某些方法是否按照预期被调用
3. mvp的v 用 rebolectric 去setup 一个Activity, 而后 用这个库找到 界面上的按钮,或者触发生命周期( onstart),判断一下当前界面的某些view是否被显示 或者 textview的值或者 dialog 是否显示 toast是否弹出错误
4. 还有网络部分的测试,能够直接使用junit进行测试 判断下返回值是否符合预期
9.请说说依赖注入框架ButterKnife的实现原理?
  • 经过注解器在编译期间生成一个XX_ViewBinding.java文件(XX能够是activity,fragment,adapter,dialog),这个文件这么生成的?

注解器里会添加须要类型的注解;查找XX类中的特定类型注解,若是有,拼接成字符串,建立并写到XX_ViewBinding.java文件中

  • XX_ViewBinding.java会持有XX的引用,若是是初始化控件,经过xx.findViewById实现,若是是设置监听,相似xx.setOnClickListener实现
  • XX类中初始化XX_ViewBinding对象,这样打通了整个流程
10.谈一谈屏幕刷新机制

屏幕刷新频率和绘制频率

cpu 负责 measure layout draw => displayList

gpu 负责 display => 位图

每一个16ms会发送一次垂直同步信号 vsync

每次信号发送的时候都会从gpu的buffer中取出渲染好的位图 显示在屏幕上

同时若是有须要 还会进行下一次的 cpu计算,计算好后放入buffer中

若是计算时间超过了两次vsync之间的时间 即16ms 则 vsync信号会把 上一次gpu buffer中的信息展现出来 这时候就是卡顿

另外若是页面没有变化 屏幕仍是同样会去buffer中取出上一次的刷新,只不过cpu再也不去计算而已

11.说说Kotlin中的Any与Java中的Object有何异同?

同:

  • 都是顶级父类

异:

  • 成员方法不一样

Any只声明了toString()hashCode()equals()做为成员方法。

咱们思考下,为何 Kotlin 设计了一个 Any ?

当咱们须要和 Java 互操做的时候,Kotlin 把 Java 方法参数和返回类型中用到的 Object 类型看做 Any,这个 Any 的设计是 Kotlin 兼容 Java 时的一种权衡设计。

全部 Java 引用类型在 Kotlin 中都表现为平台类型。当在 Kotlin 中处理平台类型的值的时候,它既能够被当作可空类型来处理,也能够被当作非空类型来操做。

试想下,若是全部来自 Java 的值都被当作非空,那么就容易写出比较危险的代码。反之,若是 Java 值都强制当作可空,则会致使大量的 null 检查。综合考量,平台类型是一种折中的设计方案。

12.谈一谈java线程安全的集合有哪些

1.早期的线程安全集合

  • Vector

= 所有方法加 synchronized 的 ArrayList

  • HashTable

= 所有方法加 synchronized 的 HashMap

2.包装工具类

  • Collections.synchronizedXXX()

在原集合的基础上添加了锁对象,集合中的每一个方法都经过这个锁对象实现同步

3.java.util.concurrent包

  • ConcurrentHashMap

1.7 分段锁技术,1.8 对table每行首元素加锁

  • CopyOnWriteXXXX

加了写锁,写的时候锁住的整个对象,读则能够并发执行

4.其余

  • Stack

继承了 Vector

13.请谈谈如何加载Bitmap并防止内存溢出

首先咱们 要知道bitmap内存是怎么计算的例子:

手机屏幕大小 1080 x 1920(inTarget = 420),加载 xhdpi (inDensity = 320)中的图片 1920 x 1080,scale = 420 / 320,
最总咱们能够得知 他的占用内存 1418 2520 4
很明显 被放大了。

防止内存溢出:

1.对图片进行内存压缩;
2.高分辨率的图片放入对应文件夹;
3.内存复用
4.及时回收

关于我

更多面试内容分析,分享,学习笔记整理,视频整理

https://github.com/xiangjiana...