1,如何避免订单重复提交和支付?
1.前端防抖处理: 控制100毫秒以内,同一个用户最多只能做一次提交订单的操作。
2.后端生成Token:保证每次调用后端接口获取的token唯一,将token存到Redis缓存中,一个订单对应一个token,每个token只能使用一次,用完即删,另外给token设置一个失效时间,将超时token也废除,当后端接收请求时,判断token在后端中是否存在,第次请求会正常返回,返回结果也会将token删除,而后续再携带相同token访问,会被服务器直接拒绝。
1.注意:如果是同一个token同时发起多个请求,服务器只会响应其中一个请求,其他请求都会被拒绝服务。
2.实现原理:使用分布式锁和Lua脚本,分布式锁保证同一个token不能被多人请求同时来访问,Lua脚本保证从Redis中获取的令牌生成对应订单号,删除令牌等操作,保证原了性。
3,支付等外理:主要是为了防止同一人订单被支付多次,通过分布式锁来保证同一人订单同一时间外理,其次还需要验证订单的状态操作防止重复提交。
1.注意:需要防止卡单,即前台一直等不到支付结果,同时保证支付幂等性,需要有一个主动查询机制,比如限制第三方支付,必须在5秒内回复,否则主动发起一个查询请求去查询支付状态,根据查询结果来更新订单状态。
2,Integer和int的区别? Java为什么要封装类?
区别:
Integer的初始值为null,int的初始值为0。
Integer存储在堆内存中,int直接存储在栈内存里面。
Integer是一个对象类型,封装了很多的方法和属性,int是一个基本数据类型。
原因:lava本身是一个面向对象的语言,一切操作都是以对象作为基础,比如说像集合里面存的元素也只支持存储Obiet类型。
3,说一下JWT 认证流程?
用户输入用户名/密码登录,服务端认证成功后,会返回给客户端一个JWT
客户端将 token 保存到本地 (通常使用 localstorage,也可以使用 cookie)
当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加]MI,其内容看起来是下面这样:
Authorization: Bearer <token>
服务端的保护路由将会检查请求头 Authorization 中的]WT 信息,如果合法,则允许用户的行为。
因为JWT 是自包含的(内部包含了一些会话信息) ,因此减少了需要查询数据库的需要
因为 JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API服务而不需要担心跨域资源共享问题(CORS)
因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制
4,Token 和JWT 的区别?
相同:
都是访问资源的令牌
都可以记录用户的信息
都是使服务端无状态化
都是只有验证成功后,客户端才能访问服务端上受保护的资源
区别:
Token: 服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。
JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是JMT 自己实现的)即可,不需要查询或者减少查询数据库,因为JWT 自包含了用户信息和加密的数据。
5,Redis会存在线程安全问题吗?
Redis Server本身是一个线程安全的K-V数据库,也就是说在Redis Server上执行的指令不需要任何同步机制,不会存在线程安全问题。