维思akulaku_041127

24 年 11 月 27 日 星期三 (已编辑)
3807 字
20 分钟

先说一下录屏的软件OBS
录屏之后 问题确实复盘更详细了 但复盘时间也变久了(

12月3号更新 周末就收到感谢信了 不到四天(

一面

自我介绍

和ieg差不多

介绍一个能代表你能力的项目,包括架构和业务流程

被问这个问题 可能就是自我介绍有些不够清楚吧...
介绍了一下肺音诊断系统,基于spring boot,数据存储有使用到mysql、redis和mongdb,其次还有nacos远程管理项目配置,minio处理文件上传等
业务背景和流程:背景就是应用老师的一个降噪算法,用户通过设备录音,设备会对音频进行降噪,接着用户上传自己的音频,我们的平台会用ai分析音频并得出一些结论,还有一个医生角色,用户可以和医生实时沟通,得到进一步的诊断(基于goeasy 底层仍然是websocket)

这个项目的注册登录流程

这个项目只能通过邮箱注册,登录可以通过邮箱+验证码和邮箱+密码

登录之后如何鉴权

通过JWT(Token)

可以说一下JWT鉴权的原理吗

jwt生成token时,会有载荷,可以存入用户的id或者用户名等可以标识用户的东西
之后呢?如果B知道A的用户名和id,那B直接传A的用户名和id就可以冒充B了呀

(这里没有想明白面试官要问啥 就重新介绍了一下JWT生成token和验证token的过程 实际上问这个问题是因为我上一问没有提到jwt对信息hash)
用户成功登录,jwt会通过加密算法生成一个token,这个token可以认为是带着登录用户的信息(id和用户名之类的)

用的什么加密算法
sh256 对称加密(猜的 实际上是HMAC SHA256 或者 RS256 )

非对称加密不能解密吗
问这个问题是因为 我当时原话是这种可以存入也可以拿出 应该是对称加密 如果存入不能拿出 应该就是非对称加密吧
面试官发现了我这个盲区 问我这个问题

我当时回答的是不能...(是可以的!!! 只有私钥可以解密)

复盘补充

的确找到知识点盲区了 没想多对称加密和非对称加密的区别都忘记了
对称加密和非对称加密本质的区别应该是解密的秘钥不同
对称加密使用一个秘钥加密和解密
非对称加密使用公钥和私钥加密和解密,公钥是公开用于加密的,被公钥加密的数据只有私钥才能解密
对称和非对称实际上对应的应该是加密的秘钥数量和解密的秘钥数量 对称加密中加密秘钥和解密秘钥都是同一个 所以是对称 非对称中加密和解密不是一个 所以是非对称

假设黑客B通过抓包,获取了A的token,并将token放在自己的请求头中,去请求A的隐藏信息,如何应对

首先明确,B拿着A的token,服务器没有别的防范措施,就会认为B是A
然后我就开始发表暴论:让每个人的请求除了token之外,还要再带上自己的id或者用户名
当时的想法就是要验证请求人的token和请求人的信息是不是对应的 但说完面试官就指出来说黑客是通过抓包的 因此A传输的id或者用户名黑客也能获取 这个方法无效

接着我就开始扯皮说 我们写程序的时候就认为token被安全保护,别人不能获取之类的...

了解https吗

在http的基础上加一个安全验证(面试的时候相关概念忘记了 是SSL)

https是如何解决刚刚说的问题的

当被问这个问题时,才意识到刚刚面试官讲的实际上是经典的中间人攻击

然后开始介绍HTTPS的原理
假设A是一个正常的用户 S是服务端 B是中间人(黑客)
A有一个公钥和私钥 最开始A先将自己的公钥发送给S,S收到公钥后,通过A的公钥加密要发送给A的数据,接着向A发送加密后的数据
A收到加密的数据后,通过私钥解密数据
B通过抓包 只能看到A的公钥 和S发送的通过A公钥加密的数据 因为没有A的私钥 因此不能看发送的原文
这就保证了安全性

有没有想过A的公钥怎么给S?JWT是如何避免或者减少这种问题的?

面试管强调了一下这个过程很复杂 然后问我项目中的jwt是如何应对这个问题的
想了好久 开始不敢说了 想着糊弄过去就说开发的时候没有想过这些问题
面试官放弃治疗 说你项目中已经用到这个了 虽然jwt没有做到100分但是也尽力去避免这样的事情了
又想了好久 想到了jwt的过期机制
面试官点头表示认可 补充说抓包需要时间 jwt过期后就无效 虽然没有根本解决 但也防范了一点
(但实际上 我记得我们项目jwt的过期时间好像是几个小时( 希望可以遇到抓包需要几个小时的黑客 让我们项目的jwt起到一点作用)

如何验证Token是合法的

回答的是 首先验证token是不是能取出来字段 如果取不出来肯定不合法 取出token负载的字段 然后查数据库看有没有这个数据 如果有就是合法的

你项目就是这样做的吗?

回答是的 面试官说如果这样使用jwt和一个用户直接返回id和用户名有啥区别
我回答说 如果不用jwt 那一个人随机猜id和用户名 猜对了就可以冒充了
面试官又说我现在说的办法也可以冒充(听到这里我意识到之前jwt又没说清楚)

负载用的什么加密算法 jwt有哪些组成成分

再次回答sh256 成分没回答全 说是有负荷、过期时间 面试官问过期时间在哪里
我回答说作为信息的一部分 存入token
然后面试官让后面自己再了解一下

复盘补充

jwt由Header(头部)、Payload(负载)和**Signature(签名)**组成
检验合法 更关键的是验证签名
关于算法 使用的是RS256或者HMAC SHA256

redis做什么

验证码缓存 接口防刷

接口防刷的问题场景和如何解决

(一个坑不能跳两次)
goeasy的访问量如果小于一个阈值 就不会收费 本着减少成本的原则 就想着限制短时间内多次访问
spring的拦截器实现一个记录缓存 每个请求在访问前将请求的ip和访问的方法 如果在缓存中不存在 就将ip和访问方法作为键存入redis 值置为1 下次遇到这个请求 如果在redis中 那就把存的值加一 当某次访问发现这个键对应的值大于一个阈值之后 就把禁止这个请求访问 因为redis的键我们有设置过期时间 如果这个时间内缓存没有消失 就说明短时间内这个ip请求这个方法超过了阈值次

为什么用redis 不用底层数据结果 比如hashmap

(还是一个坑不能跳两次)

两点原因 第一点因为我们邮件验证码用的是redis存 其次就是如果后期有扩展 多台服务器提供服务 使用内存就会出现问题 redis相对更加统一独立一些

能不能放在数据库?

(新坑 可以跳) 磕磕绊绊回答说 因为前面涉及到计时 定时主动地从数据库删除一条数据相对麻烦 redis自动过期方便一些

还有其他原因吗?你如果都使用mysql,redis甚至可以不需要

回答说 因为这个数据实际上是以键值的形式存储的 将ip和方法名作为键 一个数字作为值 mysql作为关系型数据库不是很适合
然后又说直观上感觉redis更适合之类的...

然后面试官说不要凭感觉,我们搞技术的要说理论,所以再问更重要的原因是什么
没回答出来就下一个问题了

项目有使用到事务的场景吗

耳机或者耳朵有问题 事务听成失误了(
然后他说innodb的事务 我才反应过来 这里真绷不住了
回答说项目比较小 没有使用到事务

java中如何实现事务

回答说有使用到通过注解来完成的事务 用注解修饰一个方法 当这个方法出错时就回滚

为什么添加了注解就能实现?原理是什么

回答不清楚 i o i

hashmap底层如何实现

宏观来讲 hashmap就是一个hash表 再底层就是一个数组(hash表是数组)
然后每个节点没有冲突就是一个节点 发生了冲突就是一个链表 当节点个数大于阈值(默认为8)就会变成红黑树

为什么会由链表变成红黑树
链表查找数据是O(N) 变成红黑树可以简化查找效率

为什么红黑树可以简化效率 如何简化的

难绷 红黑树没记(

如果让你选择替换链表的数据结构 你选择什么

链表之所以查询是O(N) 是因为不支持随机查询 然后就回答了支持随机查询的数组 而这里使用树是因为树的空间利用率更高

你用数组?数组里再套一个数组吗?怎么实现?

(听到这里感觉就打错了 不应该回答数组) hash的数组存内部数组的指针,在插入时就维护成有序或者维护成分块查询
在说到插入的时候就想到了数组插入是o(N) 然后慌张的说数组不行 因为插入太复杂

数组不行 那用什么 说关键原理

平衡搜索树 维护平衡的原则 在插入一个节点的时候 检查每个节点的左右子树深度差有没有大于等于2 如果有就扭一下(没看错 我面试的时候真说的是扭一下) 大概流程是 假设现在插入一个节点后有一个节点的左右字数深度差大于2(左为1 右为3) 这时候选一个新的根节点 比如这个例子就是根节点右子树的第一个节点 抽象来说 重新选一个节点让树的左右深度差小于2

那相比链表 平衡搜索树查询插入优化在哪

搜索树符合一个规则 根节点左边都小于根节点的值 右边都大于 这样在查找或者插入就像二分一样

ArrayList底层结果

回答说底层和vector一样 当元素数量大于容量 就找一个新的数组 把原来的元素复制到新数组 新数组的容量是原来的两倍

为什么不用原来的数组?这样就不用复制了

因为数组空间是连续的 如果新扩容的空间有存储数据 就会出现冲突

为什么数组的地址空间是连续的 这样的好处是啥

如果不是连续 那数组就和链表一样 不能随机访问

为什么连续就能随机访问?

因为数组元素的大小都是一样的 比如存储的int 那每个元素都是4字节 只要找到第一个元素的位置 然后偏移数*4就能找到目标元素

线程池的几个关键参数

(破防了捏 不会) 就说了一个最大线程数 不知道对不对(

你认为java基础需要了解的有哪些?

(绷) 说了线程 各种集合类 反射啥的

面向对象特性和设计原则

继承 封装 多态
单一职责原则

什么样算是多态

java有两个方法 一个是用父类指针指向子类 还有就是接口指针指向实现

一个父类 两个子类 arrayList中全是这个父类的指针 怎么知道是哪一个子类?

懵了 多态不就是这样吗

指针具体是什么 在java中

栈空间的一个值 指向堆空间的对象

多态的意义是什么

多态意义就是 通过指针抽象出一些类共同的方法和属性

线程周期有了解过吗

有了解的 前几天还看 但我说的有点磕磕绊绊面试官就问下一个问题了

怎么启动一个线程

回答了三种方法 一个类继承thread类 重写run方法 java中只支持单继承 继承了thread就不能继承别的类 所以这个方法不常用
实现thread接口 重写run方法 比较通用 假设A类实现了接口 启动线程就需要实例化一个A 并将A作为参数传入Tread类 然后调用这个Tread类的start方法
Callable方式 支持泛型 这种有返回值 可以返回和泛型同类型的返回值 并且可以抛出错误 (到这里就被打断了)

反问阶段

刚刚的表现

说我在面对自己不会的问题时有独立思考的能力(是因为不会的问题太多了吗i o i

做一个项目 使用到了一些组件但不知道具体原理 比如刚刚的jwt 你用了jwt却不知道jwt解决了什么问题 也不知道剩下了什么问题需要继续去考虑

java基础 有些知识点掌握不够

结果什么时候出

一周内

总结

继续看八股吧 多线程这方面是真短板
其次jwt等一些组件的原理还要再看 没想到面试的时候把签名忘了 不应该的
给我的感觉就是 除了眼睛都全副武装的欧洲士兵 刚出门眼睛就被射了一箭(

文章标题:维思akulaku_041127

文章作者:Blank

文章链接:https://blankxiao.github.io/posts/%E9%9D%A2%E7%BB%8F/%E7%BB%B4%E6%80%9Dakulaku_041127[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。