在这个行业和社会都处在特殊时期的时期,有多少人正在找工作,或者正准备找工作。。。本文想从发展阶段、主语言、项目等几个方面来总结下我们到底应该怎样准备面试和发展我们的技术,希望可以给各位带来一些帮助~
- 关于阶段
对于职场人,在这方面情况基本应该都一样,一年 、 三年 、 五年。。。基本都可以用这个时间段来给自己定个衡量的标准,每个阶段要达到这个阶段应该具备的水平。
2~3年
经过一年的历练,基本的开发技能和语言特性都应该有所了解,这个时候,就是从初级向高级转化的重要阶段。要把停留在使用层面的知识研究的更加深入,要知其然也知其所以然。只要理解透,我们是不必惧怕传说中的连环炮的。
例:
问:什么数据结构可以快速查找一个元素?
答:hashmap。
问:为什么可以快速定位?
答:散列算法。
问:hash函数是怎么降低冲突的?
答:扰动函数通过高位和低位特征融合,减少低位取模时的哈希冲突。
问:1.7 和1.8的扰动变化是否了解?
答:四次降为一次,边际效应,投入产出不对等。
问:1.8还有什么改进?
答:链表转树。
问:为什么转树,为什么用红黑树,而不是其他树?
答:链表查找效率低,红黑树调整效率比其他平衡树树高。
问:为什么扩容要保持2的次方,和此相关的1.8的改进了解么?
答:保持2的次方,在hash函数中取模时,直接移位就行,速度快,1.8在扩容方面进行了优化,不再计算哈希值,直接用旧的容量加上偏移量,允许这么做的前提是保持2的次方和两倍扩容,提高速度。
问:1.8对并发下的死锁修复?
等等。。。。。
3~5年
这也是个重要的阶段,这个阶段是一个知识融会贯通的时期,要把点连成线,把线连成面,把面组成体,然后再窥探整个生态的组成和发展。
我们要从hashmap关联到支持并发的currenthashmap,从而可以关联到currentHashmap 原理中锁的运用,那自然就想到了锁的种类,每种锁的优缺点。
说回来,为什么1.8里currenthashmap要弃用Lock改成synchronized,那就要谈到synchronized进化史,就有了偏向锁的原理、偏向锁的缺点、偏向锁在高并发情况下对系统性能和gc耗时的影响,什么情况什么时间怎样撤销偏向锁、什么是安全点为什么要有安全点、什么情况会使用到安全点。
谈安全点肯定谈到gc,那gc的发展历程,cms到g1到zgc都有哪些提升,从对象的可达性分析联系到root对象的种类,这些对象都是存在哪里,然后就自然想到了jvm内存模型,对象的加载创建,内存中哪些地方存储哪些东西,为什么说G1适合更大内存规格的服务器使用,因为它使用额外的内存空间来创建Rset,有什么作用呢,说白了就是空间换时间,提前维护每个内存区块的内部信息,已遍快速精确的根据用户诉求,控制垃圾回收目标。
那么还有哪些地方用到了这类思想,可能想到redis,比如字符串,底层自定义的struct中,包含并提前维护了原始c语言字符串结构,还有相关的各种信息:长度、富余可用空间等等,用空间换时间,达到操作时的高性能,那么redis的高性能还有哪些方面,单线程,多路复用io。
谈到多路复用,可能就联系到了NIO、netty,什么机制促成了其高性能,其用途那自然是各种rpc框架。
Rpc的话,负载均衡有哪些策略,除了服务端rpc的负载均衡,还有哪些地方需要负载均衡?
那可能是ip解析,四层七层网络协议这边的事了,用ngix,HA来进行上层负载。
rpc服务发展机制用什么实现,可能想到dubbo的zookeeper注册中心,那基于zk的注册中心有什么问题,曾经老东家用zk做注册中心,为什么在大促时候出现了血崩。。。。。。
遇到问题多想一步,收获可能会大很多。当然,上面的这些也只是在知识层面的相互联系,或者还应该可以把他们揉在项目里,用了某些策略带来的连带影响,业务场景对技术选型的要求等等。实话说,这两个阶段,我自己应该是没特别把握好的。顿悟的太迟了。。。
- 关于主语言
作为自己吃饭的家伙事,不管你有多全能,主语言是一定要通透的。不过对我就是Java没有主副之分,因为其他我也不会呐( ˃᷄˶˶̫˶˂᷅ )
(图片来自网络)
Java的生态非常庞大,不过只看语言的话,其实可以摘出四个比较重要的方面,如果是在准备面试的小伙伴,按这几个模块挨个的啃啃,应该也是不错的选择:
数据结构、并发、IO、虚拟机
当然,像我这种渣渣,肯定是没法把所有的点全部掌握的,像IO 、网络 这部分,我就基本上是泛泛的了解,因为写的都是服务端上层业务,基本也没有机会接触到底层的通信。不过我们可以想办法往我们熟悉的区域蹭,引导面试官。
比如项目中经常使用线程,那就可以吹一会线程的东西,怎么评估业务场景,怎么确定线程池参数,为什么重来不用java提供的线程池创建工厂去创建线程池,自动创建的那四种线程池各有什么弊端,会带来什么问题,线程池提交的任务结果怎么获取,有什么问题,设置超时的必要性,线程池超时中断原理等等。
又比如我们有压测调优的经验,那又可以从jvm的角度来扯扯,我们的用户规模,访问并发,机器集群数量,规格,gc策略,线上问题,调优方案,gc时间的影响因素,堆大小,对象大小在高并发下对gc的影响。线上oom的原因,处理方法,保存现场,止血,问题分析等等。
值得提一句的是,如果我们身在大厂,对原始的常用操作命令还是要适当回顾了解一下,不能当人家问我们,怎么保存现场呢,回答,公司有九州操作平台,我们点一下dump就行,这样就显的low了点, 就比如我 ?,不过我说的也是事实,越大的公司,对线上服务器的权限控制越严格,一般是不会允许我们自己搞命令行的,重启大法还是最有效的 。
- 关于项目
项目这一块是个大头,一般面试,都要求讲一个自己认为最牛逼的项目。简历上的东西最好都提前回顾下,我记得有次面试,就很大意,就没在乎上一家公司的项目,被一兄弟逮住一通问,都他妹的忘了,白白让他享受了一波虐人的感觉。
如果项目吹的好,基本半个小时开外了,其他的点也就捎带一下,当然,前提是我们要吃透项目的整体架构,上下游的依赖,然后就是里那些最牛逼的技术点,最好是自己参与过的。
比如说用到了分布式事务,那就要知道业界常用的XA、TCC这些方式和原理,特别是处在阿里这种公司,很多东西都是定制化,不和业界的通用技术来对比着看,总有些自说自话的感觉。
要知道它的发起方、参与方、协调者等角色,要知道怎样通过spring的后置处理器等钩子函数注册二阶段处理器,什么时机怎样将主事务信息和分支事务信息落库,落哪些信息就足够二阶段进行,怎样通过数据库中的字符串字段找到对应的二阶段服务,发起二阶段调用。
更重要的要知道服务器宕机时候事务怎样恢复,网络延迟抖动的时候,怎样防止资源悬挂,怎样幂等防重发。要把这些能清晰的讲出来,能把具体的对应方法讲清楚,即使有些地方没做过,只要能讲清楚,应该也是可以的。
当然,不是自己做的东西其实也可以讲,不过要能基本理解其原理,比如阿里这边的单元化部署,同城和异地容灾,流水数据库和状态型数据库各自的failover方案演进,只要能讲明白,起码证明在这方面我们有一定的积累和关注,同时也是对服务稳定性和高可用的理论经验吧。
不太熟的东西最好不要提了,如果正好遇到一个对这个东西特别熟的兄弟,那就会死的很惨了。用的啥数据库?OB。哦?那OB怎么部署的,用什么方法兼顾其高可用和性能,强一致性策略。因为了解的不深,所以被问了一脸。你说我说用的是mysql不挺好么,不过可能也会被呲:“胡说,你们肯定用的都是ob,来 给我说说ob吧!”
- 关于框架和中间件
这部分其实是比较能体现我们技术深度和广度的。因为这些东西基本都是现成的,而且是平常开发用不到的,RPC,消息队列,ZK,Redis 等等等等等。。。
这块我其实还是欠缺不少的,只能大概的应付应付。其实说平常业务需求忙、用的都是公司定制化的中间件都是借口吧。时间像海绵,挤挤总是有的。。。
革命尚未成功,同志仍需努力,共勉共勉~