自我介绍+项目介绍:5分钟左右;
是否能够接受使用Go语言来进行后端开发?可以。
说一说对实习期间的一个基本期望;
在介绍项目的时候提到了一些安全问题,简单介绍一下安全问题:预约挂号号源数量并发修改的超卖问题,分布式项目中可以考虑使用Redis的分布式锁来解决,单体项目可以考虑直接在后端加锁来解决;
这里考虑的是代码的业务逻辑方面的安全问题,其他的关于安全的比如SQL注入有考虑过吗?MyBatis、MyBatis Plus解决SQL注入问题;
能讲讲它们的基本原理吗?不太清楚。
主要是对用户的输入做一个转义,比如特殊字符或者语句加上单引号等等,除了SQL注入问题还有其他想到的要注意的问题吗?基于无状态思想的JWT登陆信息,Token泄露;
除了JWT之外还了解哪些登录的手段呢?Session存储,适用于单体项目,不适合单体登录;
能简单介绍一下Session的原理吗?不太清楚;
那你了解Cookie吗?Cookie强调客户端存储,Session强调服务端存储;
给个提示,其实Session本质上是基于Cookie的,只不过存储的一段乱码,你能推测一下它的基本原理吗?回答浏览器的本地缓存,面试官可能觉得我不太懂这个方面的,换话题了;
项目中提到Mysql数据库中有一条id为1且value为10的记录,同时有多个线程进行一个select and update的操作,可能会造成号源超卖的问题,能否复述一下你提到的解决方案?分布式项目中可以考虑使用Redis的分布式锁来解决,单体项目可以考虑直接在后端加锁来解决;
你认为Java的这种synchronized锁是加在哪里的?讲述了一下锁升级以及它的基本原理;
所以你认为它是加在服务器端的是吗?是的。
那你有了解数据库的隔离级别吗?了解,四大基本隔离级别和解决脏读、丢失修改、不可重复读。
说一说多条SQL语句同时对同一条记录进行修改,MySQL如何保证数据安全?表锁和行锁,CRUD操作会对表加DML读锁,同时对记录添加写锁。
那你能介绍一下行锁的多种类型吗?不太清楚。
那你能介绍一下在可重复读隔离级别下可能出现的幻读情况?记不太清楚具体的概念了。
那你能说一下读未提交和读已提交这两个有什么区别吗?通过举例来说明。
也就是说脏读就是针对一个记录,一个事务在查询一个事务在更新,那么在读未提交的情况下,就会导致事务开启之后还未提交造成的更新影响别的事务的查询,而读提交就解决了这个问题,那么你能再说说读提交有什么问题而可重复读隔离级别又做了什么改进吗?以转账功能为例说明可重复读问题,提到了MVCC机制。
那么事务又怎么知道在MVCC机制下哪些数据能读哪些数据不能读?事务开启进行快照,维护列表。
MVCC你能简单描述一下吗?多版本并发控制,同一条记录多个版本(感觉和上一个问题重复了),从记录对应的事物id开始重新讲了一遍;
那你再说一下可重复读情况下建立了一个read-view但是此时数据库中存储是最新的数据,那么它是怎么拿到老版本的数据的?undo log的回滚操作。
又回到了当初那个select and update案例,如果不依赖后端锁和分布式锁那么如何通过MySQL本身来解决这个问题?答存储过程?
和存储过程没什么关系,那么你select for update语句了解吗?相当于给select语句加了写锁那么就会触发“当前读”;
所以说通过这个机制就会加行锁能够得到最新的值从而解决select and update案例,就不需要通过服务端枷锁和分布式加锁,后端的原则是能不引入中间件就不引入中间件,这边有听说过间隙锁吗?不太清楚;
Mysql的聚簇索引和二级索引的区别?前者针对主键构造,存储所有字段,后者针对其他字段存储的主键,查询需要进行回表。
比如一个表有三个字段 需要进行where a=x and b=y and c=z 且业务逻辑必须会先查a,那你会怎么建索引?通过索引覆盖的操作构造(a,b,c)联合索引同时采用自增主键作为聚簇索引。
基本是正确的,那么你能说一下通用场景下为什么需要使用自增id而不是其他情况来作为聚簇索引吗?能够使得二级索引的存储开销更小,删除后带来的页分裂和表重建会更方便。
所以涉及插入其实会不断加到数据页末尾能够减少页分裂,那么为什么id需要尽可能小呢?回表机制...被打断了;
假如只有聚簇索引没有二级索引即不考虑回表?不太清楚。
其实是因为IO操作的性能问题,id比较小那么同一个数据块读取出来能够获取更多的数据,下面问一下进程间通讯的一些方式有哪些呢?互相不知道、通过共享变量间接知道、信号量、管程。
你提到共享变量,那么是如何实现的呢,你要知道进程间空间是隔离的?数据访问的互斥性,CAS操作来对共享变量进行操作;
那么这个共享变量是放在哪里呢?Emmm
那我们换一个问题,你了解虚拟内存吗?简述了进程映像和内存的关系,可以基于分页分段等机制,局部性原则,高并发性。
我们知道其实内存区域是分别给到用户态和内核态的,基于这个提示你再回答一下共享变量是放在哪里呢?操作系统的常驻集概念,可以考虑将存储在内核态。
4G中1G的空间基本都是给操作系统用的,所以这一部分的空间其实是共享的,还有一种方式是共享用户态内存的方式,结合你刚才说的分页机制,你来说一下怎么共享的?不太清楚。
能简单说一下分页机制的原理吗?每个进程对应一个页表,通过页来映射页框。
所以访问虚拟地址应该如何找到实际的存储地址呢?找到页框Page Frame之后加上偏移量找到具体的地址。
所以基于这个分页的机制,两个进程能否共享用户态内存呢?可以通过将不同进程中页表里的页同时映射到物理内存中。
信号你听过吗,不是信号量?不太清楚。
Linux有用过吗?只是用过。
怎么查询现在的进程?top。
得到pid之后该怎么干掉这个进程呢?kill。
kill后面可以加一个参数,比如9或者15,你知道这个参数是什么意思嘛?不太清楚。
本质就是一个信号,一开始kill命令是为了干掉进程而出现的,后来kill命令就变成一个发信号的命令了,本质是向进程发信号,需要进行信号处理函数,比如signal_user,信号是唯一一个异步的进程间通信的方式,通过注册回调函数的方式来完成异步通信,听说过回调函数吗?前端Axios/Ajax请求。
为什么前端JS,Node.js会大量使用回调函数?提高并发量,降低阻塞。
为什么前端一般要用异步处理IO操作呢?单纯提供并发量...
因为它们其实是单线程的一些操作,至于为什么是单线程其实也是为了避免上下文切换和一些资源共享不安全问题。
算法题:链表判环;数据流TopK
#面试##实习##JAVA##后端#