精彩推荐

一百期Java面试题汇总

SpringBoot内容聚合

IntelliJ IDEA内容聚合

Mybatis内容聚合

在上一轮的面试中,小林在mysql方面因为作答不够完善,被面试官吊打了一番。经过两天的自我复习之后,新的一轮面试又开始了。

面试官:你好,请简单介绍下自己吧。

小林:你好,我是xxxxxx,之前在深圳的xxx公司负责了xxx系统的研发设计。

面试官:嗯嗯,那我先来问你一些基础问题吧。

小林:嗯嗯,好的。

面试官:你了解arraylist吧,请说下内部的一些特性。

小林此时心里一下子乐开了花,这个简单啊。

小林:arraylist的底层主要是由数组组成,它和普通数组不太一样,arraylist具有自动扩容的功能。每次当我们add一个元素到队列里面的时候,都会有一步确认容量的机制判断(对应源码里面的ensureCapacityInternal函数)如果当数组内部的元素达到了数组阈值的时候,就会以1.5倍的体积去做扩容,底层是调用了才做系统内部的一个System.arraycopy方法。

又由于arraylist是采用数组存储的,在读取数据的时候可以借助数组位的下标去快速定位,写数据的时候需要涉及到挪动数组,所以读的性能平均要比写的性能更高一些。

面试官:嗯嗯,回答地挺全面的。那你觉得在使用arraylist的时候一般会注意些什么吗?

小林:嗯嗯,有的。一般我会根据代码的上下文给arraylist附一个初始值来定位这个数组的大小,防止其做过多不必要的扩容操作。另外在循环中进行删除操作的时候需要注意会有坑,一般建议采用迭代器的模式来处理。

ps:

如果使用以下这种方式进行元素的移除可能会导致出现删除元素不完整的情况:

public static void main(String[] args) {ArrayListApplication arrayListApplication = new ArrayListApplication();List<String> list = new ArrayList(3);list.add("a");list.add("c");list.add("c");list.add("d");list.add("e");System.out.println(list);System.out.println("==========");removeV1(list, "c");System.out.println(list);
}
public static void removeV1(List<String> list, String deleteItem) {for (int i = 0; i < list.size(); i++) {String item = list.get(i);if (item.equals(deleteItem)) {list.remove(item);}}
}

打印结果:

[a, c, c, d, e]
==========
[a, c, d, e]

此时由于删除掉list里面元素之后,list的size值也减少了,随之导致了数组元素的前移,因此会出现被删除元素的后一位直接绕开了if判断,没有被“命中”。如果采用foreach的方式删除,则会抛出一段异常信息,声明删除失败:

Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)at java.util.ArrayList$Itr.next(ArrayList.java:859)

面试官:嗯嗯,你刚刚有说到迭代器删除,那么你有了解过迭代器模式吗?

小林:额,迭代器模式,让我思考一下.... 背了知识点,但是不记得了....

图片

面试官:好吧...

ps:其实迭代器模式的好处在于,直接帮我们屏蔽了具体的实现细节,通过采用迭代器的方式来帮助我们编写一些可以复用的类。例如说arraylist,其实内部也有自己迭代器的具体实现,vector也有自己迭代器模式的具体实现。非常的方便,并且有助于减少代码里面的对于具体实现的强依赖性。

面试官:那我们切入下一个话题吧,能说下自己对于幻读的理解吗?

小林:嗯嗯,可以的。我在上家公司工作的时候,公司内部的事务隔离级别设置为了可重复读级别,这样能够保证当前事务读取的数据不会受到其他事务提交的影响,但是这种隔离级别会在事务提交完毕之后查询数据的时候出现幻读的场景,如果需要解决幻读的情况需要将事务的隔离级别提升为串行化等级。

面试官:哦,那你在工作中有试过提升为串行化吗?

小林:没有,因为串行化是强行在mysql层加锁,使得事务得排队执行,容易产生堵塞的情况,性能不佳。

面试官:那你是怎么解决幻读的情况呢?

小林:嗯....别的同事帮我解决的.....

此时,面试官脸上渐渐露出了诡异的笑容。

图片

ps:其实幻读这种情况在工作中偶尔还是会遇到的,举个具体场景:

假设某一时刻,同时有两个事务访问了数据库,需要先从库里面查询订单是否存在,然后再插入新的订单记录。

