java 面试题,mybatis 原理和实现机制
如 ActionForm 实例不存在,则创建一个 ActionForm 对象,把客户提交的表单数据保存到 ActionForm 对象中。
根据配置信息决定是否需要表单验证。如果需要验证,就调用 ActionForm 的 Validate()方法。如果 Valiedate()方法返回 null 或返回一个不包含 ActionMessage 的 ActionErrors 对象,则表示表单验证成功。
ActionServlet 更加 ActionMapping 实例包含的映射信息决定请请求转发给哪个 Action。如果相应的 Action 实例不存在,则先创建这个实例,然后调用 Action 的 execute()方法。
Action 的 execute()方法返回一个 ActionForward 对象,ActionServlet 再把客户请求转发给 ActionForward 对象指向的 JSP 组建。
ActionForward 对象指向的 jsp 组件生成的动态网页,返回给客户。
十九、Tomcat 的 session 处理,如果让你实现一个 tomcatserver,如何实现 session 机制
当一个 session 开始时,Servlet 容器会创建一个 HttpSession 对象,在某些情况下把这些 HttpSession 对象从内存中转移到文件系统中或数据库中。需要访问的时候将它们载入到内存中。这样的好处就是节省内存,当 web 服务器产生故障时,还可以从文件系统或数据库中恢复 Session 的数据。管理 session 有两个类:1)StandardManager,这是一个默认的类,当 tomcat 启动或重载时将会 session 对象保存到指定文件中。2)PersistentManager,管理方式更加灵活,具有容错能力,可以及时把 Session 备份到 Session Store 中,可以控制内存中 Session 的数量。
二十、关于 Cache(Ehcache,Memcached)
Memcache:分布式内存对象缓存系统,占用其他机子的内存。很多互联网,负载均衡三台(以三台为例)web 服务器可以共享一台 Memcache 的资源。传递的信息以键值对的形式存储。传递的数据要实现序列化。
Oscache:页面级缓存(网上强调最多的东西),占用本机的内存资源。可 以选择缓存到硬盘,如存取到硬盘重启服务也可重新获得上次持久化的资源,而如果缓存到内存就不行。一般没必要缓存到硬盘,因为 I/O 操作也是比较耗资源,和从数据库取往往优势很小。Oscache 存取数据的作用域分为 application 和 session 两种。
EhCache:Hibernate 缓存,DAO 缓存,安全性凭证缓存(Acegi),Web 缓存,应用持久化和分布式缓存。EhCache 在默认情况下,即在用户未提供自身配置文件 ehcache.xml 或 ehcach
e-failsafe.xml 时,EhCache 会依据其自身 Jar 存档包含的 ehcache-failsafe.xml 文件所定制的策略来管理缓存。如果用户在 classpath 下提供了 ehcache.xml 或 ehcache-failsafe.xml 文件,那么 EhCache 将会应用这个文件。如果两个文件同时提供,那么 EhCache 会使用 ehcache.xml 文件的配置。
二一、sql 的优化相关问题
1. 对查询优化,避免全表扫描
尽量避免 where 子句中对段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。
尽量避免 where 子句中出现!=或<>,否则将导致引擎放弃使用索引而进行全表扫描。
尽量避免 where 子句中出现 or 来连接条件。
慎用 in 和 not in,否则导致全表扫描
where 中不要用函数操作。
Update 语句,如果只更改 1、2 个字段,不要 Update 全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
对于多张大数据量(这里几百条就算大了)的表 JOIN,要先分页再 JOIN,否则逻辑读会很高,性能很差。
尽可能的使用 varchar/nvarchar 代替 char/nchar,节省空间,提高查询效率
select count(*) from table;这样不带任何条件的 count 会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
二二、oracle 中 rownum 与 rowid 的理解,一千条记录我查 200 到 300 的记录怎么查?
二三、如何分析 ORACLE 的执行计划?
二四、 DB 中索引原理,种类,使用索引的好处和问题是什么?
原理:因为检索磁盘比对数据,需要大量的时间和 IO,所以就需要构造某列的数据的 btree、hash 值、位图索引。一般的索引能快速的查找比对,而索引的值记录了磁盘的位置,直接读取数据库字段对应位置的内容。
索引好处:加快数据检索速度、加速表与表之间的连接特别是实现数据的参考完整性方面有特别的意义、减少查询中分组和排序的时间,使用优化隐藏器,提高系统性能。
缺点:创建和维护索引需要时间,索引需要占用物理空间,当对表中的数据惊醒增删改时所有也需要动态维护。
二五、JVM 垃圾回收实现原理。垃圾回收的线程优先级。
JVM 的堆空间中主要分为年轻代、年老代和永久代。年轻代和年老代是存储动态产生的对象。永久代主要是存储 java 类信息,包括解析得到的方法属性、字段等等。永久代基本不参与垃圾回收。年轻代分为一个 eden 区和两个相同的 survior 区。刚开始创建的对象都放置在 eden 区。这样主要是为了将生命周期短的对象尽量留在年轻代中。当 eden 区申请不到空间时,进行 minorGC,把存活的对象拷贝到 survior。年老代主要存放生命周期比较长的对象,如缓存对象。具体 JVM 垃圾回收过程如下:
1、对象在 Eden 区完成内存分配。2、当 Eden 区满了,在创建对象就会申请不到空间,则触发 minorGC,进行 young(eden 区和 1survivor 区的垃圾回收)。3、在 minorGC 时,Eden 不能被回收的对象呗放入到空的 survior(即 Eden 肯定被清空),另一个 survivor 里不能被 GC 回收的地想也会被放入到这个 survivor,始终保证一个 survivor 是空的。4、当完成第三步的时候、如果发现 survivor 满了,则这些对象呗 copy 到 old 区,或者 survivor 并没有满,但有些对象已经足够 old 了,也被放入到 old 区。当 old 区北放满之后,进行 fullGC。
二六、jvm 最大内存设置。设置的原理。结合垃圾回收讲讲。
JVM 内存可以分为堆内存和非堆内存,堆内存给开发人员用的,非堆内存给 JVM 本身用的,用来存放类型信息,即使 GC 时也不会释放空间。
堆内存设置:
-Xms 初始堆内存,默认物理内存 1/64,也是最小分配堆内存,当空余堆内存小于 40%时,会增加到-Xms 的最大限制。
-Xmx 最大堆内存分配,默认物理内存 1/4,当空余堆内存大于 70%时,会减小打-Xms 的最小限制。
非堆内存设置:
-XX:PermSize 非堆内存的初始值,默认物理内存的 1/64,也是最小非堆内存。
-XX:MaxPermSize 非堆内存最大值,默认物理内存的 1/4。
查看堆大小命令为 Runtime.getRuntime().maxMemory()。
二七、jvm 怎样通过参数调整内存大小
本地环境变量中 JVM 参数设置:
new 一个 JAVA_OPTS:
variable name: JAVA_OPTS
variable value: -Xms256M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M
eclipse 中参数设置:在缺省 VM 参数中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
二八、进程与线程的区别
线程是进程的一个单元,也是进程内的可调度实体。区别就是:1、进程内的线程共享地址空间,进程则自己独立的地址空间。2、进程是资源分配和拥有的单位,同一个进程内的线程共享进程资源。3、线程是处理器调度的基本单位。4、两者均可并发执行。
二九、怎样避免死锁
使用事务时,尽量缩短事务 idea 逻辑处理过程,及早提交或回滚事务
设置死锁的超时参数为合理范围,如 3-10 分钟,若超过时间,自动放弃本次操作,避免进程悬挂。
优化程序,检查并避免死锁现象出现。
对所有的脚本和 sp 都要仔细测试。
所有的 sp 都要有错误处理。
一般不要修改 sql 事务的默认级别。不推荐强行加锁。
三十、垃圾回收算法使用的产品、场景
标记-清除算法:标记阶段,确定所有要回收的对象,并标记,清除阶段则将需要回收的对象清除。
复制算法:把内存分为大小相等的两块,每次使用其中的一块,当垃圾回收时,把存活的对象复制到另一块上,然后把这块内存整个清理掉。两块内存比是 8:1
标记整理算法:把存活的对象往内存的一端移动,然后直接回收边界以外的内存。标记-整理算法提高了内存的利用率,并且它适合在收集对象存活时间较长的老年代。
分代回收算法:根据对象的存活时间把内存分为新生代和老年代,根据各代对象的存活特点,每代采用不同的 GC 算法。新生代用标记-复制算法,老年代用标记-整理算法。
三一、实际项目中 JVM 调优
1、JVM 启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量。
2、改进程序逻辑算法,提高性能
3、自定义封装线程池,解决用户响应时间长的问题。比如设置线程最小数量、最大数量
4、连接池
三二、jdk 并发包的集合介绍
Map 并发包,其实现为 ConcurrentHashMap,它实现了 ConcurrentMap 接口。put 方法为根据计算出的 hash 值去获取 segment 对象。找到 segment 对象后调用该对象的 put 方法完成操作。segment 中的 put 方法则是先加锁,之后判断数组大小,然后觉得是否扩充。然后得到 key 索要放置的位置。
List 并发包,客在高并发环境下使用 CopyOnWriteArrayList 代替 ArrayList。添加元素是利用数组的 copy 功能和加锁机制。并发情况下,CopyOnWriteArrayList 比 ArrayList 略快了些。
set 并发,CopyOnWriteSet 和 CopyOnWriteArrayList 底层实现差不多就是在添加元素时会进行唯一性判断,如果对象数组已经含有重复的元素,不进行增加处理。
queue 并发,并发类是 ArrayBlockingQueue,底层为数组,并对关键的方法入队、出队操作加入了锁队机制。
Atomic 系列类,比如 AtomicInteger 类,通过使用计数器操作时,一般为了避免线程安全问题,在方法上加锁操作。有了并发包下的原子系列类,我们就可以直接使用。
三三、线程之间的通信
主要包括互斥锁、条件变量、读写锁和线程信号灯。
互斥锁:以排他方式防止数据被并发修改。互斥锁两个状态 0 和 1。具体为申请锁、占用锁以防止数据被修改,此时默认阻塞等等,最后释放锁。
条件变量通信机制:原理,条件变量出现时,可以弥补互斥锁的缺陷,有些问题仅仅依靠互斥锁无法解决。但条件变量不能单独使用,必须配合互斥锁一起实现对资源的互斥访问。
读写锁:在对数据读写时,往往读占主要部分。基本原则是如果其他线程读数据,则允许其他线程执行读操作,但不允许写操作。如果有其他线程申请写操作,则其他线程不能申请读操作和写操作。
线程信号:线程拥有与信号相关的私有数据——线程信号掩码。线程可以向别的线程发送信号,每个线程可以设置自己的阻塞集合。所有线程中,同一信号子任何线程里的对该信号的处理一定相同。
三四、介绍 threadlocal
可以叫做线程本地变量或线程本地存储。ThreadLocal 为变量在每个线程中都创建了一个副本,每个线程都可以访问自己内部的副本变量。但可能这样做会导致内存占用较大。
ThreadLocal 类的几个方法:get() 用来获取 ThreadLocal 在当前线程中保存的变量副本,set()用来设置当前线程中变量的副本,remove()用来一冲当前线程中的变量副本,initialValue()一般用来在使用时进行重写,是一个延迟加载方法。最常见的 ThreadLocal 使用场景是用来解决数据库连接、Session 管理等。
三五、jdbc 的操作过程
加载数据库驱动包、连接数据库、使用 sql 语句操作数据库、关闭数据库连接
三六、HTTP1.1 的新特性
支持持续连接,通过建立一个 TCP 后,发送请求并得到响应,然后发送更多的请求并得到更多的响应。通过把简历和释放 TCP 连接的开销分摊到多个请求上,则对每个请求而言,优于 TCP 而造成的相对开销被大大降低。而且还可以发送流水线请求。
三七、异常处理,包含了什么
参考:http://lavasoft.blog.51cto.com/62575/18920/
三八、堆排序与快速排序
View Code
View Code
堆排序是渐进最优的比较排序算法,达到了 O(nlgn)这一下界,而快排有一定的可能性会产生最坏划分,时间复杂度可能为 O(n^2)。堆排比较的几乎都不是相邻元素,对 cache 极不友好。数学复杂度并不一定代表实际运行的复杂度。
三九、Collection 有哪些类
Set, List, Map, SortedSet, SortedMap, HashSet, TreeSet, ArrayList, LinkedList, Vector, Collections, Arrays, AbstractCollection
四十、Hashcode 总为 1 会怎样,如何解决 hash 冲突
当所有对象 Hashcode 返回都为 1 时,所有对象都出现 hash 冲突,其性能会下降
解决 hash 冲突:
线性再散列法、插入元素时,如果发生冲突,算法会简单的遍历 hash 表,直到找到表中的下一个空槽,并将该元素放入该槽中。查找元素时,首先散列值所指向的槽,如果没有找到匹配,则继续遍历 hash 表,直到:(1)找到相应的元素;(2)找到一个空槽(指示查找的元素不存在);(3)整个 hash 表遍历完毕(指示该元素不存在并且 hash 表是满的)。
评论