引子
大概,有一家挺想去的公司面试把我给挂了。
反思了一下,问我的问题,大多都是我能回答得好的。面试经验的不足,这几天承受的压力,面试官给我的那种压迫感,让本来就不清晰的思绪更加一片空白。
年轻人,继续加油吧~既然决定要做披荆斩棘的利剑,就别甘于被用来劈柴。
题目
1、散列表、Hash冲突 与 链表法。
问题:将 69、45、29、28、16、8、88、38、75、22 这个10个数作为 Key 存入散列表,Hash函数为 hash(x) = x%7。使用 链表法 解决hash冲突。每个Key命中等概率,则链表的平均查找长度为( 1.4 )?
解答:有题意,可得:
X | 69 | 45 | 29 | 28 | 16 | 8 | 88 | 38 | 75 | 22 |
---|---|---|---|---|---|---|---|---|---|---|
hash(x) | 6 | 3 | 1 | 0 | 2 | 1 | 4 | 3 | 5 | 1 |
由上可以得:
索引 | 链表长度 | 链表查找长度 |
---|---|---|
0 | 1 | 1 |
1 | 3 | 1+2+3=6 |
2 | 1 | 1 |
3 | 2 | 1+2=3 |
4 | 1 | 1 |
5 | 1 | 1 |
6 | 1 | 1 |
由于命中Key是等概率的,所以链表的平均查找长度为:(1+6+1+3+1+1+1) / 10 = 1.4。
对于上面这个表格,需要解释一下:
拿索引 1 来说,因为根据 hash() 方法,我们可到得到:hash(29) = hash(8) = hash(22) = 1。所以,索引为1的链表长度为3。
如上图,要查找到 29、8、22 三个节点,需要遍历的链表长度分别为 1、2、3,则索引为 1时的三个结点的链表查找总长度为 1+2+3=6。
2、构建型设计模式
常见的构建型设计模式有:单例模式、工厂模式、工厂方法和 抽象工厂、建造者模式 和 原型模式。
3、JVM类加载机制
类加载过程中,解析 阶段的作用是 Java虚拟机将常量池内的 符号引用 替换为 直接引用 的过程
4、synchronzied 和 ReentrantLock 的区别?
相同点:
- 两者都可以为需要同步的代码块加锁,保证资源在线程间的可见性和有序性。
- 两者都是可重入锁,一个线程可以多次重复获取同一把锁。
- 两者都支持 等待、唤醒操作:使用synchronized时可以通过 obj.wait() 、obj.notify() 来使线程等待、唤醒;而ReentrantLock一般和 Condition搭配,使用 condition.await()、condition.signal() 来使线程等待、唤醒。
不同点:
- ReentrantLock有着显式的加锁、释放锁过程,开发者需要手动指定何时加锁、何时释放锁。而synchonized 自动获取、释放锁。相对 synchronized 而言,ReentrantLock更加灵活。
- 中断响应:synchronized加锁的线程不能被中断,而使用 reentrantLock.lockInterruptibly()方法来申请的ReentrantLock锁支持响应中断。
- 锁申请等待限时:ReentrantLock.tryLock()方法可以指定一个等待时间,如果在指定时间内不能成功申请到锁,当前线程不会等待,而是立即返回 false;
- 非阻塞方式获取锁:ReentrantLock.tryLock()方法不指定时间时,线程会尝试获取锁,如果获取失败,方法立即返回 false,不会阻塞。
- 公平锁:使用synchroinzed 进行锁控制得到的是非公平的锁,而ReentrantLock支持通过构造方法 ReentrantLock(boolean fair)申请一个公平的锁。
5、Thread.sleep() 和 Object.wait() 的区别?
参考:https://blog.csdn.net/Zereao/article/details/105484827#t3
6、MySQL事务的隔离级别?
- Serializable:采用最保守的策略,解决了“幻读”的问题。
- Repeatable Read:解决了“不可重复读”的问题。
- Read Commited:当前事务可能读取到其他事务提交的数据,可能存在“不可重复读”的问题;
- Read Uncommited:当前事务可能读取到其他事务未提交的数据,可能存在“脏读”的问题。
脏读、幻读与不可重复读:
参考:MySQL事务的特性与隔离级别_怕乌龟骑的博客-CSDN博客
7、Spring中事务是用哪个关键字实现的?针对的是什么异常?事务不生效可能的原因有哪些?
Spring中事务是由 @Transactional 注解支持的。针对的是 unchecked exception。
- UnChecked Exception:包括 RuntimeException 和 其子类,以及 Error 及其子类。例如 NullPointerException等。
- Checked Exception:除了上面的 UnCheckException,其他的都称为 CheckedExcetion。例如:IOException、NoSuchFieldException。CheckedException 必须要手动进行捕获。
事务不生效的原因可能有:
- 注解标注的方法的访问权限不是 public 的,或者,方法被 static、final 标注。
- 方法调用是目标对象内的相互调用,方法没有被正确代理。
- Spring事务管理只会在出现 UnCheckedException 的时候才会回滚。
- MySQL使用了不支持事务的引擎,例如:MyISAM
8、Spring事务的传播机制?
Spring中定义了7种事务传播机制,在 org.springframework.transaction.annotation.Propagation 枚举中定义:
public enum Propagation {
REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);
// 省略其他方法
}
下面就分别介绍下这几种机制:
- REQUIRED:默认配置。如果当前存在事务,则加入,合并为一个事务;如果不存在事务,则新建事务。
- SUPPORTS:如果存在事务,则加入;如果不存在事务,则按照非事务方式运行。
- MANDATORY:如果当前存在事务,则加入;如果不存在事务,则抛出异常。
- REQUIRES_NEW:创建一个新的事务,不管是是否存在事务。新旧事务独立,父级事务异常,它也会正常提交。
- NOT_SUPPORTED:非事务方式执行;如果存在事务,则挂起该事务。
- NEVER:非事务方式执行;如果已经存在事务,则抛出异常。
- NESTED:如果当前不存在事务,则新建事务;如果当前存在事务,则在嵌套事务中执行——它将成为父级事务的一个子事务,方法结束后不提交,等父级事务提交后才提交。如果父级事务异常,子事务也会回滚。
9、MyBatis中,“${ }”和“#{ }”的区别?
使用 “#{ }” 参数语法时,MyBatis会创建 PreparedStatement 参数占位符,使用“?”做预处理,并通过占位符安全地设置参数。这样做更安全、更迅速,是首选做法。
使用“${ }”参数语法时,MyBatis不会修改或转义该字符串,而直接使用目标字符串 替换掉 “${ }” 这一块。这样做是不安全的,可能会存在潜在的SQL注入攻击。
10、MyBatis中的缓存,有了解过么?
MyBatis提供了对缓存的支持,分为一起缓存和二级缓存。默认情况下,只开启一级缓存。
一级缓存:
一级缓存是针对同一个 SqlSession 而言的。
- 在同一个SqlSession中,MyBatis会把执行的方法和参数通过一定的算法生成缓存的Key,将Key和查询结果存放在一个Map中。如果后续查询的Key已存在,则直接从Map中获取结果返回。
- 不同的SqlSession之间的缓存是相互隔离的。
- 使用一个SqlSession时,可以通过配置使得在查询前清空缓存。
- 如果需要刷新缓存,会清空这个 SqlSession 中的所有缓存,而不是某个特定的 Key。
- 任何 UPDATE、INSERT、DELETE 语句都会清空缓存。
二级缓存:
二级缓存是针对 同一个Mapper的。当多个SqlSession去操作同一个 Mapper 的时候,会将从数据库查到的数据存放在二级缓存区域。二级缓存可以在多个 SqlSession间共享。
默认情况下,MyBatis没有开启二级缓存。
11、Linux定时任务命令是什么?如何创建一个定时任务?
Linux定时任务处理的命令是:crontab。
简单的说,创建一个定时任务分两步:
- 创建一个文件(例如:vi testcron),在文件中写好 cron表达式,以及需要执行的命令;
- 使用 crontab <文件名> 来执行任务,例如:crontab testcron。
下面是 crontab配置文件的格式:
上图来自于:crontab用法与实例 | 《Linux就该这么学》,具体的详情也可以参考下这篇文章。
12、ES聚合搜索怎么操作?
这一块我之前看过,现在就记得一个 GROUP BY了。
具体的参考:Elasticsearch入门(五):Elasticsearch基础概念与基本操作_怕乌龟骑的博客-CSDN博客
总结
嗯,这一波笔试面试就记得问了这些了。当时有些东西的确是不了解,比如 Spring 的事务传播机制。无数次地遇见它,又无数次的忽略了他。有的知识,明明自己了解的很清楚,但是却没能用自己的语言流畅地表达出来,比如MySQL事务的隔离级别。说到底,还是自己没将知识理解透彻。那就,继续加油吧,年轻人!
参考文档
1、Synchronize和ReentrantLock区别 - 掘金
2、https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#Parameters
3、19. crontab 定时任务 — Linux Tools Quick Tutorial