面试复盘 | 招银网络一、二、Hr面
招银网络一面
9/22 16:50 40分钟 这里只记录回答不上来的问题;
- 自我介绍
- 聊了一下本科学习的东西
- java中是否存在像C++里面一样的goto关键字
java中goto是属于保留字的,目前还没有在java中使用。
在java中想实现跳转操作,可以使用break,continue和label标签配合使用,进行相关的跳转,例如在双重for循环中,内循环体中的break只能结束内层循环,但是如果加了标签,则可以直接结束所以循环到标签处。public static void main(String[] args) { label1: for (int i=0;i<10;i++){ System.out.println("tti"+i); for (int j = 0;j<10;j++){ if(j==6){ break label1; // 这里就会直接跳转到label1并且后面不会再进入for循环; } } } System.out.println("all test is over!~"); } // 输出为: tti0 all test is over!~
- Mybatis中的$和#符号可能带来了什么隐患
- mysql的索引失效情况
- mysql在下面的情况中有可能失效:
- 模糊查询:like以%开头时,索引会失效(有特殊情况,当所需要查询的字段是属于已建的索引时(包括主键索引),那么这时候即使是以%开头的字段,依旧可以使用索引,主要是覆盖查询的存在)
- or语句的前后没有同时使用索引的时候。当or语句查询字段只有一个有索引,该索引一定失效,当or语句两端的查询字段均为索引时,会视情况是否生效(经过测试,在其中一个查询字段用到了主键索引时,其同时会使用到两个索引,但是对于两个普通索引,其组合的话会失效)
- 当是组合索引的时候,如果没有使用到第一列索引,则其也会索引失效
- 在索引列上出现is null 或 is not null,!=操作时,索引视情况来判断是否失效。
- 首先对于允许为null值的字段,其创建了索引后,null值会在B+树的最左端(因为mysql中默认null值为最小值),在进行上述查询时,具体要不要使用索引,mysql会看成本。成本组成主要有两个方面:
- 读取二级索引记录的成本
- 将二级索引记录执行回表操作,也就是到聚簇索引中找到完整的用户记录的操作所付出的成本。所以MySQL优化器在真正执行查询之前,对于每个可能使用到的索引来说,都会预先计算一下需要扫描的二级索引记录的数量(通过index dive或者依据统计数据估算,详见:https://mp.weixin.qq.com/s/CEJFsDBizdl0SvugGX7UmQ)
- 首先对于允许为null值的字段,其创建了索引后,null值会在B+树的最左端(因为mysql中默认null值为最小值),在进行上述查询时,具体要不要使用索引,mysql会看成本。成本组成主要有两个方面:
- 在索引字段上使用not,,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key0 改为 key>0 or key<0。
- 对索引字段进行计算操作、字段上使用函数。
- 当SQL优化器认为全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。
mysql中怎么样可以实现:有一个数据存在的时候执行查找操作,该数据不存在的时候执行插入操作
MySQL插入一条数据,如果数据已存在就跳过,不存在就插入:使用insert ignore语句:(要求必须有唯一字段参与匹配,该唯一字段可以为主键)
insert ignore into dept(deptno) values(20); # 如果已存在deptno为20的行,则跳过不执行操作,否则执行插入(注意deptno必须唯一或为主键插入一条数据,如果数据存在则更新,不存在则插入(必须要有唯一字段或主键),使用 insert...on duplicate key update语句,例如:
insert into dept(deptno,dname) values(30,'null') on duplicate key update dname='xiaoming';
该条语句,如果已经存在了对应的deptno(deptno为unique或者主键),那么就执行后面的update操作,即其就等价于:
update dept set dname='xiaoming' where deptno=30;
如果并不存在对应的deptno,则执行insert操作,即相当于只存在on 关键字前面半部分。
如果最终执行的是行插入操作,则该条语句执行结果中返回的受影响的行数为1;如果是原有的记录被更新,则返回的受影响的行的值为2;Replace关键字的使用:Replace关键字最主要的作用就是可以将delete和insert操作合二为一,实现一个原子操作。在使用Replace时,表中必须存在唯一索引,即存在unique字段,且该字段不允许为空值。
replace into dept(deptno,dname,loc) values(50,'xiaohong','BeiJing');
当deptno=50存在时,就会执行delete这条记录,并重新insert一个新的记录,新纪录dname和loc为当前设定的值;当deptno=50不存在时,则直接执行插入操作;
在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明没有重复的记录,直接执行插入操作;如果返回2,说明有重复记录,系统先DELETE这条记录,然后再INSERT这条记录。
招银网络二面
9/24 14:10 40分钟
- 自我介绍
- 从你的项目里面挑一个你最熟悉的讲一下吧
- (针对项目进行各种角度提问)
- JVM垃圾清理常见的算法有哪些(CMS和G1)
- 说一说CMS算法
CMS垃圾收集器
- 简介:是一种==以获取最短回收停顿时间为目标==(最小时延)的收集器,其基于标记-清除算法实现,其主要的优点是并发收集、低停顿。
- 运行过程:可分为4个步骤:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
- “标记”是指将存活的对象和要回收的对象都给标记出来,而“清除”是指清除掉将要回收的对象。
- 其中,初始标记、重新标记这两个步骤仍然需要“Stop The World”。
- 初始标记只是标记一下GC Roots能直接关联到的对象,速度很快。
- 并发标记阶段,就是从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时很长但是不需要停顿用户线程,可以与垃圾回收器一起并发运行。
- 重新标记阶段则==是为了修正并发标记期间因用户程序继续动作而导致标记产生变动的那一部分对象的标记记录==,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。
- 最后是并发清除阶段,清理删除掉标记阶段判断的已经死亡的对象,由于不需要移动对象,所以这个阶段也是可以与用户线程并发的。
- CMS收集器的动作步骤如下图所示,在整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,因此,从总体上看,CMS收集器的内存回收过程是与用户线程一起并发执行的:
- 注:STW即Stop The World
- CMS收集器缺点
- 对处理器资源非常敏感,尤其是处理器小于4的时候,其占有的线程资源比重就会很大
- 会出现“浮动垃圾”,即标记处理之前该对象不是垃圾,但是处理之后这个对象又成为了垃圾,即在并发清理的过程中出现的新的垃圾称为浮动垃圾。
- 会产生内存碎片,严重时无法存放大对象,直接触发Full GC。
- CMS算法是如何进行内存分区的(暂时不知)
- Redis数据库常见的数据结构类型有哪些(String、List、set、Zset、Hash)
- 算法题:如何实现一个最小栈,即设计一个栈包含push、pop、min、top方法(力扣原题)
- emm...就记得这么多了,总体来说问的不难
Hr面
9/28 11:00 30分钟
- 自我介绍
- 说一下为什么想从事后端研发这个职位呢
- 后面的职业规划
- 挑一个你之前觉得对你挑战最大的项目讲一下吧,并说一下遇到了哪些问题,怎么解决的?
- (针对项目进行细节性提问)
- 说一下你的家庭情况吧
- 你家里父母同意你到成都工作吗
- 对于陌生的技术,你如何对它进行学习呢
- 你如何看待加班这个事情(害,只能违心回答了)
- 你如何评估一个期望去的公司呢(你最看重公司的哪些方面)
- 反问
总结:招银网络面试官水平还是有的,不会出现不懂装懂全盘否定你的情况,至少现在看来还不错。
反思:不要不懂装懂,诚实点还是很不错的。