您的位置:首页 > 其它

这里有一份面经请查收(三)

2016-07-26 14:44 183 查看


这里有一份面经请查收(三)

2016/07/25 · 职场 · 面试

分享到:0

Java
分页原理与实践(下)

模式的秘密---适配器模式

Hibernate初探之一对多映射

走近大数据之Hive入门

本文作者: 伯乐在线 - 朱小厮 。未经作者许可,禁止转载!

欢迎加入伯乐在线 专栏作者

经过前面两次的面试,这里就马上转到第三家公司了的面试了,这里简称B,工作地点和上一篇所讲述的W公司在一个城市,是面完W之后第二天去的,说出名字的话大多小伙伴都听过或者用过其服务,具体是什么要靠你们的悟性了。


一面

B公司的一面也是电面,主要是根据简历上的聊了一下,问了几个问题。挑两个比较有通用性的问题聊一下。

1. 了解Spring框架多少?

博主说SpringMVC+Spring是比较常用的,看过一点Spring的源码,主要是关于Xml解析和Bean加载的,记得大致的步骤。面试官就让博主讲一下Bean的加载过程。其实这个是蛮长的一段,主要有一下一些步骤(博主个人理解,仅供参考):xml解析之后存入一个BeanDefinition之中,然后主要是对其进行操作;先在singletionObjects(是一个ConcurrentHashMap的对象)判断有没有Bean的实例,有就处理下返回,没有就继续;检测一下循坏依赖之类的;下面要进入主题了,如果是单例(Spring
Bean默认是单例)的话,就创建实例并存入singletonObjects中,如果不是则创建不保存(当然这里也有一个非常复杂的过程,这里就不论述了);实例创建完之后就开始属性注入(autowiredByType, autowiredByName);初始化Bean(激活Aware方法:BeanNameAware, BeanFactoryAware, ApplicationContextAware等;BeanPostProcessor接口;激活自定义init方法:init-method, InitializingBean接口;);这里就可以使用Bean了;使用完之后就是销毁了(destory-method,
DisposableBean接口)。有关Spring的一些知识点可以参考《Spring知识点提炼》。

之后又被问了个问题:大家都知道BeanFactory是什么,那么你了不了解FactoryBean呢?这个见过,但是真记不得干嘛用的,后来翻看了下资料:一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化Bean。在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案,Spring为此提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。

2.ArrayList的问题。

有关ArrayList无非就是一下一些基本认知:非线程安全,初始容量为10,按照1.5倍扩容,底层采用数组elementData实现,对于随机访问get和set效率比较高,对于add和remove效率比LinkedList要低。当要扩容时采用System.arrayCopy()这个native方法实现。

但是ArrayList有两个点需要注意的。

第一个是 ArrayList 有个 trimToSize() 方法用来缩小 elementData 数组的大小,这样可以节约内存。考虑这样一种情形,当某个应用需要,一个 ArrayList 扩容到比如 size=10000,之后经过一系列 remove 操作 size=15,在后面的很长一段时间内这个 ArrayList 的 size 一直保持在 < 100 以内,那么就造成了很大的空间浪费,这时候建议显式调用一下 trimToSize() 这个方法,以优化一下内存空间。或者在一个 ArrayList 中的容量已经固定,但是由于之前每次扩容都扩充
50%,所以有一定的空间浪费,可以调用 trimToSize() 消除这些空间上的浪费。

第二个是ArrayList中有个不合理之处,就是ArrayList是implements RandomAccess这个接口的。关于RandomAccess接口JDK中有明确定义:实现了RandomAccess接口的集合框架,采用迭代器遍历比较慢,不推荐。 原文是这么说的:

It is recognized that the distinction between random and sequential access is often fuzzy. For example, some List implementations provide asymptotically linear access times if they get huge, but constant access times in practice. Such a List implementation
should generally implement this interface. As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:

123456for (int i=0, n=list.size(); i < n; i++)         list.get(i); runs faster than this loop:     for (Iterator i=list.iterator(); i.hasNext(); )         i.next();
但是ArrayList的toString()方法是继承了AbstractCollection的,这个方法用的是迭代器的遍历方式。详细可以参《RandomAccess?!》。而且如果采用Java中的foreach语法糖进行遍历ArrayList的话,Javac在解语法糖时是解释成迭代器的遍历方式而没有解释成普通for()循环list.get(i)的方式,详细可以参考《Java语法糖之foreach》。3.流控怎么处理?直接丢弃;本机内存暂存一些请求,比如用Semaphore实现;消息队列。最后面试官提示了一个令牌算法。4.Linux的常用命令?这个在第一篇中也陈述过了:

1

2

3

4

