赞
踩
准备了接近两个月的面试笔试,现在终于是可以休息下了。真真是应了那句老话“台上一分钟, 台下十年功。”。
人嘛,越努力,才会越幸运。机会总是留给有准备的人的。
下面分享一下我的Java实习生准备所看过的材料,(虽然至今还有些依然看不懂地方。) 希望对这方面的同学有点帮助。
先针对自己的情况写段自我介绍,真实一些就好了,这方面我倒是没有什么其他的建议。我就写了我自己的真实的情况,比如喜欢写博客,喜欢学习新技术,做过哪些小工具什么的。
但是有一点,那就是别作假,否则的话很容易被发现的,而且后果一般会很严重。
这段时间自己也总结了关于数据结构和算法相关的一些例子。也看了几本书,总的来说《剑指Offer》挺好,就我不多的面试经验来看,大部分面试官都是面试的上面的题,所以有时间的同学可以好好参考参考。
原书是使用C++实现的,我又用Python实现了其中大部分的内容,有兴趣的话可以参考我的GitHub: https://github.com/guoruibiao/sword-to-offer
由于本人经验,技术能力有限,有不恰当,不正确的地方还望批评指正。觉得还可以的也可以给我点个star,(^__^) 嘻嘻……
阿里的那个《技术之瞳》我也看了,里面内容比较多,但是也比较乱。知识面很广,但是我感觉深度上还是不太够。不是很适合我。
其他的类似于Java面试宝典啊这些的,复习的时候认真看一遍,就可以扔一边了。但是前提是认真看了,因为基础没打牢的话,更别提生层建筑了。于乎微处见真章。
concurrencyHashMap 底层原理,好在哪?
分段锁原理,对有竞争的区块实现同步,区块内维护hashEntry
- 一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
- Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
- Comparable 接口以提供自然排序顺序。
-
- 对于那些没有自然顺序的类、或者当您想要一个不同于自然顺序的顺序时,您可以实现
- Comparator 接口来定义您自己的排序函数。可以将Comparator传递给Collections.sort或Arrays.sort。
-
- Comparator接口
- 当一个类并未实现Comparable,或者不喜欢缺省的Comaparable行为。可以实现Comparator接口
- 直接实现Comparator的compare接口完成自定义比较类。
- 例:Arrays.sort(results, new Comparator<RepDataQueryResultVO/>() 数组排序 RepDataQueryExecutor
- 例:Collections.sort(lst,new Comparator<TaskPrintSchemeVO/>()
Java 的instanceof关键字底层实现:
维护了主要超类型(继承深度)小于7的主数组, 和次要超类型(判断的时候需要super链遍历查找);在字节码使用特殊指令对常量池中的相关符号引用进行判断,来决定true和false。
Java内存模型
年轻代,: 伊甸区,两个存活区(总有一个为空,轮询转移)。 (逐级晋升机制)
年老代: 在年轻代中经历了N次垃圾回收后依然存活的生命期较长的对象。
GC 触发机制:
新生代GC: 在新对象生成且在伊甸区申请空间失败的时候会触发一次对伊甸区的GC,把
存活的对象放置到存活区。通常来说伊甸区的GC会比较频繁。
Full GC: 对整个堆进行整理,速度慢,次数少。触发的时机: 年轻代被写满, 持久代被写满,系统GC被调用。
GC 回收标准:
引用计数算法: 可能导致循环引用导致GC效果不好,代替方式有引用标记清理方式
根搜索算法: 那些对象可以作为GC Root? 答案是虚拟机栈中引用的对象,方法区中的类静态属性引用的对象
方法区中的常量引用的对象, 本地方法栈中JNI的引用对象
引用状态:强(被引用着)软(还有些有那个但不是必须, 二次回收)弱(非必须对象,下次就回收)虚(告知被引用的对象,要被回收啦,作用不大): 程度依次减小,
方法区回收: JVM没有强调方法区的回收,但是也是非常有用的,对于效率要求较高而言。对于废弃常量比较好处理
直接判断有没有相关的引用即可。对于无效类对象而言有下面几种方式。该类的实例都被回收;该类的classLoader被回收;该类对应的字节码对象Class没有被任何地方引用,无法在任何地方通过反射来访问该类的方法。
GC 算法:
标记清除算法: 对要进行回收的对象进行标记,在下次GC的时候予以回收。但是碎片化严重,对下次的大对象的分配效率不高。
复制算法: 为了解决效率问题而出现,将内存分为可用的两块,对于存活的对象
进行复制转移,碎片化现象减轻。但是代价高啊,可用的只有一半,对于新生代内存区采用比较频繁,
标记整理算法: 对于老年代对象存活率高,这样复制算法不适用,而采用标记整理算法。将老年代中存活的对象移动到一侧,对另外的区域进行GC。
综上所述,对不同的代区采用不同的GC算法,会使得GC的效率得到进一步的提升。
- (<3/>init-method,<1/>intilizingbean接口方法<2/>afterPropertiesSet的先后顺序)等。
-
- //详情参考
- Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:
- 1. BeanNameAware's setBeanName
- 2. BeanClassLoaderAware's setBeanClassLoader
- 3. BeanFactoryAware's setBeanFactory
- 4. ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
- 5. ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
- 6. MessageSourceAware's setMessageSource (only applicable when running in an application context)
- 7. ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
- 8. ServletContextAware's setServletContext (only applicable when running in a web application context)
-
- 9. postProcessBeforeInitialization methods of BeanPostProcessors
- 10. InitializingBean's afterPropertiesSet
- 11. a custom init-method definition
- 12. postProcessAfterInitialization methods of BeanPostProcessors
- On shutdown of a bean factory, the following lifecycle methods apply:
- 1. DisposableBean's destroy
- 2. a custom destroy-method definition
大致可以这么来理解:
bean容器创建–通过反射实现bean开始实例化–通过注入信息设置属性–可以被调用啦–容器被销毁/bean中设置的destory-method方法被调用实现bean的销毁。
我自己的理解如下:
Strtus:
首先是客户端发起一个指向servlet容器的请求,被容器上一系列的过滤器获得主要是ActionContextCleanUp
然后被FilterDispatcher拦截到,经过查询ActionMapper之后决定调用哪个action
FilterDispatcher将请求转发给ActionProxy,ActionMapper内部经过查询ConfigurationManager找到要调用的Action类
ActionProxy代理产生一个ActionInvocation实例,回调action的execute方法,通过返回的串调用相关的jsp页面
最后反向经过一系列的拦截器,释放不需要的如ThreadLocal里面的数据,对象信息。
SpringMVC:
前端管家DispatcherServlet接收来自客户端的请求,然后通过handlerMapping查找到相应的处理器。转交给handler处理相应的业务逻辑。处理结束后返回一个ModelAndView,返回给客户端以响应。
Servlet:
web服务器接收到客户端请求之后,将请求指向一个与url对应的servlet的class,如果已实例化则调用init,service,destory。如果未创建,则通过查询ServletConfig获取到相关的字节码信息,进行实例化,接着进行上面的操作。
spring AOP解决了什么问题?怎么实现的?aop与cglib,与asm的关系。
AOP实现了面向切面编程。连接点(可以被增强的方法),切入点(被增强的方法),增强(业务中增强的具体逻辑),切面(将增强应用到切入点的过程)
AOP中借助于动态代理或者cglib实现。动态代理需要接口,cglib是子类增强机制,不能增强final类。
HTTP协议, http1.0和http2.0区别:
http2的二进制压缩流,完全的多路传输。使用报头压缩降低了开销;实现了推送,降低了客户端多次请求。
报文结构—请求部分:
请求行:请求方法+空格+URL+空格+协议版本+回车+换行符
请求头: 什么referer,userAgent啦等等
空行: 回车符+换行符
请求数据: 来自客户端的请求的数据。
推送模式:
但是总的来说有两大方向: Pull 和 Push; Push对于客户端而言流量消耗更少;Pull对服务器端而言压力稍小。
WebService浅析:
对二者的思考,就是现在的rest也只是soap模式在rest下的借尸还魂,并没有彻底的改变,而rest缺少一套标准,实现的方式也比较乱,各大厂商也不一致。需要时间的沉淀。
页面置换算法: FIFO, LRU, LRU的二次标记法来给次机会。
Memcache和Redis:
总结:
redis的最佳使用方式时全部数据in-memory.
redis更多场景是作为memcache的替代品来使用。
当需要除了key-value之外的数据结构支持的时候,redis更适合。
当存储的数据不鞥呗剔除的时候,使用redis更合适。
数据库事务以及隔离级别:
四大特性: ACID(原子性[要么都成功,要么全失败], 一致性[事务从一个状态变成另一个一致性的状态], 隔离性[一个事务中的行为不会影响到另一个事务], 持久性[改变了数据就不能再撤销了])。
不考虑事务的时候有可能在读取数据库时发生如下问题:
脏读: 一个事务中读取了另一个事务中未提交的数据。
不可重复读: 相同的sql语句,两次读取的结果不一致。
幻读: 一个事务读取到了另一个事务提交后的结果,或者改变了本次事务的数据的结果。也称为虚读。
隔离级别:
事务的隔离级别越高,执行的效率就会越低!在JDBC代码中可以对connection对象设置相应的隔离级别。
数据库数据结构:
2.数据库事务的几种粒度;表锁(不会产生死锁,但是并发度低), 页锁(有可能产生死锁,但是用的不多), 行锁(并发度高,但是有可能产生死锁)。
DTD(Document Type Define,文档定义类型), schema( XSD, XML Schema Document)之间的区别和联系
du path -type f -size +NumberG | sort -n -r | head -n 10
找出给定目录下以G为单位的最大的10个文件,并排序输出。
全局唯一ID问题:
时间戳,加去中心化,加逻辑分片,机器号等
Linux使用及问题排查:
常见的cpu load过高,us过高,一般是什么问题。引申出是否用过top,jstat,jstack等。
可以先ps -aux (或者top, htop)找到占比高的进程号,然后使用ps -Lp 122427 cu找到对应的java进程的每个线程的CPU使用率,追踪线程内部运行的状况。
常见的内存问题一般有哪些。 引申出是否用过free,top, jmap等。
林林总总的一万多字了,但是这还远远不能覆盖全部。而且距离一个合格的Java程序员仅仅知道这些还远远不够,我们能做的就是尽可能的让自己接近那个标准吧。
上面这些链接也好,总结也好,大家还是需要有自己的理解。
“尽信书,则不如无书!”,其实也是这么个道理,带着思考来阅读,效率,效果都可能会更好。
最后,希望大家都能找到自己心仪的offer。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。