面试单位:全国500强大型企业。职位:高级java开发工程师(共分初中高三级)。待遇:15-30K,16薪。基本要求:5年以上开发经验,3年以上leader经历,3个以上大型项目经验,熟悉设计模式,性能调优等。
标题很俗气,估计大牛看了会不屑的说:厚积薄发就是最好的面试策略。我要说的确是厚积薄发,技术是没有捷径可走的,但技巧可以更好的展现自身能力.
相比大牛,我只是在一个恶劣的IT环境中坚持技术的平凡人。之所以叫吐血分享,是因为面试很成功但结局早已注定失败,难受得想吐血。
就像二战德国闪电战一样战术上非常成功,但战略上去挑战美苏两大巨头的秩序,注定了失败结局。
我学习起来的狂热连我自己都怕,但无数失败教训证明了运气更加重要,学历这个战略点一直没拿下来。
自从上次面试.NET大受打击(见也记一次失败的面试),开始注重理论学习,时隔一年多卷土重来,虽然实战经验为零(之前失败的是电话面试),但去面试的路上信心满满。
虽然是java面试,但思路和C#是一样的,高级程序员面试中大部分问题和编程语言无关,更注重理论在实际项目中的使用. 基础部分题目虽然简单,但竞争对手众多,要杀出重围必须比别人回答得更完美。
我心中对几种选手这样分类的。初段选手:回答完概念完事。进阶:举应用实例或适用场景。专家:结合自己的使用经验。
很多人觉得题目很普通,的确初级到高级都会问同样的问题,但是深度不同。如果仅仅回答标准答案,没有自己的运用和融会贯通,是不可能获得评分的。面试官甚至不会提示你。
一、基础问题:
0,讲讲spring
除了标准答案,IOC和AOP外,我讲了下代理模式。
然后面试官问题来了,讲讲你自己实现过的AOP代理模式。
这里我老实说没实现过,但应该可以参考多语言国际化的写法来做。
这就是地狱难度,上来先一个下马威,打服了再说。
spring深入理解起来博大精深,我想专家级程序猿如果了解spring,最后可能会被问到源代码的问题上。
1,抽象类和接口的区别:
回答完概念后,我举了适配器和装饰器模式例子。适配器是把一个对象的接口转换供另一个接口调用,比如io读写的字符流通过适配器调用字节流对象来完成。
装饰器模式是接口不变,把一个抽象父类的功能增强,比如文件io流就是实现了io流抽象对象,调用文件读写的io优化,增强了io功能。
最后我举了自己项目中做C语言做USB转串口的适配器模式。
2,讲讲单例模式:
回答完概念后,我讲了饿汉和懒汉单例的实现,spring的默认单例运行。然后罗列一堆开源项目使用的单例+线程池。
最后讲了自己项目中使用的单例。还讲了适用范围的,此处单例仅适用于程序内部,系统中程序只允许启动一个实例的单例实现。
3,讲讲string在内存的存储:
答完string和一般值类型如int、double的不同,存储在JVM的堆上,在栈上保存对象的引用。然后快速介绍jvm的GC算法。
最后讲了在代码中如何避免内存泄露。
4,cookie和session的优缺点:
回答完标准答案后,我讲了一些自己项目中session共享的实现,快速画简要建构图,然后简单说了一下nginx反向代理配置tomcat集群,tomcat里配置session由某个开源插件来实现,session的产生由redis服务器来完成。
面试官刚好也研究过,问我单点登录怎么解决,我session共享关键问题解决后,只需要加台用户中心服务器即可。
实际上单点登录我并没有完全实现,但这堆应付面试是无伤大雅的。真要实现单点登录环境,相信给一周时间也能做出demo。
这时发现一个细节,面试官手里的纸上写了一些我说过的技术点,在设计模式和内存管理后面又加了一个单点登录。
二、进阶问题
5,讲讲多线程
我直接把《多线程编程核心》书里的知识点快速介绍一遍,然后说了一下多线程实现生产者-消费者的伪代码。
讲了MQ消息队列的点对点模式类似实现,引申出了MQ消息队列的发布订阅模式。这回有点表现过头了,说到一些公平锁和线程调度方面时,面试官有点发愣,我赶紧停下来等面试官问。
果然面试官可能有些不快地说,多线程你只是理论看得多,实际项目没有使用过吧?我赶紧说不好意思,我说到自己擅长领域就忘记了环境(当然我确实也没有游戏编程那种多线程经验)。
面试官态度变好了,我便拿那个专利项目举例,说多线程除了异步等待耗时操作外,也可以用在纯计算耗CPU的场景,有几个CPU核心开几个线程把CPU全占满,以加快计算。
多线程被顺利加入清单。
6,前面提到了MQ消息队列,那么你对分布式有什么经验?
我坦言分布式只是最近我在学习的,画了个简图,简单讲了下dubbo、zookeper、activiedMQ、redis、FastDFS组成的分布式架构。
分布式有所了解这个技能又被加入清单。
7,讲讲你项目架构中的性能优化
状态越来越好,性能优化我准备多时早就饥渴难耐了,这里的纲要按照 架构设计思维导图 来讲。
分前台,后台,数据库优化三大方面来展开。
最后结合了我写代码的规范标准,自己总结的不比大公司人多力量大,作为单打独斗的野生程序员能做到这个地步也差不多了.
8,我们数据安全性很高,讲讲你的安全设计
我讲了下自己登陆体系使用过的技术,密码MD5,RSA加密用户输入数据,AES解密数据库连接等。
中规中矩吧。
9,讲讲springMVC原理,及如何注入的
非基础方面可能问不出什么了,于是搞面试官冷不丁抛出一个基础问题。我的思路一时无法从系统架构的状态上切换过来,想了10秒也想不起。
在面试官引导下,我说了通过包扫描来注入。面试官说很正常,他也经常忘记一些基本的东西。
10,final,finally,finalize的区别?
基础关键字,如果这个答错应该是会被扣分的(其中finalize方法是在垃圾收集器删除对象之前调用的)。
当然基础知识我怎么可能忘记,顺便发说了一下service中一般不使用try catch finally,自己处理的话,配置的事务处理就不起作用了。
三、杀手问题
11,看你的项目经历,是开发企业应用居多,没有互联网和电商项目经验。现在我问你如果是电商项目,你如果拆分成分布式项目。
这个问题直击弱点,这里其实已经不是考察能力是否匹配职位需求了,应该是为优中选优准备的附加题。
我答不上来,就说了下我对自己项目分布式拆分的思考,因为我从搭建自己项目那天开始就想着给企业所有几万用户使用,腹稿早就有了。
然后推理电商项目中用户、支付、交易记录这些也注册为基础服务。利用分布式缓存提高性能,分布式文件系统来存储海量数据。
500强企业的专家级面试果然是变态,当时我不知道分布式数据库这个概念,导致后面被针对海量数据和分布式数据库攻击。
12,前面说到海量数据,你对海量数据有哪些了解?
杀手问题果然是连环陷阱,就看你能闯过多少关获得加分了。还好我每次回答都注意答案出现的相关概念都至少是自己了解过的,以防御针对弱点攻击。
我说海量数据加算法=大数据,讲了几个海量数据的典型算法, 提到海量数据算法又顺带讲了分布式最终一致性那个二次提交确认的算法。
说到面试官不了解的领域再次被打断了,面试官又问我下一个杀手问题。海量数据算法了解的标签被加上。
13,我们公司的的数据中心,经常会遇到短时间写入上百万数据场景,你会怎么处理?
答案应该是分布式数据库,前面没提到分布式数据库,这里再次被针对弱点提问,巧妙的隐藏概念,防止浑水摸鱼。
开始我说用MQ消息队列先消掉高并发峰值,向订票系统那样延后操作。面试官说要求实时处理,你这想法只是推迟。
我想了一下又说再加分布式缓存,面试说还是实时性不够。
我突然想到做单片机时,为了提高数据传输量,增加多几个IO口一起来传输。讲了到利用NIO的原理多增加端口来提高数据吞吐量。
面试官说好了然后问了最后一个杀手问题。
14,你自己写过开源框架吗?
果然是终极问题,一般大牛要是写了开源,早就会在简历显眼位置上标注并宣传,并会在面试时主动提出。不会留到最后等面试官问题
我想如果回答写过,一定会悲贴上不诚信的标签,然后来个突然死亡。
当然我说没写过,面试官继续问当你遇到的开源框架并不适合,一定要自己写怎么办?
我说我还没能力写框架,但据说观察开源框架一定是符合这些标准的,比如代码优雅,遇到创建和销毁耗资源的场景用单例,然后又列举一遍使用了单例加线程池的框架。
我继续说spring是标配,大胆使用spring优雅的开发。最后讲了下自己学习phogap时使用angularjs实现了公共的factroy和controller,然后开发功能模式,只需要像ajax一样传入请求url和参数就自动实现了列表页面和查看页面。
再迁移一些JS类库进来,勉强算是实现开发框架吧。
面试赞许了一下,不过他并不了angularJs,可能得不到这个附加分吧。
面试结束了,我看了下时间,两个竞争对手的时间加起来大概一小时,我大老远做高铁过来所以排在最后,大概用了50来分钟。
面试完意犹未尽,我一直精神高度集中快速回答,回家后不停的回报过程,并把回答得不好的分布式数据库理解了一遍。
并计划读一个典型开源框架源码,以后可以说在读开源框架的源码,为早日写出自己的框架做前期准备了。
但我很清楚自己并不是威震天能做大佬开创道路,我只是一台为生存而战的量产T800型终结者。
然而,第二天接到HR的通知:
很抱歉,您的面试效果很好,但由于学历问题没有给您发复试通知。已经努力和总监为您争取过,但总监不同意。