5

6

7

8

cat
tac
head
tail
more
less
nl
vim
vi
gvim

date
cal
man
shutdown
poweroff
reboot
echo

uname
-r;
mount;
unmount;
exit

cd
ls
pwd
mkdir
cp
scp
rm
mv

touch
file
which
whereis
locate
find
tar
unzip

grep
df
top
free
kill
killall

ifconfig
ping
netstat
telnet
ftp

passwd
umask
chrown
chmod
chgrp
sudo
ps
who


二面

二面本来是两个面试官,一个面试官(是一面的面试官)在纸上画了个数就接个电话出去了,剩下的是另一个面试官。整个过程持续1个半小时左右,过程是边面边在纸上写。这种方式有点“虐”,不过还好问的比较全面,也不是特别的深。面试官人不错,面试过程也很和谐。题目还蛮多的,博主尽量回忆一下。

1.根据纸上画的树(多叉树,并不是二叉树)写出一个树的实现,用Java。然后写出树的遍历方式,递归和非递归方式都要写。然后是写出树的前序,中序,后序遍历的结果。

1

2

3

4

5

class
TreeNode{

    String
treeInfo;

    TreeNode
father;

    List
sons;

}

递归的遍历比较简单,非递归的方式是采用栈进行操作。至于前序,中序,后序遍历只要懂点数据结构和算法的人都能知道,在此不赘述了。

2. JVM调优。

主要是讲讲自己实际遇到的情况。比如调节一下参数,类似:-Xmx, -Xms等;又比如采用JConsole或者JVisualVm进行操作;又比如用jps, jmap, jstack等命令工具。

接着再讲讲遇到OOM的时候是怎么处理的。

3.刚刚讲述了OOM也就是内存吃不住的时候怎么处理,如果某个线程CPU占用率100%怎么查看。

这个博主直说出了用资源管理工具查看,或者linux的top命令查看一个进程的CPU占用率,至于某个线程的占用率怎么查看还真不知道。

后面面试官说可以这么使用,先jstack查出线程堆的信息,在用top H -p [pid]的方式查看某个线程占用率(pid 通过jps命令获取),中间进过16进制转换下就对应起来了。回家试了下,还真是。还有一种方法也可以,在linux下:ps -H -eo pid,ppid,tid,%cpu –sort=%cpu | grep [pid]也有同样的效果。

4.写一个单例

先写了一个内部类的,后来说了一个enum的,又说一个synchronized的,面试官接着问还有呢?我说:你指的是双检锁的那种方式吧,然后又写了一个双检锁的单例。后面被问了为什么双检锁中要进行两次null的判断?博主DCL的没有用过,这个问题也没有全答对。。详细可以参考《设计模式:单例模式(Singleton)》。

5.聊了聊多线程。CAS等

多线程一般聊了聊ThreadPoolExecutor相关的,或者ConcurrentHashMap, 或者BlockingQueue系列的。CAS就写了一个CAS的实现方式,Java中的CAS的底层实现只有三个:sun.misc.Unsafe.CompareAndSwapInt, CompareAndSwapLong, CompareAndSwapObject.

6.画出volatile的内存模型。

这个题目比较吓人,如果看过的人很容易就画出来了。volatile就两点:内存可见性;原子性。

7.画出TCP三次握手,四次挥手。(略)

8.动态代理。

写一个动态代理,博主写了一个JDK的实现,写完补了一句这个还有CGLib的实现方式,然后就被要求写一个CGLib的实现方式,博主只记得用Enhancer干嘛干嘛的,剩下的不记得了。嘴贱打脸。后来又被问了JDK和CGLib的区别,开始没答出来,后来提示了一下,JDK是通过接口实现的,CGLib是通过继承实现的,如果所要代理的对象没有接口实现那只能采用CGLib进行动态代理了。详细可以参考《设计模式:代理模式(Proxy)


后续

说实话,这家公司挺好的,也在稳步上升阶段。上班可以从10点开始,面试官人不错,感觉秒秒钟就能做好朋友的那种。只是博主这次出来转一转是有目的性的,需要找一家有点名气的互联网公司,有一个必须点是必须要有足够的流量接入。B公司的互联网产品主要面对商户,所以流量上并没有那么的大。薪资其实给的也不错,如果B公司与博主同城,博主肯定就选择了。只是要换个城市,这份offer的诱惑力就没有那么大了,最终还是没有选择。最后在这里感谢下背后运作的猎头Theresa, 虽然我也知道你不会看我博客,你真的比其他的猎人负责任多了,抱歉没能给你赚一单业绩~

更多链接请关注:
这里有一份面经请查收(一) 
这里有一份面经请查收(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: