“ 阅读完本文需要 8 分钟。”
最近开始考虑换个工作了,在招聘网站上投了十几份简历,发现 JAVA 程序员要求都变高了,基本上都要求 3-5 年以上的经验了,但是去哪儿找那么多 3-5 年开发经验的程序员呢,3-5 年只是个要求,对于能力强的程序员来说可以试试。其中投了一些大厂,过后就没怎么在意这些事情了。
上周五,在家里的我晚上 7 点突然接到了一个来自大厂的电话,你好,你是 XXX 吗? 我们现在可以进行电话面试吗?当时我就惊呆了,因为我没有做好准备,事到入今也只能硬着头皮上了。
请你做个自我介绍:
一、介绍一下自己的名字,如果有特色的名字可以稍微解释一下,简洁介绍下自己的工作经历等;
二、接下来可以介绍平日里在公司做得是什么业务,做得什么项目,用了哪些技术,相比于市场同等产品优势在哪里?你对项目的贡献点在哪里?说句实话,这两年我一直在做公司内部业务的项目,基本上都是给公司内部用,压根就谈不上市场和前景,更不用谈涉及到高并发这些了,所以这一块我很吃亏;
三、你说完了之后,就该面试官问你问题了。看你简历上写了两个项目,具体讲讲这两个项目的功能,技术,使用场景,你就开始和面试官巴拉巴拉聊起来,中间的话面试官可能还会打断你提一些技术问题,例如他会深挖你的项目,如果项目中使用了 redis,如何避免高并发情况下缓存击穿等问题,具体文章可以参考这篇文章:
https://juejin.im/post/5c9a67ac6fb9a070cb24bf34,或者使用了哪些数据结构和算法等。
1、好,到了这一步,面试官还会问你简历上写的技能,例如你在某个项目中是如何解决了 MYSQL 连接数过多导致系统崩溃的问题。这是我刚来公司时接收的一个项目,这个项目上线后一开始还正常,运行几天后就会把 MYSQL 数据库连接数占尽,并且不会释放连接,导致最终 MYSQL 崩溃。查看 MYSQL 最大连接数:
show variables like '%max_connections%';
MYSQL 实时查看连接数:
show status like '%Thread%';
或者
show global status like 'Thread%';
设置 MYSQL 最大连接数:
set GLOBAL max_connections = 2000;
公司测试环境下 MYSQL 设置的连接数是两千多个,我这个项目运行几天后就会将连接数耗尽,运维会找到我要求我解决问题。打开项目发现项目中使用了 C3p0 连接池和 SpringTemplate 进行数据库操作,怀疑可能是该问题导致。
@Cacheable(cacheNames = "jdbcTemplateCache", key = "#dbName", unless = "#result == null") public JdbcTemplate getJdbcTemplate(String dbName) { ComboPooledDataSource dataSource = null; try { dataSource = new ComboPooledDataSource(); dataSource.setUser(jdbcUsername); dataSource.setPassword(jdbcPassword); dataSource.setDriverClass(jdbcDriver); dataSource.setJdbcUrl(jdbcAddress + dbName + SQL_UNICODE); dataSource.setMaxPoolSize(10); dataSource.setMaxIdleTime(300); dataSource.setAcquireIncrement(1); dataSource.setMaxConnectionAge(36000); dataSource.setAcquireRetryAttempts(5); return new JdbcTemplate(dataSource); } catch (Exception e) { return null; }
换成了 Spring 自带的 SingleConnectionDataSource,代码变成了如下所示:
@Cacheable(cacheNames = "jdbcTemplateCache", key = "#dbName", unless = "#result == null") public JdbcTemplate getJdbcTemplate(String dbName) { SingleConnectionDataSource dataSource = null; try { dataSource = new SingleConnectionDataSource(); dataSource.setUsername(jdbcUsername); dataSource.setPassword(jdbcPassword); dataSource.setDriverClassName(jdbcDriver); dataSource.setUrl(jdbcAddress + dbName + SQL_UNICODE); return new JdbcTemplate(dataSource); } catch (Exception e) { return null; } } }
项目重新运行起来,使用 Jmeter 填好接口地址测试 2000 个并发量,查看数据库连接数,不超过两百个,关于 Jmeter 使用可以参考下文:
https://blog.csdn.net/gld824125233/article/details/52799496
这里使用了单例模式来创建这个数据库连接池,关于这里思考如果使用 Druid 连接池效果会更好一些,项目正常上线后没有再次出现连接不释放的情况了。
我的简历上面写了对 MYSQL 调优有一些研究,这话说得好尴尬,准确来说我最近刚看完 《深入浅出 MYSQL》这本书,刚好了解了一些调优的知识,先说 SQL 优化:
1)、使用 show status 来查看各种 SQL 的执行效率
show status like 'Com_%';
比较关心的是
Com_select、Com_insert、Com_update、Com_delete 的操作次数
2)、定位执行效率较低的 SQL 语句
使用 EXPLAIN 命令分析具体做法在执行的 SQL 语句前面加上 explain 命令
explain select * from pre_home_blog; +----+-------------+---------------+--------+---------------+------+---------+------+------+---------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------------+--------+---------------+------+---------+------+------+---------------------+ | 1 | SIMPLE | pre_home_blog | system | NULL | NULL | NULL | NULL | 0 | const row not found | +----+-------------+---------------+--------+---------------+------+---------+------+------+---------------------+
type = ALL(全表扫描),type = index (索引全扫描)、type = range (索引范围扫描)、type = ref (使用非唯一索引扫描或唯一索引的前缀扫描)、type = const/system (单表中查询,一般使用主键或者唯一索引 unique index 进行查询)、type = NULL(MYSQL 不用访问表或者索引就可以得到结果),例如:
explain select 1 from task_quartz where 1; +----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | task_quartz | index | NULL | PRIMARY | 8 | NULL | 4 | Using index
|+----+-------------+-------------+-------+---------------+---------+---------+------+------+-------------+
type = index ,并不为 NULL
3)通过 show profile 来分析 SQL
MYSQL 从 5.0.37 版开始支持对 show profiles 和 show profile 语句的支持,查看当前 MYSQL 是否支持 profile:
select @@profiling;
+-------------+ | @@profiling | +-------------+ | 0 | +-------------+ 1 row in set (0.03 sec)
默认 profiling 是关闭的,通过 Set 语句在 Session 级别开启 profiling
mysql> set profiling = 1;
执行一条查询语句后,执行 show profiles; 语句
select count(*) from tb_user;show profiles;
+----------+------------+-------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------+
| 1 | 0.00023800 | select count(*) from tb_user |
+----------+------------+-------------------------------------------+
考虑到文章篇幅问题后续会出 MYSQL 调优第一篇系列以及 REDIS 基础等等文章,
4)最后谈了下 Redis ,Redis
有哪几种基本数据类型,脑海里想了想:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset),我当时没说完整,Redis 有两种持久化方式, 脑海里只记得 AOF (Append
Only File)了, 面试官补充道 RDB (Redis DataBase),他们两者之间的区别在于哪里,额,前一段时间好像看过现在忘了,一点记忆都没有了,《Redis 设计与实现》 这本书不久前还读过,到这里我想我已经被 PASS 了,后面面试官为了让气氛不那么尴尬,问我有什么想问的吗?RDB 是通过快照的方式进行数据的保存,而 AOF 是将 Redis 执行过的所有指令保存下,RDB 恢复数据可能会导致数据丢失,而 AOF 则是保存了完整的数据,但是随着指令越来越多,AOF 文件也会越来越大,Redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,具体详情查看博客:https://blog.csdn.net/ljheee/article/details/76284082
5)到了我提问的环节,首先问一下公司的业务是干什么的,平时的一个工作日常是什么样的?团队氛围怎么样,用几个词形容一下?公司有没有提供培训或者提升的机会,这个职业的下一步是什么?团队多少人?创始人是否是技术出身?创始人的偶像是谁?等等问题,总之上面几个问题可以问 2 到 3 个即可以,和面试官有话聊,聊得下去。可以参考 b 站上一位面试官大佬的分享经验: https://space.bilibili.com/109606796
平时我是个话很少的人,这次和面试官聊了半个多小时,程序员需要平时多与人沟通,说话毕竟人是社会性动物,一定要有自信能 hold 住面试官。
其实面试官一开始在某些问题应聘者答不上来时心里已经 PASS 了,为了照顾应聘者的尊严,后面会出一些简单题来考面试者,应聘者觉得自己答得很好但是没有被录取,问题就在于这里。
这次面试总结:
1、简历上的内容务必真实,一定要吃透,上面写得东西一定要十分熟悉,否则被人逮住怼,换个角度考虑如果你是面试官看到你的简历会如何提问?
2、投了简历之后不要觉得没事干了,多复习基础知识、数据结构、刷力扣等,多总结,而且不知道什么时候就会有个电话打过来;
3、关于学习一定要将学得知识用起来,否则只是走马观花,关键时候记不起来,看书是输入,写作是输出,将自己学到的编程知识写成文章,提前做好准备,在学中做,在做中学。
4、简历上如果你干了什么事情,对于整个系统优化有什么提高,或者这个你所负责的模块和以前相比较提高在哪里,一定要有数据对比才能真正的展现你。
最后,希望这篇文章对你会有一点帮助,祝福每个程序员都能拿到心仪的 offer 。
更多关于面试、技术的干货欢迎关注我的微信公众号 stormli: