2017年上半年Java高级工程师求职面试题总结

文章目录
  1. 1. HashMap的数据结构
  2. 2. ArrayList的数据结构
  3. 3. HashSet的数据结构
  4. 4. LinkedList的数据结构
  5. 5. Integer值的==判断
  6. 6. 创建一个线程池有几种方法以及参数
  7. 7. Spring的IOC(循环依赖)
  8. 8. Spring AOP
  9. 9. Spring一个方法是否可以配置多个切面
  10. 10. Java内存结构
  11. 11. Spring多数据源的事物控制
  12. 12. Spring事物嵌套
  13. 13. ThreadLocal结构
  14. 14. redis
  15. 15. redis有几种数据结构
  16. 16. redis常用方法
  17. 17. redis事物
  18. 18. 分布式锁如何实现
  19. 19. 多个方法同时操作一条数据怎么办
  20. 20. 二叉树遍历的几种方式
  21. 21. 二分查找法
  22. 22. 栈(先进后出)
  23. 23. 堆(先进先出)
  24. 24. http状态码
  25. 25. linux下查看日志文件常用命令
  26. 26. 适配器模式
  27. 27. Java中那些类使用了那些模式
  28. 28. 乐观锁
  29. 29. 悲观锁
  30. 30. 事物与锁
  31. 31. 线上mysql如何查看那条sql执行时间比较长
  32. 32. synchronized与Lock
  33. 33. 请描述一下GC(jvm垃圾回收器)
  34. 34. Java中的引用有几种?
  35. 35. Java中的threadlocal是怎么用的? threadlocal中的内部实现是怎么样的? 哪种引用?
  36. 36. Java中的”final”关键字在多线程的语义中,有什么含义
  37. 37. 说说nio的架构,为什么变快了,说说select和buffer都是怎么用的?
  38. 38. nio中, 如果不显式的调用 system.gc() 那会出现什么问题?
  39. 39. SimpleDateFormat如果是一个全局变量的话,有什么问题?
  40. 40. HashMap的操作中,直接使用keySet()遍历有什么问题
  41. 41. 线程池队列中几种策略
  42. 42. ConcurrentHashMap为什么会比HashTable快
  43. 43. 一个数组n 其中的值是1到n-1 找出其中第一个重复的
  44. 44. 两个整数交换不使用第三个变量
  45. 45. 手写代码实现LRU数据结构
  46. 46. 一个数组将奇数放左边偶数放右边
  47. 47. 一个字符串找出第一个相同的字符
  48. 48. 数据库sql优化
  49. 49. 数据库索引该如何建在正确的字段上
  50. 50. Spring有几种事物隔离
  51. 51. 请描述一下Spring MVC 从发起请求到后台的处理流程
  52. 52. 请描述一下JVM类加载

HashMap的数据结构

数组加单链表结构。不允许有相同的key允许null为key,null为key的时候值是保存下了数组下标为0中。可以有相同的value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class HashMap{
Entity[] entity;
public HashMap(){
entity = new Entity[10];
}
class Entity{
String key;
String value;
int hash;
Entity next;
}
public void put(Object key,Object value){
int i = key.hashCode % entity.length;
if(entity[i]==null){
entity[i] = new Entity(key,value,i,null);
}else{
Entity temp = entity[i];
entity[i] = = new Entity(key,value,i,temp);
}
}
public Object get(Object key){
int i = key.hashCode % entity.length;
Entity temp = Entity[i];
while(temp!=null){
if(temp.key.equlas(key)){
return temp.value;
}else{
temp = temp.next;
}
}
}
}

ArrayList的数据结构

数组结构,允许重复数据,取值快,插入慢

1
2
3
4
5
6
7
8
9
10
class ArrayList{
Object[] elementData;
int elementCount;
public ArrayList(){
elementData = new Object[10];
}
public void add(Object o){
elementData[elementCount++]=o;
}
}

HashSet的数据结构

不允许有相同的值,无序的,优势在于查找相同元素的时候时间复杂度为最低

1
2
3
4
5
6
7
class HashSet{
HashMap map ;
Object PRESENT = new Object();
public add(Object v){
map.put(v,PRESENT);
}
}

LinkedList的数据结构

双链表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class LinkedList{
Node first;
Node last;
public void push(Object o){
addFirst(o);
}
private void addFirst(Object o){
if(first==null){
first =new Node();
}else{

}
}
class Node {
Object v;
Node prev;
Node next;
public Node(Object o,Node prev,Node next){
v=o;
prev = prev;
next = next;
}
}
}

