前言-
致那些迷茫的JAVA面试者(特别是南京的1-4年经验),致那些奋发的年轻人,致自己。写这篇博文主要也是对我的成长道路的记录,面试受挫后的反思,及对自己的勉励。
本人介绍:3年多经验的程序员,坐标南京。
背景:因水平有限,及对部分面试问题记忆及理解有限,可能有些问题并不能表达准确。掌握技术有限,学习主动性一般(虽遇到问题善于思考钻研,但如果没有遇到问题比较放纵自己...被自由,轻松,安逸迷失心智),以及原公司项目背景因素,基本不需要太多新的技术框架支持,更没有涉及消息中间件,高并发分布式等等相关较主流技术,技术体系相对较老。综上导致我对很多新技术并不是太了解。
面试经验背景:基本公司都是按简历掌握技术来问(当然也有超纲不按套路出牌的),如果你简历掌握技术什么都不写,也有可能接到面试邀请,那么面试官问题可能就比较广了,对面试者不利。掌握技术我写了java基础:多线程,io/nio,jvm,集合底层,tcp/ip协议,socket,websocket。spring,springmvc,xml,设计模式,eclipse plugin开发,数据库,前端(基本没有什么人问,面的后端开发,也许熟悉前端也是加分项)了解netty、mybatis、redis(实际就是看了一点点).
项目经验背景:
1.原公司我所在的部门做的是一款大型工具,web项目。项目周期很长很长,至今还在做,具体不细说,技术上就用了上述我写的部分技术(未涉及redis、netty、mybatis、springmvc),作为项目经历,该项目竞争力不强。
2.朋友找我做的私活项目,只接触了一个星期左右,朋友就跟接活人闹崩了,然后不了了之。但是我还是把项目写进项目经验了(投递的时候写,自带的纸质简历就把它去掉,以防面试官问到我一脸懵逼...机智如我,当然也有公司不需要你的自带简历,那就没办法,他问到的话我就忽悠,坦白)。实际就是个特别小的项目,用到的技术springmvc,mybatis,redis,activemq,阿里云对象存储等等。这个项目我只稍微了解了一点点springmvc,mybatis,redis最最基本的用法,可以说没啥用。
面试经历(具体录用薪资我就不说明了,只说我对薪资+公司福利满意度。
面试中项目介绍必定要说的,以及项目中的细节问题,这些不细说了。只说技术问题)
按时间先后排序(时间越远遗忘的问题可能越多。很多重复的,将就看吧)
1.小公司
名字忘了。时间久远,只记得有多线程,线程池拒绝策略,jvm调优,tomcat调优,消息中间件,分布式,集群,zookeeper,微服务。sql左连接右连接区别,存储过程。linux。基本全程懵逼,(因为第一次面试,简历技术什么都没写,这货敞开了问)。最后竟然通知我面试通过。
难度-难
公司环境-不满意
薪资福利-不满意
工作内容-不满意(忽悠我刚开始写逻辑代码,以后可能会做微服务,大数据,基本不加班,我是不信的)。
2.软通动力(华为外包)
stringbuffer和stringbuild区别,stringbuild线程不安全体现在哪,你对线程安不安全怎么理解(这个问题发挥空间很大,关键词:全局变量、JVM运行时数据区、可见性、原子性、锁、甚至可以说到多核cpu硬件层面(我是不会的)),arraylist和linkedlist区别,spring ioc,aop作用,原理。springmvc执行流程(这种问题最扯淡),hashmap原理(问的很浅,底层结构,答数组+链表/红黑树。他就没问了),hashmap,hashtable,concurrentHashMap(大致基本说下,他就不问了),hashmap遍历。对大数据有关技术了解多少(答:了解一点,听过hadoop)。其它忘了,总体难度不大。写代码:字符串分割排序(split+冒泡))。
难度-简单
薪资福利-一般
工作内容-不满意(外包你懂的。有关大数据方面的(这点还可以),更多的是数据清洗)
3.鸿信集团(电信子公司)
一个年纪比较大的面试官,像管理层人员,感觉技术水平有限。基本就问了项目,spring的理解,activemq,没了。笔试,扯淡的笔试题,写了一点走人了。公司整体给人的感觉比较自由松散,适合养老。感觉技术上没有发展空间。
面试建议-别去
4.苏宁
我前后面了4次(因为住的地方就靠着苏宁,没事就顺便去面试打发时间,4个部门,通过了3个)。写一起。
苏宁金服:问的项目业务,公司业务模块(无从下口),为什么要用redis,相比于如memcached,mongodb有什么优势,mybatis,activemq。springmvc有什么好处,为什么要用它,springmvc和struts区别(都不会)...用过什么数据库,有没有做过数据库优化,什么情况下要用到索引,好处是什么,哪些字段适合建立索引,mysql索引底层数据结构了解吗,索引什么情况下会失效,联合索引abc只用了a字段,索引是否会生效。什么情况下要用到多线程,为什么要用,好处。启动多个线程,如何知道他们都运行完毕了。jquery要想取某个节点中的第几个元素怎么写,具体哪个方法((我看你是闲着蛋疼)答:元素选择器,find,eq)。 总体回答的很不好,感觉他就盯着我写的了解程度的技术问,有为难我降低我薪资要求的意思。最后通知面试通过(也许是真的缺人,也许是我吹牛比较6,画了项目流程图给他)
难度-对于我来说难(其实一般,主要是我实在不太会他问的框架技术)
薪资福利-一般(面的不太好的地方我是不太好意思去的,感觉进去有种抬不起头的感觉)
苏宁易购网站购物车消费者业务线:string为什么是不可变的,重写重载,object类有哪些方法,sleep和wait区别,实现线程的方式,run,start区别,线程有几种状态,synchronize实现原理(这个问题可以说的很多,建议大家往深了看,往深了说,以震慑面试官),与lock区别,还知道哪些锁,说说自旋锁。线程池,线程池等待队列,拒绝策略,死锁产生原因。为什么java可以一次编译,到处运行。事务特性,索引失效,mysql有哪些函数。http和https区别,get和post区别,springbean是单例吗,spring源码看过吗,其中的单例bean是怎么实现的。redis有支持哪些数据结构。servlet怎么取前端参数。(两个面试官,感觉面试官水平有限,一直在想问什么问题,越问越没难度)设计个洗牌算法。线上购物车需要有个标志唯一id,有什么方法实现这个id(uuid,参考jdk中random实现原理,取随机种子)
难度-一般
薪资福利-一般
大数据部门:抽象类接口区别,接口中可以定义成员变量吗,默认是什么类型的变量(public static final),接口中方法权限可以是private吗,接口是否可以写具体实现(答:jdk8开始可以)重写重载区别,线程的实现方式(我已经感觉到这个部门有多缺人了)。sql交并集,事务隔离级别。能调用另一个类的私有方法吗,怎么做。如果线程池执行shutdown或shutdownNow,线程池中线程会中断吗,会出现什么异常,catch处理中该写些什么。用过哪些concurrent包下的类,说说原子类,cas操作可能会存在什么问题。jdk中有哪些设计模式的运用,项目中用了哪些设计模式,treemap中compartor用了什么设计模式,有哪些单例模式的实现方式,springbean是单例吗。如果想要在某些自己指定的某些方法前后打印日志怎么实现(答:自定义注解,问:具体怎么做,答:spring aop的实现思路...),注解实现原理。
面试难度-一般
薪资福利-较满意
苏宁物流部:苏宁最难的一次面试经历,也许是晚上面试,时间充分,安静,面试官比较好发挥,我全程半懵逼,面试官是中年人,看气势最起码经理级别。
servlet和jsp区别,如果没有servlet,jsp怎么跟后端交互(大概是这个意思,没听太懂,一脸懵逼)。springmvc怎么取前端数据,springmvc模式下,如果没有注解怎么取前端参数(答:servlet,requset.getParameter。他问,具体在哪怎么用,也没听太懂,懵逼)。搭建springmvc项目步骤。spirngmvc controller中定义全局hashmap,它是否是线程安全的,为什么。
Io nio区别,nio原理。netty用的多吗。答,不多。
项目中用哪种方式解析xml的 答:jaxb,dom4j,digester。问:jaxp是什么。 答:是jaxb,巴拉巴拉... 问:哦哦,挺好用的
servlet生命周期。tomcat在初始化中做了什么事(答:启动socket服务端...问:没了吗?答:... 很明显该回答的还有很多,想了解的应该是我对tomcat的理解程度,以及是否看过tomcat源码)。是否用过Nginx。过滤器和拦截器的区别。
项目中有用到缓存吗,redis有提供了哪些存储数据结构,redis持久化。
说说java内存模型,新生代老年代算法,你说的新生代老年代属于堆还是栈,还知道哪些gc算法,创建大对象也是在新生代分配吗,(答:直接晋升进入老年代,问:具体多大对象,答:超过eden区大小,问:你是否确定,顿时虚了,后来回去查阅过,我回答的不对,jvm这里的看点很多,涉及到优化)。新生代的算法,说说minor gc,minor gc触发条件。老年代用了什么算法,说说标记整理算法,full gc是否真正回收了废弃对象。有哪些gc策略。你觉得你的项目中如果需要jvm调优你会注重哪个分带的调优,或者说更注重哪种gc调优,为什么,具体怎么做(懵逼,随便吹了下。问:你确定吗? 顿时又虚了)。
线上系统每天会收到20万级的数据,一个月会有百万条,并且还会递增。你如何设计数据库(答:分库分表,建立索引,问:分库分表对的,还有哪些点,分库分表按什么规则分)。如果查询字段不是分库分表的规则字段,怎么办(他说没事,想到什么说什么,也许你的思路会比我们的更好,你说说看)。沉默许久,不会,没接触过。(后来查了该问题:分库分表多维度查询)问:oracle分页的sql关键字是什么 答:limit 问:不对吧,那是mysql的 答:啊?好吧 问:也许是limit,我也记不清了,可能你说的是对的,回去我得看看。(面试官还算和蔼,其实是rownum)
面试难度- 难
苏宁结束,总结:苏宁大部分部门都非常缺程序员,招人要求相比于其它大点公司要低一些,都会问的同样的问题:能否接受苏宁的加班(部门加班情况不一,按我面试部门了解(加班从多到少:金服->物流/购物车->大数据部门),总体加班很多) ,苏宁的软件电商工作在外的名声总体不太好,加班严重,福利一般,晋升难,听说不是太注重员工培养。
5.烽火科技
写笔试题,笔试题一看就是用心出的(基础题偏多,也有问答题:线上系统出现故障,怎么排查。以及一些编程题:用jdk自带包实现抓取指定网页元素/内容(不会,后来查了,代码如下:
static void doGet() {try { String urlStr ="https://bbs.csdn.net"; URL url =new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestMethod("GET"); connection.setUseCaches(false); connection.setInstanceFollowRedirects(false); connection.connect(); BufferedReader reader =new BufferedReader(new InputStreamReader(connection.getInputStream())); String ss,total=""; while ((ss = reader.readLine()) !=null) { total += ss; total+="\n"; } System.out.println("total=" + total); reader.close(); connection.disconnect(); }catch (Exception e) { e.printStackTrace(); }}
),两个线程间隔输出字符,文件夹中查询指定类型文件)。
面试开始:1面。3个技术人员依次提问,jdbc连接步骤,statement和prepareStatement区别,项目中数据库事务控制你们是怎么做的。TreeMap,TreeSet,HashSet实现原理(之前只看了hashmap(别人都问hashmap,偏偏他就不问,这公司有套路的)其它回答的不好。这次面试经验很重要-所有集合实现都得认真看一遍),dom4j怎么取节点。为什么重写equals方法最好也得重写hashcode。treeMap中元素怎么排序,如果没实现comparator接口会怎么样。序列化作用。
中途hr跟我聊了聊公司福利,公司制度。
2面,也是3个人,项目经理(从言谈中看得出来技术沉淀很不错)+HR+不知道什么人(女,基本没说话)。都是项目经理问。自我介绍,项目介绍,项目细节(问的很细致)。项目中有用到多线程,线程池吗,怎么用的。说说你对hash的理解。hashSet是怎么去重的。你知道哪些map,set,说说他们实现原理。红黑树,二叉树。sql优化。linux。socket长连接短连接,连接出现异常你是怎么处理的。定时器。如果cpu有8个核心,那么程序启动多少个线程相对合适(懵逼)。最后还是通过了。
难度-稍难(其实还好,是我准备不充分)
薪资福利 - 不满意
6.擎天科技
最扯淡的一次面试。浪费我时间
面试建议-别去
7.亚信科技(亚信安全)
写面试题(难度一般,sql,springmvc,编程)。Integer缓存-128-127对象相不相等问题,其它都是上面提到的问题,不细说了(感觉面试官水平有限),问题基本都完整的回答出来了。跟面试官也谈了很久,问了他们现在具体做什么,用了什么技术,这家公司所用技术挺老(估计还没我原公司用到的技术多),貌似也是在做工具,非线上系统。还夸赞了我在原公司的做的项目(所有面试中唯一夸赞的)。
因为这次面试很成功,而且此公司环境和技术方面没有吸引我的地方,而且面试官还说他们可能就12-13薪 。综上最终我提了个很高的薪资要求,xx最低。
面试难度-简单
薪资福利- 一般(没达到我提的要求)
8.中地控股(付融宝),云问科技。这两家问题合并放一起(因为问的很多问题对于我来说算是超纲了,更多的偏向了线上系统大流量情况下的处理方案)。
treeMap元素排序。项目中是否做过jvm优化,sql优化。gc算法。是否用过webservice。mybatis分页,redis有关问题。BIO,NIO,AIO区别。高并发情况下怎么降低服务器压力(暂不从增加服务器和硬件提升层面考虑),方案解决问题:
1.假如servlet处理一个请求需要0.4秒,那么处理100请求大概需要多久,为什么。同时处理1000个请求导致服务器压力过大崩溃怎么解决
2.线上系统造成服务器cpu占用率过高问题(网上有解决方案)
3.秒杀系统少卖超卖问题怎么处理(网上有解决方案)
4.有个业务场景,通过第三方工具收集到大概百万条手机号,存储到文本中,文本中每行一个号码。我们的数据库中会存每个号码对应的会员等级信息(也有可能这个号码在数据库中不存在,那么他就是新用户)。按会员等级给号码发送不同内容的信息,新号码发送邀请信息。设计一个方案,怎么做效率最高(数据库数据量很大)。
难度-很难
9.焦点科技
两位面试官。项目介绍,细节提问。
项目中用到缓存了吗,答:曾经打算用用ehcache,后来发现种种原因(细说)并不需要用到
eclipse插件开发,它的初始化方法是什么(答:2年前做的了,实在是忘了...)
以下问题问的很细,我用红色标注面试官的提问。
ArrayList和LinkedList区别,ArrayList有初始容量吗,你看的是jdk几版本 ,容量不够怎么办 ,扩容为多大 ,如果Arraylist当前容量是10,且有9个数据,那么是添加第10个数据时扩容还是第11个,扩容怎么实现的,为什么采用复制数组的方式而不是往后直接添加数据 。(回答的不好,我回答的是jdk1.8初始化容量10,扩容回答的是2倍,都错了...ArrayList没细看,以为很简单,大概看看就行了,然后看完就忘了,实际上可看的点还是很多的。回去之后研究了下,JDK6-8ArrayList实现都有变化:体现在初始容量不同,1.7之前初始化容量为10,1.7及之后只会初始化空{},添加数据时才会开始给定初始化容量,如果初始化时自定义容量,那么情况又不一样,扩容规则
int newCapacity = oldCapacity + (oldCapacity >>1);
以及其它一些细节,这里就不细说了)然后我说ArrayList看的不太仔细,面试官问:你比较熟悉哪个集合,答:hashmap。
说说hashmap数据结构(数组+链表,链表长度超过8此链表转为红黑树(其实不准确,后来又看了1.8源码
final void treeifyBin(Node[] tab, int hash) {int n, index; Node e; if (tab ==null || (n = tab.length) <MIN_TREEIFY_CAPACITY) resize(); else if ((e = tab[index = (n -1) & hash]) !=null) { TreeNode hd =null, tl =null; do { TreeNode p = replacementTreeNode(e, null); if (tl ==null) hd = p; else { p.prev = tl; tl.next = p; } tl = p; }while ((e = e.next) !=null); if ((tab[index] = hd) !=null) hd.treeify(tab); }
数组长度少于MIN_TREEIFY_CAPACITY 是不优先转红黑树的,而是优先进行扩容))。
说说红黑树,它是基于什么数据结构实现的(红黑树了解不深,只是大致说了下思想-旋转、平衡、大小比较。(我感觉很难,有空得静下心来好好研究))。红黑树可能会再转为链表吗(答:长度低于8会转回链表 问:你确定是8而不是6 答:好像是6... (hashmap的看点真的很多,回去看了源码真的是6,而且扩容时红黑树变化很复杂,暂时看不懂))。说下hashmap put的过程(答:key的hashcode高16位与低16位异或运算得到新的hash,为了让数据(特别是在当前容量不大的情况下)散列更均匀,然后把异或计算出的新hash与此时的hashmap容量-1做&运算,得到插入下标。问:为什么要做&运算,还有什么方式。答:二进制运算速度快,还可以取模。之后如果下标位数组无数据则直接插入,如果有数据则链表往下逐个进行hash比较,如果产生hash碰撞再进行==或者equals比较key是否一样,一样则覆盖原数据,否则添加到链表后面。问:发生hash冲突怎么办 答:刚刚说了(重复)问:你确定是添加到链表后面吗 答:确定(我怀疑他jdk8的hashmap没看全(jdk7是新元素插入至链表头部的)还问了产生hash冲突后为什么还会比较原来key的hashcode,表示没听懂,看了源码也没发现有再次比较的过程,而且之后也重复问rehash后的元素具体去向问题(1.7和1.8元素rehash后元素去向是不同的),还有扩容问题,感觉他对jdk8的hashmap和1.7的有点混淆(还好我没怎么看jdk7,不过如果jdk7也看明白了,再说明与1.8的区别之后估计会大大加分吧,有点遗憾))。继续,当hashmap中数据量超过当前容量*扩容因子(默认0.75)则扩容为原来的2倍,问:还有什么要求 答:好像没了 问:当前插入的位置上没有元素就不扩容吧 答:哦哦。(其实不然,他说的是jdk7的情况,jdk8没有这个要求。当时要是知道7和8的区别,指出这点,那就是亮点了,再次遗憾))。为什么是2次幂扩容。(答:我觉得有3点因素。2进制运算快;hash与当前容量-1做&运算很快且很巧妙地获得元素下标;扩容后能巧妙地重新分配元素位置)说下扩容的rehash,扩容后的部分节点数据会重新定位,具体规则是hash&原容量,得到无非两个结果:0和1,如果是0则该元素所在下标位置不动,如果是1则将该元素放置原位置扩容后的对应位置(假如原先容量为16,元素位置在数组下标14的位置,则扩容后容量为32,该元素移动到数组下标30的位置(即原索引+原容量位置)。当时没这点解释的不够准确,有瑕疵)。为什么看hashmap源码,你觉得看了后对你有什么好处(答:比较喜欢探究(其实是近期面试才认真看的...)。知道了计算机位运算速度会比其它数学运算快;学习了它的思想对我思考问题方式有提升(能吹多少尽量吹多少);扩容是一个费性能的事,如果知道集合中大致会存多少元素最好给它一个初始容量),如果你知道里面会存100个左右数据,你会给它多大初始容量 (答:128) 它是线程安全的吗(答:不是,jdk1.8多线程情况下可能会造成数据丢失,1.8之前更可能造成死循环),线程安全的map有什么(答:hashtable,concurrentHashMap,前者已经被后者替代了,效率更高),说说concurrentHashMap,默认容量多少(答:16。只是了解,太复杂了,没细看,只知道jdk1.8之前采用分段锁方式处理,1.8之后采用cas乐观锁的方式来操作)。其它集合类了解吗(hashSet,treeSet,treeMap,都解释的相对明白,篇幅过长,不细说了),它们是否允许插入空值(treeSet,treeMap不可以)使用treeMap有什么需要注意的 (其中的元素要实现comparator接口)
有关synchronize的问题(忘了怎么问的了,只记得回答的挺多(作用,原理及jdk6之后的优化(锁升级:偏向锁->轻量级锁->重量级锁)))。Lock接口有哪些实现类,说说读写锁。
java内存模型,新生代老年代算法,简述新生代老年代gc过程,算法(复制回收(这里没说太明白,有点模糊),标记清除,标记整理(也说的不漂亮))。为什么新生代和老年代采用gc算法不同。jvm调优。
线程池有哪些参数,各代表什么意思。线程池中提供哪些队列种类。假如线程池核心池5,总池大小10,有界队列长度10,现在有13个线程要用线程池运行,说下核心池和队列中的线程情况。jdk中提供了哪几种线程池的实现。项目中用到线程池吗。
JDK中有哪些设计模式的体现,io中用了什么设计模式,说说观察者模式,项目中用了哪些设计模式。jdk8有哪些新增功能(答:那个箭头的那个叫什么来着 面试官:(笑)lambda表达式 答:对,可以让一些操作更直白简单,也有效率上的提高 问:说说它的闭包体现在哪 答:(随便说说,也不知道对不对) 还有哪些其它功能 答:还可以参数传入方法 问:它有什么好处 (随便说了点,也不知道对不对))。
redis有哪些数据结构。spring bean的生命周期,spring的BeanFactory和FactoryBean有什么区别。
之后问工作中,代码上的一些注意细节,总共面试时间将近2小时,最长时间一次面试。给我的感觉面试氛围很好,有位面试官全程都是笑着的,另一位稍微严肃,都挺好。
面试难度- 稍难
薪资福利-薪资稍低,福利很好
-------------------------------------------
总结:大型互联网通讯公司相对于外包、小型公司更注重面试者对基础的掌握程度。
作者:Java高级架构
链接:https://www.jianshu.com/p/abaa7744cd67