用户端使用用浏览器中的localStorage保存token
通过axios的拦截器,给每次请求的请求头都加上token
服务端收到token,就能在Redis中找到对应的数据
[](()三方登录流程讲一下
1.用户发起微信登录请求
2.后端获取请求二维码的连接,重定向到扫码界面
3.用户使用微信扫一扫并同意授权
4.后端回调获取授权码,并将授权码作为参数,重定向到前端跳转页面
5.前端将授权码返回后端,后端根据授权码获取token
6.后端根据token获取openId
7.根据openId查询微信用户表
-
如果查到有用户信息,且已关联本地账户,就默认登录
-
如果有查到用户信息,但没有关联本地账户,就跳转本地账户绑定页面,
-
如果没有查到用户信息,就向微信平台发起请求查询用户基本信息,添加到微信用户信息表,再跳转本地账户绑定页面
8.执行绑定逻辑时,根据手机号判断是否有本地账户,如果有就直接绑定,如果没有就自动注册再绑定,绑定成功后就默认登录
[](()讲一下什么是非对称加密,什么是数字签名,数字签名的作用是什么?
非对称加密是一种算法,指的是加密和解密时使用不同的密钥,其中私钥不可公开,公钥可以公开。
数字签名就是在非对称加密的基础上,使用私钥加密,公钥解密,主要用来防止数据被篡改,实现安全传输的目的
[](()如何查询出树状结构的课程分类数据
首先,在entity中加入子分类字段children
查询方式有四种
-
第一,使用嵌套for循环,循环体内查询每一层级的数据,并关联到children。当然这也可以使用递归函数来实现
-
第二,使用mybatis的嵌套查询,也就是主查询加额外子sql查询的方式
-
第三,只使用一次查询,将所有数据查询出来,通过一种算法来实现:除了第一级,其他所有数据都关联到自己的父级分类,结果返回第一级数据就可以
第一,第二种方式,当层级多的时候查询性能极低,第三种方式性能最高,适用于数据量本身并不大但层级很多的场景
[](()你们系统使用Redis缓存了哪些东西?用Redis的什么结构去存储的?
数据字典,用户权限,分类数据等,这些多用String结构存储,购物车保存,使用的是Hash结构
[](()你们项目最大并发是多少
俺们项目是按照最高2000 QPS设计的,实际并发数运维在统计,俺也不太清楚
[](()怎么处理高并发请求
前端优化:
-
使用页面静态化技术由Nginx实现动静分离、
-
CDN加速加快响应速度、
-
使用验证码使流量错峰等手段最大限度的降低并发
后端优化:
-
Nginx+LVS负载,也可以多机房部署,分流
-
从架构上使用分布式、集群分散并发量,
-
从数据结构上使用缓存如Redis减少数据读写时间,
-
从处理方式上采用如RabitMQ队列实现异步响应,
-
资源隔离比如使用Hystrix的信号量隔离来限流,同时做好备用方案比如Hystrix的熔断降级策略等等
[](()讲一下你们的微服务授权方案 你还知道有哪些方案吗?
我们使用的是SpringSecurity+Oauth2+JWT,认证服务器负责颁发token,资源服务器负责认证和授权
或者也可以将认证工作交给网关zuul,资源服务器只负责授权工作。
另外常见的授权方案还有,单点登录,用户只用在某个服务上登录,访问其他服务时就不需要登录了,这就要求每个面向用户的服务都必须于认证服务交互,会产生大量重复的工作
分布式会话,它是将用户认证信息存储在共享容器比如redis中,通常会以会话作为key,当用户访问微服务时,就从redis中获取认证信息。这对安全存储有较高的要求,复杂度高
[](()讲一下你们微服务认证授权的整体流程
客户端访问认证服务器,认证服务器验证用户名密码,然后颁发token
客户端保存token,并且每次访问服务时都携带token
资源服务器接收到客户端请求,会验证token信息,认证通过后返回资源
[](()你们为啥要用JWT
一个字,安全
我们做了认证授权后,每次客户端访问资源服务器,都需要远程调用认证服务器进行token的校验和授权,才能访问到资源。这是很好性能的,因此我们考虑将签名信息直接保存到客户端,那就不需要每次都向认证服务器认证授权了。
但是这有有一个新的问题,这些敏感数据赤裸裸的存到客户端不安全!而JWT就能解决这个问题。它支持非对称加密算法对信息加密,保证了信息安全
另外,JWT以json对象的形式传递信息,解析更方便
可以再令牌中定义内容,方便扩展
[](()Oauth2的授权模式有哪些,分别使用在什么场景?
授权码模式:它是功能最完整、流程最严密的授权模式
简化模式:跳过授权码,直接再浏览器端申请令牌
用户名密码模式:客户向客户端提供用户名密码,建立在用户对客户端高度信赖的基础上
客户端模式:客户端以自己的名义,要求服务提供商提供服务
[](()Oauth2认证,如果Token过期了你们是怎么处理的
首先,我们会在前端设置axios后置拦截,检查是否是token过期,判断一下如果返回401,就代表token过期了
然后从localStorage中获取刷新refresh_token,并发送请求获取新的token
后台接收到前台的刷新token请求,拼接完整的刷新token的url,发送http请求获取到新的token并返回客户端
客户端收到新的token就把旧的token覆盖掉,最后把之前的请求再重新发送一次
[](()Oauth2认证,如果Token被盗了怎么办?
首先,我们需要对token设置过期时间,这个时间可以根据需要设置短一点
然后,可以在token中加入客户身份标识,比如客户的ip地址,如果短时间内ip地址频繁变动,就标记为异常状态,并给用户发送信息,提示账户有风险
[](()秒杀的整体流程详细说一下
秒杀的商品和库存是缓存到Redis的,库存使用信号量,做的是秒杀预减库存方案。用户发起秒杀,直接走Redis秒杀商品,满足资格就预减库存,然后预创订单写入Redis。整个秒杀流程是不做数据罗库的。
此时把订单号返回给客户端,用户带着订单号进入订单确认页面进行下单,用户确认下单,再把Redis中的预创订单写入订单数据,同时做库存同步。紧接着就是调用支付接口做支付。
[](()如果流量更高,比如:每秒10W+请求,应该怎么处理
Lvs+Nginx集群+限流+下游服务集群。如果流量再高,就使用CDN分流。
[](()说一下支付超时处理方案?延迟队列和死信队列是什么意思?
支付超时使用MQ延迟队列来处理,把消息投递到一个设置了过期时间的队列中,达到过期时间消息会被转发给另外一个“死信队列”
设置了过期时间的队列就是延迟队列,过期的消息叫着死信消息,存放死信消息的队列叫死信队列。
[](()整个秒杀流程你用到了哪些队列
下单业务中用到了一个低劣,订单超时用到一个队列,支付结果处理用到一个队列。
[](()秒杀成功,返回给用户的数据是什么?
预创订单号,前台通过这个订单号来进行下单。
[](()你们怎么处理超卖
Redisson分布式锁,信号量来保证库存不超卖
[](()如何提高接口的qps
一方面:提高并发数
1.多线程,尽量用线程池 (线程个数:CPU核数 / (1 - 阻塞系数(IO密集型接近1,计算密集型接近0)))
2.适当调整连接数(Tomcat,Redis,Mysql等连接数)
3.集群
二方面:提高接口响应速度
1.减少和数据库交互,使用Redis代替
2.使用异步方案,比如MQ
3.使用并发编程,多个线程同时工作
4.减少服务的调用链
5.实在要连数据库,考虑数据库优化
[](()你们这个前后端分离项目是怎么部署的
前后端分开部署,前端使用Nginx部署,
后端使用Springboot内嵌的tomcat部署,
分开部署后,通过代理解决前后端域名不一致的跨域问题
[](()前后端分离的好处
第一,专人干专事,前后端同时开发,效率更高
第二,责任分离,避免了前后端相互踢皮球的现象
第三,前后端解耦合,一套后端可以处理不同的前端,包括app端,浏览器端
第四,分开部署,减轻了服务器压力
第五,页面显示东西再多也不怕,数据都是异步加载,就算后端服务器挂了,前端页面也能访问,虽然没有数据
第六,前端分离出去,后端写 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 一套接口就可以适用于web,app端
[](()你们用什么做项目代码管理的
使用主流的Git管理项目