因为各种原因,笔者又踏上了寻找新工作机会的道路,10天左右下来面试了7家单位,顺利拿到了4家offer,今天得以有空将面试的过程总结下来,一来给大家分享当中遇到的问题,二来是自我总结。这份面经是针对3-5年工作经验的朋友们,若不属于该阶段的朋友可以不用去在意。
自我介绍
本人不才,不是什么京东阿里大神,就一个想改变世界的普通程序员,高中毕业之后开始进入JAVA培训学校正式接触JAVA,19岁参加工作,到目前为止已经工作4年多,因为对技术有着浓厚的兴趣,一路下来研究并沉淀了不少技术,在这过程中先后自考了大专和本科,本科目前属于在读阶段,以后也希望能有机会考研。有和我一样经历的朋友建议能尽快去念一个本科,至少在很多公司对学历的要求是硬性指标,当然你可能说也有很多公司因为能力而适当放宽,那这里我不做过多的描述。
面试过程
- 因为参加工作时间也不短,在以往的工作中也面试过不少新人。所以现在几乎所有的面试过程中我都比较自信,也聊得特别开,当然也必须有足够的技术功底才能做到自信,这个就来自于平时的自我总结了,O(∩_∩)O哈哈~个人能力。
- 唯独在阿里巴巴的复式过程中比较紧张,这种紧张的感觉只有我当初第一次面试的时候才出现过,可能也是提供了一个机会比较看重的原因吧,路上还一直让我的朋友们替我打气,让我放松O(∩_∩)O~~,感谢可爱的人儿们。
问题技术点
设计模式、常用数据结构、线程、JAVA7和JAVA8比较、分布式、WebSocket、微服务、nginx单点、TCP/IP、分库分表、缓存服务器、JVM、内存管理、Linux、Git
详细过程
因为记忆不是很好,总结得不及时,所以有大部分都已经忘了,阿里巴巴是最近的面试,这里我以阿里巴巴的问题为例,因为阿里的流程走得比较慢,面过的朋友应该都知道,从简历筛选到一面电话,再到二面,再到交叉等等少说得2周,有的甚至更久,我的简历筛选好像也是一周前就发邮件告诉我,所以也是感觉不太好,毕竟多少人挤破头都想进的地方,我一个全日制都不是的技术人员有这个机会又何尝不是一次历练呢,然后一周后打电话过来了。
一面
一面是电面,杭州打过来的,电话号码也是特别6,当时在外面有些事,环境也比较吵,但也是足足聊了一个多小时,接通电话后把我目前工作的所有情况问了一遍,然后让我再简单介绍一下后就开始技术题了,自我介绍我觉得大家简单的说一说就行了,没有必要那么正式,阿里问的问题大多是连环的,一环接一环,问到你不会为止,如果你都会,那你很6。
请说说ArrayList、LinkedList、HashMap的区别
这里大家一定要把java几个常用的数据结构给弄懂了,早些年你可以随便说说他们如何使用的就可以找到工作,但是现在不是说简单的糊弄几句就可以过去的,懂的程度表示你技术的深度,这里的话我把回答点说一下
a.描述他们的上级接口父类关系、
b.描述如何扩容,不是说一实例化就会扩容的,大家可以跟进去看看源码,有同学debug细心也会有所发现
c.他们各自的底层实现
这里我拿HashMap做解答:HashMap和HashTable虽然都实现于Map,但他们继承父类不一样,HashTable继承自旧的Dictionary,而HashMap的父类是AbstractMap,HashMap的负载因子为0.75f,初始化和ArrayList一样容量都是0添加变量的时候才会进行扩容,HashMap当容量实际大小达到0.75*总容量则再次触发扩容,即达到3/4扩容。掌握这些还不够,因为你还没有说到面试官真正想要的,这个时候继续。因为HashMap是异步的,所以会存在安全问题,至于为什么会有安全问题,不了解的同学可以自己学习下,那要解决安全问题可以采用同步关键字,进行线程同步操作,早期也有人这么使用过,但是这样会存在很大的资源弊端,引发阻塞产生故障,可以采取concurrent包中的ConcurrentHashMap,接着就说到点子上了,面试官就是想要这个东西,ConcurrentHashMap是如何做到同步且提升效率的大家可以自行学习,这里描述不完,还有concurrent这个包也要好好学习,另外再引申一点,1.7中HashMap采用链表数组实现,1.8之后改为前一部分使用链表数组,但是达到存放阈值后改为红黑树实现,主要是解决hash碰撞问题,至于什么是hash碰撞,大家也是必须掌握的。如何保证线程安全
这里我回答的是加锁,其实我这个回答也是不尽人意的,因为我没有描述出具体的解决方式。接着又问我怎么加,锁哪里,当时我就想说“哪里不行锁哪里”, 说实话工作这几年,还没有考虑过高并发需要加锁的场景,一直都是在网上找资料学习理论,所以这也是我一直薄弱的地方,因为在开发中这样写过但没提供场景真正实验过,就算知道,说出来也比较虚,言归正传,最传统的做法是使用synchronized 关键字解决,可以保证一次只有一个线程通过,这里需要对synchronized描述详细使用场景,交给大家脑补。第二种做法采用concurrent下的ReentrantLock 加锁的方式来解决,大家看仔细了,又是concurrent对吧,所以这个包是特别感人,特别6的一个包,ReentrantLock 使用lock的方式大家过后自己学习,由于本题我描述得过少显得过于尴尬,所以我补充回答了悲观锁和乐观锁机制。谈谈你对事物的理解,如何解决分布式事物
首先我简单描述下什么是事物,事物特性ACID以及隔离级别,因为我看到后面的重点最终是落到分布式上,所以我开始说到spring中集成事物的几种方式。我先描述了传统解决事物的方法,使用逻辑进行解决,待A服务执行完毕之后将结果返回,然后去执行B服务,若B失败,则代码回滚A,这样做也不是不行,但是显然是比较废的一种方式,另外我还说出了一种学习过但没有使用过的方式,就是采用MQ发送可靠消息以及数据库状态日志解决,至于原理大家可以去网上学习。微服务架构使用过或了解过哪些,有什么区别
微服务作为一个近两年很火的话题,应用的公司必然不少,几乎我面试的公司中都有关于微服务的话题,那这里凡是研究过或者了解过的朋友都知道阿里巴巴开源的dubbo,当当网升级版的的dubbox,以及springcloud等,那提到微服务自然就能联想到MQ,zookepper,redis等等技术,这些都是需要大家花时间进行研究的,网上案例也特别多,对于MQ和zookepper和redis大家可以看看我的其他文章,高可用集群都有进行讲解。在最近一份工作中,我们采用的微服务架构是基于数据库注册API,采用redis缓存+MQ进行消息传输模式,进行服务调用,与dubbo大同小异,所以这个问题我也描述了不少东西,这块大致是过了。结合项目进行提问
描述一个项目后,抓着一个点深究,是如何解决这个问题的,就例如返佣,是一笔一笔的返还是怎么弄的,如果数据量提升到现在的100万倍,如何解决,有些问题确实没答上来。非技术问题
这方面我想面试几乎都有被问过,问今后的规划,这块因人而异吧,只要是积极向上即可。
二面
二面是邀约现场面试,因为在一面结束后我提了一个小小的要求,如果说我能通过,因为经济原因,那边能不能尽快明天给结果,面试官说我们的流程一般都是一周,我待会再备注下,如果合适的话尽快给结果,所以当晚就有阿里的hr给我打电话安排了第二天的面试,说实话阿里的技术生态体系确实可以,钉钉直接就推过来了,二面的时候是一个看上去40多岁头顶都秃得发亮的技术人员,我希望我不要这样子,毕竟生活是很美好,少那么一丢丢很不愉快,闲话不多说,自我介绍忽略,直接上问题(二面挂了)。
支付宝有好几亿用户,如何使用缓存服务器进行用户数据的存储
说到缓存服务器,大家都会想到Redis和Memcached,前者更多的是基于缓存持久化的,支持的数据类型也特别多,后者是基于内存的,这两个各有各的使用场景,所以说不能说谁好谁不好,关于redis我有文章进行详细说明,了解基本原理之后接下来就要说应用场景了。笔者不才碰碰磕磕的说了种解决方案,没有达到面试官的效果。我是这么说的,在业务层,用户对关键信息筛选,毕竟第一层大流量是关键信息,次要的放在第二层,采用分布式redis多节点部署,使用hash取模算法进行服务器的分配,这样可以保证服务器分配均匀,但是后面接着问我,服务器节点扩容或者删减,算法就改变了,又该如何解决。确实会特别麻烦,然后我实在是想不出来,也就结束了这个问题。500万的用户数据,我现在想要通过redis快速的统计90后人群,以及90后男性人群
当时唯一能抓住的就是两个特征,90后,和90后男性,于是眼前一亮,觉得可以拆分出:70/80/90后,男性/女性,存储的时候就存这几个关键特征所对应的id集合,然后进行采用“集合并集”方式就可以定位出90男性,不知道是不是面试官想要的结过,但是我觉得这样应该是可以实现的。这题是一道算法题
算法是我的弱项,自己几斤几两还是有点B数,所以稍微有点紧张,给定一个数列,9 13 17 25 3 5 8,它对应的原数列为递增数列3 5 8 9 13 17 25 ,我们不知道原数列,只知道给出的现有数列,表达式为f(n),求n。稍微有点数学基础的同学应该都知道怎么算。我也一眼看出来了,既然原数列是递增,那肯定有一个位置是递减的,那这个点就是临界点,求出前面的长度即可,然后面试官接着问我,你这个复杂度是多少,对于复杂度,不懂的同学可以去网上学习下,因为从左到右每个都要遍历下我说O(n),于是问我有没有优化的,我觉得就算我做出了第二次优化,提升到log n,他还会接着问,于是我只能想到二分法了,毕竟这是普遍做法,再接下来的我不会了。其实这道题跟1-100楼扔鸡蛋是一个道理,其中有一层是临界值,意思就是那一层往下鸡蛋是不会摔破的,往上是会破的,以最快的方式求出那一层,我也看过那道题,二分法同样可以算出来,但是最优解不是二分法,所以阿里巴巴的本次面试就到这结束了。
其他公司面试题
其他公司虽然不是很接近算法题目,但是也是java里面比较深入的,虽然数据规模比不上阿里巴巴,但是面试题目也是比较重要的,下面我抽取几道难度稍微高一点的
说说你理解的GC
其实GC在过去我真没了解过,也是最近一年才接触JVM,不过学好JAVA,JVM是必须要懂的,就算看不懂也要硬着头皮去看,这对写出高质量代码真的是很有帮助的。
JVM体系分哪几个区,类加载过程是哪些,双亲委派模型是什么,如何自己实现一个类加载器,对象的4种引用,minor GC和full GC,对象如何被回收,如何对GC进行调优,你用过的内存调试工具有哪些说说你对TCP/IP的理解
这个自己说吧,3次握手,4次挥手,SOCKET通信,能了解得越多越好BIO、NIO、AIO有什么区别,各自的原理
其实这个东西了解了原理大家就知道是什么了,阻塞IO,非阻塞IO,异步IO,netty实现就是基于非阻塞IO,采用非阻塞IO的工具或是服务器也特别多,大家自己了解啦分库分表,读写分离
分库分表看情况,可以水平也可垂直,但是水平和垂直都必须满足他们各自的基础条件,另外解决数据落地的平衡即可。MySQL Proxy可实现多节点读写分离,但是其实也就一个代理,存在单点问题,笔者也是对这块没进行过深入研究,所以给不出更多的结论了。如何对业务进行拆分和扩展
这道题属于业务层的,不好说太多,在模块划分时确实要经过严格的思考,否则带来的开发问题会很多,看个人经验吧。说说CI和CD的区别
因为我在项目中有接触过持续集成和持续交付的,也有研究过持续集成例如jenkins和hudson工具,所以说问了我这个问题,持续集成多用于互联网公司的项目快速构建,功能模块的快速完成,交付至测试,但是CI和CD的真正核心还不是在于自动化,自动化是一方面,更重要的是代码交付质量,在这一层花的功夫确实要比较多。
总结
技术更新很快,在刚入行的时候,随便说个list set,写个sql的group或者jdbc连接就能找到工作,现在呢?所以说做为一个技术人员,对技术的探索自然是不能停,对工作也要富有责任心。遇到问题不要放弃,没有过不去的坎,对技术而言总结几点如下:
- 不要抵触,要敢于接纳新事物,新需求。(重要)
- 对技术产生浓厚的兴趣(非必须),但至少保证不是拒绝,否则很难持久(很重要)
- 在学习路上出现问题要找合适资料,那些破资料枯燥到能让你放弃,多寻求google而非度娘。(你懂的)
- 技术在于沉淀,请坚持学习,记住,坚持过后必有收获。(真的很重要)
- 做技术更多的是要参与业务分析再落实到功能实现,业务转化不了技术说明你写不出代码或是只能写出不能用的代码
差不多就说这么多吧,以上都是个人见解,也正在学习路上,有不对的地方希望朋友们指出,希望更多的是能帮助到大家