Integer值的==判断

1
2
3
4
5
6
Integer a=1;
Integer b=1;
a==b echo true
Integer a1=200;
Integer b1=200;
a1==b1 echo false

-128到127之间的值是存在一块缓存区域中超过此区间这个是new Integer

创建一个线程池有几种方法以及参数

可以使用Executors类创建也可以自己new ThreadPoolExecutor();

1
2
3
4
5
6
new ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory);

执行流程当有任务执行的时候创建一个线程执行此任务如果,已到达corePoolSize大小并且小于maximumPoolSize时且没有空闲的线程,将任务加入到任务队列中
当任务队列慢了的时候开始创建新的线程执行任务队列中的任务。当等于maximumPoolSize大小的时候且任务队列满了的时候此时开始启用策略,默认是拒绝任务加入,还有一种是抛弃旧的任务。
当任务都执行完成了线程池的线程数大于corePoolSize,并且空闲时间大于keepAliveTime时销毁线程使之线程池中的数量等于corePoolSize

Executors.newFixedThreadPool(int nThreads):创建一个固定的大小的线程池
Executors.newSingleThreadExecutor();创建一个线程的线程池
Executors.newCachedThreadPool();创建一个0到Integer.MAX_VALUE区间的线程池 线程空闲60秒销毁

Spring的IOC(循环依赖)

IOC 注入有三种方式
构造器注入、set注入、注解注入

循环注入问题
如果采用构造器或者bean为prototype的此时循环依赖会抛出异常,在以下情况不会出现循环依赖异常scope为singleton非构造器注入

Spring AOP

有两种代理方式一中是使用JdkDynamicAopProxy一种是使用cglib判断方式是被代理的类有没有实现一个接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
return CglibProxyFactory.createCglibProxy(config);
}else {
return new JdkDynamicAopProxy(config);
}
}

/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
}
}

Spring一个方法是否可以配置多个切面

可以,是采用递归的方式执行

Java内存结构

方法区 堆 栈 程序计数器 本地方法栈
方法区:被所有线程共享区域用于存放已被虚拟机加载的类信息,常量,静态变量等数据
栈:它是线程私有的,生命周期与线程相同,存放编译期间可知的8种基本数据类型,及对象引用和指令地址
堆:堆被所有线程共享区域,在虚拟机启动时创建,唯一目的存放对象实例
程序计数器:当前线程所执行的行号指示器
本地方法栈:用于支持native方法的运行
堆有可以细分为新生代、幸存区、和老年代

Spring多数据源的事物控制

Spring事物嵌套

采用REQUIRED级别只要一个失败结果都失败不管有没有try异常
场景:如果一个失败了另一个不受影响 可以对那个需要不受印象的配置为NOT_SUPPORTED 已非事物执行如果当前存在事物就将事物挂起
或者采用独立事物执行 REQUIRES_NEW新建一个事物,如果当前存在事物就将事物挂起

ThreadLocal结构

当前线程属性threadLocals 为一个ThreadLocalMap结构

redis

单进程单线程 多路 I/O 复用模型

redis有几种数据结构

String:字符串
hash:哈希 Map结构
List:列表 双向链表结构
set:集合 不允许重复且无序的
sortset 有序集合

redis常用方法

String类型对应 set get del
Hash类型对应 hset hget hdel
List类型对应 lset lpush lpop
set: sadd spop
sortset zadd
发布/订阅
原子操作

redis事物

分布式锁如何实现

借助redis

  • 1、setnx(lockkey, 当前时间+过期超时时间) ,如果返回1,则获取锁成功;
    如果返回0则没有获取到锁,转向2。
  • 2、get(lockkey)获取值oldExpireTime ,并将这个value值与当前的系统时间进行比较,
    如果小于当前系统时间,则认为这个锁已经超时,可以允许别的请求重新获取,转向3。
  • 3、计算newExpireTime=当前时间+过期超时时间,然后getset(lockkey, newExpireTime)
    会返回当前lockkey的值currentExpireTime。
  • 4、判断currentExpireTime与oldExpireTime 是否相等,如果相等,
    说明当前getset设置成功,获取到了锁。如果不相等,说明这个锁又被别的请求获取走了,那么当前请求可以直接返回失败,或者继续重试。
  • 5、在获取到锁之后,当前线程可以开始自己的业务处理,当处理完毕后,比较自己的处理时间和对于锁设置的超时时间,如果小于锁设置的超时时间,则直接执行delete释放锁;如果大于锁设置的超时时间,则不需要再锁进行处理。