a连接

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set, 2 warnings (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_order_1 where id =100;
Empty set (0.00 sec)

b连接

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_order_01 where id =100;
ERROR 1146 (42S02): Table 'test-db01.t_order_01' doesn't exist
mysql> select * from t_order_1 where id =100;
Empty set (0.00 sec)

假设在两边事务都开启的一刻,a连接中的事务往数据库插入了一条id为100的数据,然后commit。a连接

mysql> INSERT INTO `test-db01`.`t_order_1` ( `id`, `order_no`, `product_id`, `user_id`, `create_time`, `update_time` )-> VALUES-> ( 100, 2, 2, 2, now(), now());
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_order_1 where id=100;
+-----+----------+------------+---------+---------------------+---------------------+
| id  | order_no | product_id | user_id | create_time         | update_time         |
+-----+----------+------------+---------+---------------------+---------------------+
| 100 |        2 |          2 |       2 | 2020-07-14 22:57:37 | 2020-07-14 22:57:37 |
+-----+----------+------------+---------+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

当a事务提交结束了,此时b事务开始执行select 查询校验的操作,判断不存在id为100的数据,此时打算执行插入数据的操作:

mysql> select * from t_order_1 where id=100;
Empty set (0.00 sec)
mysql> INSERT INTO `test-db01`.`t_order_1` ( `id`, `order_no`, `product_id`, `user_id`, `create_time`, `update_time` )-> VALUES-> ( 100, 2, 2, 2, now(), now());
ERROR 1062 (23000): Duplicate entry '100' for key 'PRIMARY'

结果出现了异常,这种情况我们通常称之为幻读。那么该如何解决这种场景的问题呢?其实mysql内部提供了一种叫做next-key-lock的加锁机制,可以供我们处理这类特殊情况:

mysql> select * from t_order_1 where id=100 for update;
+-----+----------+------------+---------+---------------------+---------------------+
| id  | order_no | product_id | user_id | create_time         | update_time         |
+-----+----------+------------+---------+---------------------+---------------------+
| 100 |        2 |          2 |       2 | 2020-07-14 23:06:03 | 2020-07-14 23:06:03 |
+-----+----------+------------+---------+---------------------+---------------------+
1 row in set (0.00 sec)
借助 **for update **语句,我们可以在应用程序的层面手工实现数据加锁保护操作。就是那些需要业务层面数据独占时,可以考虑使用** for update**。

其实 for update 可以理解为一把悲观锁,每次获取数据的时候,都担心会有其他线程修改当前的数据,因此在拿数据的时候就会加入一把锁,其他试图改写数据的请求将会处于堵塞情况。(读数据的请求不会堵塞)

面试官:那你知道mysql里面的mvcc机制吗?

小林:mvcc是啥?mvc我倒知道,之前工作中有使用过springmvc框架 blabla(希望把面试官绕开引到自己熟系的话题方向)

面试官满脸微笑地看着小林,似乎想缓解下尴尬的气氛。

面试官:好吧,你之前有对缓存了解过吗?

小林:嗯嗯,我在工作中一般喜欢使用redis作为缓存。当查询数据的时候先去redis中查询,如果redis没有再去mysql中读取数据。

面试官:嗯嗯,那你有了解过redis里面的哪些数据结构吗?

小林:嗯嗯,我在工作中有使用过string,list,hash,zset,set这几类数据结构,它们各自都有自己的特点,在使用的时候需要结合实际的业务场景来使用。

String类型可以用于存储一些简单的键值对数据,例如数字,字符串之类的。

List结构一般是采用了双端队列的结构,这类结构通常使用的命令有lpush,lpop,rpop等,如果想移除某个节点的前置和后置节点就比较简单(复杂度就是O(1)),但是搜索比较复杂。适合用于存储一些列表类型的数据信息,例如说用户的留言和评论信息。

Set 是一个无顺序的集合,比较常见的例如说交集查询,用于搜索两个好友之间共同阅读过的图书。或者两个人之间的共同好友等。使用命令sinter key [key...] 即可实现。

图片

Hash是包含键值对的无序散列表,常用命令有:hget,hgetall等。

ZSet则是一套有序集合,通常会根据分值范围或者成员来获取元素并且计算一个键的排名。

面试官:嗯嗯,你讲的这些东西都只是停留在了表层,关于其内部的构造有去做过一些深入的了解吗?

小林:额,没有....

此时小林又一次被面试官打击了自信心

面试官:好吧,今天的一面主要只是问问基础,那么就先这样吧,我去找下我老大询问下。

小林:嗯嗯,好的。(似乎感觉还有戏)

小林一个人在前台坐着等待着下一场面试的到来,不仅内心感叹道,自己过去的工作中过多地安逸于写crud,很多java的基础问题也都记得不太清楚了,每天下班之后也没怎么学习,虽然一面只是问了些基础问题,结果却暴露了自己这么多的知识盲区。

过了不久一个陌生的男人慢慢走了过来,天啊,这家伙真的是聪明“绝顶” 了。小林一下子慌了,脑袋一片空白,二面似乎来了一位资深的大佬.....

二面面试官:你好,我是你的二面面试官,下边我可能会针对你的项目做一些询问。

(未完待续....)

END

我知道你 “在看”

小林求职记(二):说好的问基础,为啥我感觉一点也不基础呢?相关推荐

  1. 小林求职记(六)踩过Dubbo坑,回答印象深,干货整理

    小林求职记系列文章,归置到公众号菜单栏,欢迎查看历史篇 前传 小林求职记(五)上来就一连串的分布式缓存提问,我有点上头.... 终于,在小林的努力下,获得了王哥公司那边的offer,但是因为薪水没有谈 ...

  2. 小林求职记(五)上来就一连串的分布式缓存提问,我有点上头....

    小林求职记系列文章,归置到公众号菜单栏,欢迎查看历史篇 前传 小林求职记(四)不会吧不会吧,面试还真会问这些呀 在之前王哥的辅助之下,小明的简历成功被内推进到了王哥所在公司.由于一面就是王哥自己,所以 ...

  3. 小林求职记(三)一上来就围绕电商系统层层提问,我太难了....

    前传 面试官:什么是大事务?小林哥:就是 很大...的...事务?? 小林求职记(二):说好的问基础,为啥我感觉一点也不基础呢? 二面的面试官来到来我的跟前,开始对我的简历进行了一番打量然后就开始了技 ...

  4. 小林求职记(四)不会吧不会吧,面试还真会问这些呀

    小林求职记系列文章,归置到公众号菜单栏,欢迎查看历史篇 前传 小林求职记(三)一上来就围绕电商系统层层提问,我太难了.... 经历了好几次求职失败的经历,小林最终找到了自己以前一起工作合作的老同事王哥 ...

  5. 具有软件特色的电子小硕求职记

    十月国庆大阅兵刚过,又到了应届生求职应聘的高峰季节,我也踏上了这趟载着数十万甚至上百万人的大船.简单介绍下:南京211院校小硕,本科非211的,电子类专业,在校期间由于课题和老板项目的原因从事的课题研 ...

  6. 小圣求职记A:腾讯篇

    本人普通985高校计算机专业研究生一枚,从9月12号开始正式找工作,一个月过去了,参加了能参加的各个互联网公司的宣讲.笔试.面试,现用两篇随笔分享所见所闻.随笔A将以腾讯为例详细展示整个过程,随笔B将 ...

  7. 小圣求职记B:总集篇

    1. 搜狐sohu 搜狐在正式招聘前邀请了部分应聘者到武汉研发中心开座谈会(因此简历尽量早投,机会多些),有研发的也有产品的,40人左右,座谈会期间介绍了搜狐汽车.北京研发中心.武汉研发中心和搜狐媒体 ...

  8. Jamie求职记--北邮信通小硕--技术类

    前言:      前些日子看了Steve兄的求职分享帖,写的很好,相信对于将来想从事非技术类的师弟师妹们,一定有很大的积极作用.      相信我们09级的同学们很多人还记得07级信通院求职交流会中大 ...

  9. 大脑门儿求职记——我的求职经历完全记录

    [写在前面的话]          从2009年7月初开始准备找工作,到12月底正式签约,递交三方,漫漫求职路走了整整六个月.在这六个月的时间里,我经历了人生迄今为止最为丰富多彩而又跌宕起伏的难忘时光 ...

最新文章

  1. java makefile jar包_java makefile学习实践(编译的javac命令写在makefile中,运行命令java写在shell脚本中)...
  2. 一步一步学Ruby(九):Ruby正则表达式(上)
  3. 爱情,没有对不起;只有不珍惜……[
  4. query判断值是否为空,针对前台提交数据的校验
  5. php socket非阻塞,php stream_set_blocking设置非阻塞模式,php stream_set_blocking影响函数fgets()和fread()...
  6. 【Linux】——常见的rc的含义
  7. 2018年工业机器人销量排位_2020年全球工业机器人现状与竞争情况 中国为全球最大供应国...
  8. mysql 输出解释怎么看_了解MySQL中EXPLAIN解释命令
  9. uva 10934—— Dropping water balloons
  10. word交叉引用插入文献后更新域之后编号未更新
  11. 理解SVN中trunk,branches,tags
  12. salesforce 架构设计_关于Salesforce证书维护重要通知
  13. Linux服务器启动流程详解
  14. 为什么黑客都用python-黑客编程为什么首选Python语言?这里告诉你答案!
  15. Oracle CRS/ASM/RAC版本兼容对应表
  16. 从上往下打印二叉树(C++)
  17. use MSAgent in C#
  18. html超链接访问前颜色,html超链接颜色设置
  19. Spring为什么需要使用三级缓存?
  20. win10 ODBC数据源32位没有Microsoft Access Driver(*.mdb,*accdb)

热门文章

  1. 坑哭了!老牌教育机构也崩盘,疑失联跑路,学员却还得继续还贷
  2. 支付宝上线新功能:家长们放心了!
  3. 《哪吒》票房超25亿元 进入中国电影票房总榜前十
  4. 投资快手近尾声 腾讯持股超30%将置入资产或资源
  5. 美团王兴:互联网下半场基本功不过关 活下去都很难
  6. java tts引擎_让Java说话-用Java实现语音引擎
  7. 智慧讲台:office 文件 pdf 文件 转成 png图片
  8. python断点调试出现问题_Python错误、调试
  9. 嵌入式Linux入门8:rootfs移植
  10. 再识PCI:一个PCI驱动实例