天天看点

2018.9.21携程后台开发面试记录

一面感觉挺随便的,就是一大群人和一大群面试官在一个大房间然后一对一面试,俨然一个菜市场……也不知道有没有二面,面试官有些问题也没答上来,作为第一次面试还是好好记录一下,积累面试的套路经验

1、上来当然还是自我介绍

2、看简历,让我讲一下模仿天猫的项目用了什么技术栈,我主要用的SSM,就问了Spring的bean对象的生命周期。这个其实不是特别清楚,现在捋一下

流程图转自这篇博客

2018.9.21携程后台开发面试记录
2018.9.21携程后台开发面试记录

Bean的完整声明周期经过了很多方法调用,大致分为四个

  1. Bean自身的方法:包括Bean自身调用的方法以及applicationContext.xml中指定的init-method和destroy-method
  2. Bean级生命周期接口方法:这个包括了BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean这些接口的方法
  3. 容器级生命接口方法:这个包括InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口,一般称它们的实现类为“后处理器”
  4. 工厂后处理器方法:这个包括AspectJWeavingEnabler,ConfigurationClassPostProcessor,CustomerAutowireConfigurer等工厂后处理器接口的方法,它也是容器级的,在应用上下文装配配置文件后立即调用

演示:

2018.9.21携程后台开发面试记录

对照测试结果和流程图基本就清楚了

3、问项目是学校的还是单位的还是怎么的,我说是按照一个教程做的,就设想了一个并发场景,如果库存为1但同时有两人下单,那么会出现什么问题,如何解决。我一开始给的方案是给数据库加锁,同一时间只有一个用户能操作数据,他思考了一下说这样是可行的,但是又会带来另一个问题,如果此时库存加货了需要更新怎么办,让我回来思考。问了问站长他说可以用乐观锁来解决,大致就是采用一个版本控制,原理图如下

2018.9.21携程后台开发面试记录

4、因为刚才讨论过程中我说到了也许可以用事务来解决(当然我是随便说的很快就反应到不对了)所以他又问了数据库的隔离级别, 这个没怎么看过,当时回答还跟springMVC的事务隔离级别混淆了,现在补上……

数据库的四种隔离级别

READ_UNCOMMITED

  • 事务对当前读取的数据不加锁
  • 事务在更新数据的瞬间必须对其加行级共享锁,直到事务结束才释放

表现

  • 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,能读到事务2对该记录的修改版本,即使该修改尚未被提交
  • 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束

READ_COMMITED

  • 事务对当前读取到的数据加行级共享锁,一旦读完该行,立即释放锁
  • 事务在更新某数据瞬间,必须加行级排他锁,直到事务结束才释放

表现

  • 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的只能是事务2对其更新前的版本,要不就是事务2提交后的版本
  • 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束

REPEATABLE_READ

  • 事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加行级共享锁,直到事务结束才释放
  • 事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放

表现

  • 事务1读取某行记录时,事务2也能对这行记录进行读取、更新;当事务2对该记录进行更新时,事务1再次读取该记录,读到的仍然是第一次读取的那个版本
  • 事务1更新某行记录时,事务2不能对这行记录做更新,直到事务1结束

SERIALIZABLE

  • 事务在读取数据时,必须先对其加表级共享锁,直到事务结束才释放
  • 事务在更新数据时,必须先对其加表级排他锁,直到事务结束才释放

表现

  • 事务1正在读取A表中的记录时,则事务2也能读取A表,但不能对A表做更新、新增、删除,直到事务1结束
  • 事务1正在更新A表中的记录时,则事务2不能读取A表的任意记录,更不可能对A表做更新、新增、删除,直到事务1结束

5、开始问Java基础,比如ArrayList和LinkedList的区别,插入较多选用哪个;HashMap和HashTable的区别,选用什么(我说ConcurrentHashMap)于是问了HashTable和ConcurrentHashMap线程安全的实现方式区别;然后还问了创建线程的两种方式,start和run的区别

6、问原子操作是什么意思,原子类是如何实现的。只记得原子类了,当时回答说可能都用了synchronized关键词,这里记一下

使用CAS算法,直接由硬件支持保证原子性

CAS记录三个值,内存位置V,预期值A,新值B

如果更新时发现V与A相等,则说明数据没有被修改过,就用B更新V,否则什么都不做

7、问了一些深入点的问题,用到什么设计模式(设计模式还没看,只能乱答)他提示我用过单例模式没有,我说用过,于是要求手写了一个单例(有点忘记了,估计当时写错了)这里巩固一下

三个要素
  1. 构造方法私有化,保证无法在外部new一个对象
  2. 静态属性指向实例
  3. public static的getInstance方法,返回第二步的静态属性
// 饿汉式,直接新建实例
public class Singleton {
	private static Object instance = new Object();
	private Singleton() {}
	public static Object getInstance() {
		return instance;
	}
}

// 懒汉式,调用方法时才新建实例
public class Singleton {
	private static Object instance;
	private Singleton() {}
	public static Object getInstance() {
		if (null == instance)
			instance = new Object();
		return instance;
	}
}
           

8、问JVM帮助我们优化了什么东西,举了个例子是回收内存。这个真的不知道怎么回答,毕竟没有深入研究过JVM……

9、看我是电气的,问我为什么转行,职业规划之类的

10、有什么问题要问我

差不多就这些,感觉自己答的不是太好,很多地方还有欠缺,没过也不觉得可惜吧。积攒经验,准备后面的面试