多个方法同时操作一条数据怎么办

将表的引擎修改为innerDB这种就支持行锁,但注意的是表里面需要含有主键 查询条件也需要为主键字段或者会成为表锁

二叉树遍历的几种方式

前序(根左右) 中序(左根右)后序(左右根)

二分查找法

栈(先进后出)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Stack{
Object[] element;
int elementCount;

public Stack(){
element = new Object[10];
}

public synchronized void push(Object o){
element[elementCount++]=o;
}
public synchronized Object pop(){
Object o = element[elementCount--];
element[elementCount--]=null;
return o;
}
}

堆(先进先出)

http状态码

linux下查看日志文件常用命令

适配器模式

系统需要使用现有的类,而这些类的接口不符合系统的接口。

Java中那些类使用了那些模式

乐观锁

每次去拿数据的时候都认为别人不会修改,所以不会上锁,但在更新的时候会判断一下再次期间有没有人去更新这个数据,可是使用版本号等机制。
在表中添加一个version字段来记录当前数据的版本号

悲观锁

每次取数据的时候都会认为别人会对这个数据进行修改,所以每次拿数据的时候都会加上锁 比如行锁,表锁等,读锁,写锁等

mysql 锁分三种 行锁、表锁、页锁
innoDB 行锁在检索数据的时候只有根据索引为条件才会添加行锁或者为表锁
MyISAM 表锁 不支持事物
a、对MyISAM表的读操作(加读锁),不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
b、对MyISAM表的写操作(加写锁),会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
BDB 页锁

行锁:对写操作多的时候使用行数可以提搞并发;缺点:比页锁需要占用更多的内存。
表锁:对度操作多的时候使用表锁可以提高性能

事物与锁

事物:原子性、一致性、隔离性、持久性
锁:是为了保证数据的完整性。

线上mysql如何查看那条sql执行时间比较长

查看mysql慢日志

synchronized与Lock

synchronizeed与Lock实现的功能都一样,在使用方面synchronizeed是隐式的而Lock是显示的
大多数情况下,内置锁都能很好的工作,但在功能上存在一些局限性,例如,无法中断一个正在等待获取锁的的线程。或者无法再请求获取一个锁时无限地等待下去。
Lock是基于CAS LockSupport.park()与LockSupport.unpark实现

请描述一下GC(jvm垃圾回收器)

Java中的引用有几种?

四种 分别为强引用 弱引用 软引用 虚引用

Java中的threadlocal是怎么用的? threadlocal中的内部实现是怎么样的? 哪种引用?

new ThreadLocal()调用set get方法
软引用
使用当前线程的的threadLocals属性 这是一个Map结构

Java中的”final”关键字在多线程的语义中,有什么含义

最终的不可修改的

说说nio的架构,为什么变快了,说说select和buffer都是怎么用的?

在操作系统中的实现原理? 如果都是cpu轮训话,会不会对cpu影响太大?
应用到了linux中的什么特性?

NIO无阻塞IO,基于事件驱动,
在Select中绑定Socket 注册相关事件
ByteBuffer.allocateDirect()

nio中, 如果不显式的调用 system.gc() 那会出现什么问题?

会引起内存溢出
对系统而言分为内核空间和用户空间 而jvm属于用户空间在jvm中垃圾是自动回收,而触发这个垃圾回收器的时机是java堆内存满的时候
在NIO中使用的ByteBuffer通过allocateDirect在内核内存中分配了一份空间。而此空间不属于jvm堆所以如果不显示调用gc就会引起系统内存溢出的情况
这也是传说中的零拷贝

SimpleDateFormat如果是一个全局变量的话,有什么问题?

因为不是同步的 在并发的时候会引起各种错误异常

HashMap的操作中,直接使用keySet()遍历有什么问题

性能底下;为啥呢因为会遍历两次

线程池队列中几种策略

两种
第一种:拒绝任务
第二种:丢弃历史任务

ConcurrentHashMap为什么会比HashTable快

一个数组n 其中的值是1到n-1 找出其中第一个重复的

两个整数交换不使用第三个变量

a=a+b;
b=a-b;
a=a-b;

手写代码实现LRU数据结构

查看http://www.programcreek.com/2013/03/leetcode-lru-cache-java/

一个数组将奇数放左边偶数放右边

一个字符串找出第一个相同的字符

数据库sql优化

数据库索引该如何建在正确的字段上

Spring有几种事物隔离

请描述一下Spring MVC 从发起请求到后台的处理流程

请描述一下JVM类加载