zoukankan      html  css  js  c++  java
  • 记一次失败的大厂面试

     

     阅读完本文需要 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: 

     

     stormli

  • 相关阅读:
    【转+补充】在OpenCV for Android 2.4.5中使用SURF(nonfree module)
    Delphi StarOffice Framework Beta 1.0 发布
    Angular ngIf相关问题
    angularjs文档下载
    公众号微信支付开发
    公众号第三方平台开发 教程六 代公众号使用JS SDK说明
    公众号第三方平台开发 教程五 代公众号处理消息和事件
    公众号第三方平台开发 教程四 代公众号发起网页授权说明
    公众号第三方平台开发 教程三 微信公众号授权第三方平台
    公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取
  • 原文地址:https://www.cnblogs.com/zhuixun/p/13189208.html
Copyright © 2011-2022 走看看