250313面试回顾
今天面试的效果比较差,题目更多偏源码或者底层一些,回答的不是很好,趁着题目还有印象,做个记录
1、多线程的理解和应用场景
线程区别与进程,是颗粒度更小的运行单位。进程内可以有很多的线程,同样,线程内也可以再启动线程,线程是共享进程的资源。
多线程的并发运行其实是CPU顺序执行,哪个拿到了CPU资源就可以执行,当CPU运行速度快到一定程度,可以等同于并行
哪些地方会用到线程
总体来说,线程还是为了提高CPU资源的利用率,一方面提高执行时间、快速的共享资源使用,线程之间的便捷通信等,提高业务的响应速度,
1、加快流程进度:
这里拿之前业务举个例子,车辆注册涉及到的业务流程比较长,可能包含1车辆、2车载设备、3SIM卡的新建,4车辆扩展业务,5终端绑定协议等等。就拿这几步来说,如果顺序执行就是123456...这样,当时当123数据新建完成后,4的业务只需要车辆,5的业务只需要终端新建成功即可。那么4和5就可以同时执行。且对于用户来说,车辆的注册功能,前台只关注数据新建和绑定即可。
这个时候,4和5就可以通过启动子线程的方式在后台运行,一定程度上就可以加快注册流程的响应速率。
2、批处理:
其实这个也是为了提高执行效率。当数据量比较多,主线程循环处理慢的情况下,就可以每一批启动一个线程分别进行处理。
3、简单通信
睡眠:比如我们想要对线程在运行到某个节点暂停等待,可以指定睡眠时间。
阻塞唤醒:一个线程执行到某个节点时,可以通过wait方法暂停进入阻塞,然后释放CPU资源,在他的依赖线程完成后,通过notify方法唤醒后再继续执行。资源共同使用
4、复杂通信
等待执行:还是刚才例子,假如还有一个业务6,他需要前面5个都执行好之后,才能执行。顺序执行123456就可以,还有一种就是可以创建一个等待器,标记个数为6,业务6只能等标记数到0才能执行。前面的每个业务块一个线程,执行完成后进行标记减一,这样业务6在数据到0的时候才能执行,也就意味着业务6需要等待前面所有线程完成后,才能执行
屏蔽线:大概就是所有的线程到达某个接单都需要暂停等待,当所有线程同时到达后,再同时启动执行。相当于一个起跑线的概念
2、在分布式定时任务里面,如何分配不重复的数据到不同的线程。
这个问题最开始没有提到分布式,先说单体应用是如何分配的。
结合之前写的代码里面,假如定时任务服务只部署了一个节点,那就是单体的。我们在晚上做定时任务处理数据的时候,第一步:先获取数据总量,第二步,计算多线程池每个线程要处理的个数(线程池的大小,根据服务器CPU和核数来定),第三步,逐步获取偏移数据(一般按照时间排序),每组生成一个任务放入线程池。
当单个服务仍然有压力,就多启动一个节点。这里面试的时候紧张没想起来。在分布式环境下。多个服务启动后,我们打开控制台可以看到,每个服务根据注册的时间会有一个索引序号。
在执行任务的时候,当前服务是可以拿到当前服务的序号以及总数的。那么仍然是获取数据总量,然后首先是根据自己的总数和索引号判断自己要执行的数据范围,然后再去逐步从对应的范围起始点获取数据,达到一定数量后生成任务
几个点:1个是先获取总数,2是多部署节点可以在xml中配置总数,3是任务可以从配置中拿到总数以及当前自己的索引item,这几个值就可以将总数分布到不同的机器和线程中了。
3、Mysql的组成
呃,这个问题看过,但是系统性说起来不知道从哪儿说,有些又忘记了就组织不起来,简单说话应该是是下面这几个
1、首先是连接:账密验证,连接管理
2、然后是服务层:这个是对sql做一些工作,分析sql有没有语法错误,优化sql的执行,选择索引?然后执行
3、引擎:涉及到底层的一些运行逻辑和支持的功能吧,现在默认是innodb,支持行锁、支持事务等,MVCC多版本控制等
4、存储:几部分:表数据、索引数据、日志数据(binlog、undolog、redolog等)
4、springboot扩展点?
这个有点不知道该咋答,尴尬了
5、mvc执行流程,有哪些类,怎么处理
model view controller
请求到调度、调度器按照映射器做分发,然后分发到对应的处理器做处理,然后返回到调度器,调度器拿这些给view,生成一个view后又回来调度器,由它再返回给前端展示
再详细的有哪些类,怎么接收到这个请求?每个类干啥的,这个确实想不起来了。先找个图吧

6、sql优化
1、sql本身可见问题的语句优化(复杂sql、尽量用索引?)
2、explian分析
3、合适的索引,呃啥是合适,不是越多越好,尽量在高频字段或者排序字段?不同类型的索引的使用
最左匹配、联合索引、索引下推等知识点
7、分库分表
库
1、分库(应该说垂直分库):实际有应用的就是业务分库,公共库、业务库(不同业务不同库)
2、水平呢:这个真没用过,比如车辆服务,一个车辆库还不够,要建两个车辆库,把数据分散到不同的数据库
表
1、垂直分表:这个说实话挺常见的,就是基础表和扩展表。字段太多了拆一下
2、水平分表:这个其实用过但是用的比较差,回答的时候也说的乱七八糟
就是之前业务上车辆的操作流水太多了,根据业务查一年,然后导出可导出三年,然后历史数据冻结这样的一个需求吧。就是手动多建了几张表。每天的时候通过定时任务,把主表a中当前时间为往前推一年前的数据放到分表a-1里面,同样a-1里面往前推2年的数据放到a-2里面。然后三年前的数据单独存另外一个冷数据表(几乎不需要查询,其实当时业务也没两年,所以没考虑再引入其他库)
这个情况,业务上不管是查当前的数据还是往前推一年的数据,都是查询主表来实现。如果要查三年内的数据,就是比较麻烦些。但业务上这个需求无非就是导出到Excel表中,而且默认也是用时间排序。所以就是查询的时候切时间到不同的库查,可以每一个月一个sheet去导出就行了。
分表的场景确实用的比较少,其他的就是只了解没用过的
比如说分库分表的中间件,什么mycat,shardingjdbc之类的,这个确实只是私下了解,没用到项目上。
然后分表的话,可能建10张表,然后根据主键ID去取模,进行散列存储之类的
分表后如何查询,可能会通过将数据抽取同步到ES去加快查询搜索的效率吧。
不过如果业务上需要多表联合查询搜索的话,也可以通过将数据放到ES,通过binlog自动同步或者手动同步的方式将多表的数据汇总到ES上,查询搜索走ES就行。单表过大,千万级别的数据,单表查询走索引应该也还行吧?这里要深入了解下MySQL的性能