首先,可以设置图形验证码,流量错峰
其次,可以获取请求的ip地址,手机号,发送时间,并保存到发送短信记录的日志中,对于短时间多次请求的ip地址,手机号,可以拦截不执行发送手机验证码
再次,可以设置单位时间内发送短信的总数量,比如设定1秒最多只发送10条验证码。但这种方式会降低并发性
使用Nginx+Lua也可以做防刷,和黑名单
非对称加密,什么是数字签名非对称加密是一种算法,指的是加密和解密时使用不同的密钥,叫着公私钥
数字签名就是在非对称加密的基础上,使用私钥加密,公钥解密,主要用来防止数据被篡改,实现安全传输的目的
Oauth2的四种授权模式oauth协议是一个安全的开放授权标准,与传统的授权方式相比,它不会使第三方触及到用户的账号信息,比如用户名,密码。Oauth2有四种授权模式
一、授权码模式,它是功能最完整,流程最严密的授权模式
二、简化模式,直接从前端渠道获取token,容易受安全攻击
三、用户名密码模式,使用用户名和密码登录的应用,比如桌面APP
四、客户端凭证模式,用户直接向客户端认证,客户端以自己的名义向第三方索取服务
要求每天早上 1点统计前一天的平台注册人数,怎么做使用定时任务每日结算即可。把结算的数据保存到一个统计表中
使用Quzrtz定时任务做订单超时关单有什么问题有两种方式,一是使用一个定时任务扫表,这种方式在数据量大的时候,定时任务扫描表性能会很差,而且多数都是空扫描,还有延迟问题。二是一个订单一个定时器,指定一个关单时间,但是这样的话并发高的时候会产生很多的定时任务,影响服务器性能。
对于我们的小型项目,数据量少,可以使用quartz定时器,使用起来也很简单方便,但如果是数据量大,可以使用RabbitMQ的延迟队列来实现,也可以使用Redis来做延迟队列。
讲一下你做过的比较复杂的业务省略…
什么是RBAC , 相关表怎么设计的?RBAC:Role-Based Access Control首字母缩写,意为基于角色的访问控制。基本思想是对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合。
将权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
实现RBAC,需要将用户对权限的多对多关系,转化为用户对角色,角色对权限的多对多关系,因此在数据库中,需要在用户,角色,权限中分别加入中间表,即用户表,用户和角色关系表,角色表,角色和权限关系表,权限表
在VUE中,什么是MVVMMVVM,Model–View–ViewModel首字母缩写,是一种软件架构模式。
其中Model指的是模型,包括数据和一些基本操作
View指的是视图,页面渲染结果
ViewModel指的是模型与视图间的双向操作
MVVM的思想就是数据模型和视图的双向绑定,只要数据变化,视图会跟着变化,只要视图被修改,数据也会跟者变化
讲几个VUE的指令v-text:给元素填充纯文本内容
v-html:给元素填充内容,与v-text的区别是它会把内容的html符号进行渲染
v-for:遍历数字,字符串,数组,对象
v-bind:将data中的数据绑定到标签上,作为标签的属性
v-model:创建双向绑定,表单的值被修改时会自动修改data中的数据,data中的值变化时页面也会被修改
v-show:根据表达式的真假值,切换元素的css属性
v-if:根据表达式的真假值,销毁或重建元素
v-on:绑定事件
webpack的作用VUE项目需要打包后才能部署
首先,它可以将ES6等高级语法,编译成各个浏览器都认识的语法
其次,它可以将相互依赖的许多散碎文件搞成一个整体,提高网页访问的效率
再次,它可以将代码压缩,减小代码体积
Vue中定义组件分为几种,有什么区别组件是一种自定义的元素标签,可以对功能封装,提高代码复用性,分为全局组件和局部组件两种
- 全局组件,是在所有vue挂载的标签中都有效,
- 局部组件,只在当前vue所挂载的标签中有效
基础组件,比如按钮Button,图标Icon
表单组件:比如表单Form,单选框Radio,多选框Checkbox,输入框Input,选择器Select,级联选择器Cascader
其他组件:比如Dialog对话框,消息提示Message
你们Redis做登录是怎么处理登录信息过期的?给保存在Redis中的token设置过期时间来处理登录过期的,为了防止已登录用户在访问后台时突然遭遇登录过期的情况,我们在后台接收到用户访问时,重新设置token的过期时间写入Redis,则用户访问期间就不会突然过期了
讲一下你们的登录实现方案当用户第一次发起登录请求,后台生成一个token保存到Redis中
将生成的token返回给用户端
用户端使用用浏览器中的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端,浏览器端
第四,分开部署,减轻了服务器压力
第五,页面显示东西再多也不怕,数据都是异步加载,就算后端服务器挂了,前端页面也能访问,虽然没有数据
第六,前端分离出去,后端写一套接口就可以适用于web,app端
你们用什么做项目代码管理的使用主流的Git管理项目
讲讲Git相对于SVN的区别第一。Git是每个攻城狮都有自己的版本库,可以在自己的库上任意操作提交代码
第二。Git在每个工程只产生一个.git目录,而SVN会在每个目录下都生成.svn目录
第三。Git能快速切换分支,且合并文件的速度比SVN快
第四。Git采用分布式版本库,内容完整性更好
你们微服务项目怎么部署docker 容器 ,使用Jnekins做持续集成。
讲几个Git的命令git clone:从远程仓库克隆项目到本地
git add:添加代码到本地仓库管理
git commit:提交add后的代码到本地仓库
git push:推送本地仓库文件到远程仓库
git pull:拉取远程仓库中的代码到本地仓库