这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
前言
对于在职的我们来说,面试就显得很不方便,所以一般我们都会选择先电话面试,防止对双方的时间浪费,当然了,这也是对我们的基础来一次历练,(勿轻易尝试),毕竟面试才是对掌握的最好检验。
历练
说一下目前负责的项目
公司的业务架构是面向B端的,目前项目负责的是后台管理系统,从入职开始,公司对原有的自研项目进行了重构,正好参与了重构的整个环节。公司所使用的技术栈是Springboot+mybatis,沿用了微服务的架构,采用分布式SpringCloud的框架。
- 为什么使用mybatis而没有使用mybatisPlus
- 各有各的说法吧,毕竟MP是基于mybatis的基础上做增强而不做改变;如果公司内部有封装好的mapper的话,大可以使用mybatis+自己内部封装;
- 有说MP的QueryWrapper很好用,实测真的挺好用的,但是对于部分的coder而言可能需要额外的学习成本,毕竟面向xml的sql是刚需。
- MP忽略了dao层,使service和dao层的概念模糊化,简单的CRUD用的是mybatis,复杂的还是需要自己写sql
关于Netty的使用
在目前的项目中,我负责的车辆管理系统,由公司外购的第三方gps,并作为终端设备通过netty服务上发数据平台+业务处理实现实时定位+历史数据的功能。
-
Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。
-
作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty的NIO框架构建。
关于Redis在项目中的使用
-
在项目中有用到,关于Redis,做短暂的存储
-
有了解Redis的集群吗
Springboot的启动类的注解
-
@SpringBootApplication
标注这个类是属于SpringBoot的启动类,从源代码中可以获悉,这个注解被**@Configuration、@EnableAutoConfiguration、@ComponentScan** 注解所修饰,换言之 Springboot 提供了统一的注解来替代以上三个注解。
-
@EnableFeignClients
加上这个注解,表示这个服务支持调用远程服务
-
@EnableEurekaClient
这个注解是必须的,表示这个注解要注册到某个Eureka服务(注册中心)中,就相当于是给这个服务在一个群里面加了一个通行证,通行证的具体内容就涉及到了application.yml配置文件里面了
-
@MapperScan
上面的那个注解是用来标注扫描dao范围的,这里如果你使用的MyBatis的话,需要通过配置文件来指定Mapper和主要的配置文件的位置
-
手动封装
自己手动写接口,并封装成注解使用
关于一条SQL如何查看运行情况+索引使用
-
先查看sql的建表语句,直接查看创建表的时候设置的索引,并校对索引是否生效或者,是否遵循最左原则
-
使用explain解释函数
- id:选择标识符
- select_type:表示查询的类型。
- table:输出结果集的表
- partitions:匹配的分区
- type:表示表的连接类型
- possible_keys:表示查询时,可能使用的索引
- key:表示实际使用的索引
- key_len:索引字段的长度
- ref:列与索引的比较
- rows:扫描出的行数(估算的行数)
- filtered:按表条件过滤的行百分比
- Extra:执行情况的描述和说明
关于线程池的了解
- 降低资源消耗:通过重用已经创建的线程来降低线程创建和销毁的消耗
- 提高响应速度:任务到达时不需要等待线程创建就可以立即执行
- 提高线程的可管理性:线程池可以统一管理、分配、调优和监控
线程池的参数
- int corePoolSize 核心线程数
- int maximumPoolSize 线程池最大线程数
- long keepAliveTime 线程保持活跃的时间
- TimeUnit unit keepAliveTime 的时间单位
- BlockingQueue< Runnable > workQueue 任务挤压队列
- ThreadFactory threadFactory 线程创建工厂类
- RejectedExecutionHandler handler 拒绝策略
线程池的最大线程数
创建多少线程合适,要看多线程具体的应用场景。我们的程序一般都是 CPU 计算和 I/O 操作交叉执行的,由于 I/O 设备的速度相对于 CPU 来说都很慢,所以大部分情况下,I/O 操作执行的时间相对于 CPU 计算来说都非常长,这种场景我们一般都称为 I/O 密集型计算;和 I/O 密集型计算相对的就是 CPU 密集型计算了,CPU 密集型计算大部分场景下都是纯 CPU 计算。I/O 密集型程序和 CPU 密集型程序,计算最佳线程数的方法是不同的。
对于CPU密集型来说,多线程主要目的是提成CPU利用率,保持和CPU核数一致即可。不过在工程上,,线程的数量一般会设置为“CPU 核数 +1”,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证 CPU 的利用率。
对于IO密集型来说,一般是最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
关于多线程,快的线程先完成,如何等待慢线程一起(除了join方法)
-
在业务使用中,除了使用join方法去实现以外还可以使用其他方法去替代
-
使用CountDownLatch()方法
public class Async implements Runnable { private CountDownLatch countDownLatch; public void setCountDownLatch(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { //业务逻辑 countDownLatch.countDown(); } } public class MainClass { public void call(){ int size=10; CountDownLatch ctl = new CountDownLatch(size); for(int i=0;i<size;i++){ Async async= new Async(); async.setCountDownLatch(ctl); Thread thread=new Thread(async); thread.start(); } ctl.await(6, TimeUnit.SECONDS); //等待多久为超时 } -
由于join方法的底层也是wait()+synchronize同步代码块,所以可以使用这两者去替代。