1.项目主要实现了哪些功能?
本项目是专门为校园食堂窗口定制的一款软件产品,包括系统管理后台和客户端两部分。其中系统管理后台主要提供给食堂内部员工使用,可以对餐厅的菜品、套餐、订单、员工等进行管理维护。客户端主要提供给学生及校职工使用,可以在线浏览菜品、添加购物车、下单、支付、催单等。
2.Nginx反向代理
(1)引入
问题:前端发送的请求,是如何请求到后端服务的?
答:利用nginx反向代理。
(2)nginx反向代理
nginx反向代理:将前端发送的动态请求由 nginx 转发到后端服务器。
(3)好处
- 提高访问速度。(nginx可以缓存,当请求相同的接口地址时,可以在nginx将数据响应给前端,而无需再访问后端服务器)
- 进行负载均衡。(负载均衡:就是把大量的请求按照我们指定的方式均衡地分配给集群中的每台服务器)(没有nginx,前端—1个后端服务器;有nginx,前端—多个后端服务器)
- 保证后端服务安全。(后端一般不对外开放,在公司的局域网(内网)下)
(4)配置方式
nginx反向代理的配置方式 | |||||||||||||
nginx负载均衡的配置方式 | nginx负载均衡策略:
|
(5)nginx正反向代理的区别
正向代理 | 反向代理 |
代理的对象是客户端 代替客户端去发送请求 | 代理的对象是服务端 代理服务端接受请求 |
客户端架设的 | 服务端架设的 |
保护客户端免受潜在的网络风险和威胁 | 保护原始资源服务器免受高并发方法等造成的过载问题 |
proxy和client同属一个LAN,对server透明 | proxy和server同属一个LAN,对client透明 |
3.MD5密码加密
- MD5是信息摘要算法第五代,属于Hash算法一代。
- MD5可以将输入的信息加密转换为128位固定长度的散列值。
- MD5是一种单向加密算法,即不可逆(只能正向加密,无法反向解密)。
(1)为什么要加密?
员工表中的密码是明文加密,安全性太低。
(2)过程
(3)缺点
- 作为一种哈希算法,虽然很难发生散列碰撞,但是经过验证,仍然存在两种不同数据会发生碰撞。
- MD5的安全性:将用户的密码直接MD5后存储在数据库是不安全的。
- 第一,用户普遍习惯用容易记忆的密码(例如:生日、手机号等),攻击者可以将所有密码的常见组合进行单向哈希,得到一个摘要组合(rainbow table),然后与数据库中的摘要进行比对即可获得对应的密码。这也是加盐值的一个原因。
- 第二,直接MD5存入数据库,若数据库被破解,通过MD5反查会查到密码,需要随机盐值的配合。
(4)为什么不可逆?
当MD5的运算过程中出现进位时,进位被直接丢失而不会保存,即MD5的运算过程存在信息丢失。由于不知道运算过程中会有多少个进位在哪一步被丢弃,因此仅仅根据MD5的计算过程和得到的最终结果,是无法逆向计算出明文的。
【面试总结】MD5及加密算法优劣_md5码计算速度有哪些有关-CSDN博客
3.Swagger框架
(1)为什么要使用Swagger?
使用Swagger只需要按照它的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面。
- Swagger是在开发阶段使用的框架,帮助后端开发人员做后端的接口测试。
- Knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案。
(2)使用方式
- 导入knife4j的maven坐标
- 在配置类中加入knife4j相关配置(一个docket方法)
- 设置静态资源映射(一个addResourceHandlers方法),否则接口文档页面无法访问。
- localhost8080/doc/html打开接口文档界面
(3)常用注解
通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:
注解 | 说明 |
@Api | 用在类上,例如Controller,表示对类的说明 |
@ApiModel | 用在类上,例如entity,DTO,VO |
@ApiModelProperty | 用在属性上,描述属性信息 |
@ApiOperation | 用在方法上,例如controller的方法,说明方法的用途、作用(value:可省略) |
4.JWT令牌
(1)定义
JWT(JSON Web Token)是一种用于身份验证和授权的开放标准。它由三部分组成,分别是头部(Header)、载荷(PayLoad)和签名(Signature)。
- 头部(Header):记录令牌类型、签名算法等。
- 载荷(PayLoad):携带一些自定义信息、默认信息等。
- 签名(Signature):用于验证令牌的完整性和可信任性。将header、payload加入指定密钥,通过指定签名算法计算而来。
(2)JWT验证流程
JWT令牌主要用于实现一种无状态的认证机制,定义了一种紧凑且自包含的方式,在各方之间安全的传输信息。主要用于用户首次登录成功以后,服务器会创建一个JWT,将其发回给用户。随后用户的每次请求都会包含这个JWT。JWT使得服务器无需去存储用户的登录状态,从而实现无状态认证。
5.
3.POI是什么?
4.怎么实现微信支付?
5.如果要实现地图定位功能,该怎么做?
6.如何得到销量排名前三的川菜?
7.
8.怎么保证在同时操作多张数据库表出现程序错误时保证数据的一致性?
我在使用多表操作时使用了事务(Transaction):将涉及到的数据库操作封装在一个事务中。在事务中,要么所有的数据库操作都成功提交,要么全部失败回滚,保证了数据的一致性。如果发生异常,可以通过捕获异常并执行回滚操作来保证数据的一致性。
具体操作:
- 在启动类上方添加@EnableTransactionManagement
- 开启事务注解之后,我们只需要在需要捆绑成为一个事务的方法上添加@Transactional
- 这样就把对两张表的操作捆绑成为了一个事务。
9.Redis
问:讲讲Redis,它在你的项目中作用是什么?
答:Redis是一个基于内存的key-value结构数据库,是互联网技术领域使用最为广泛的存储中间件,Redis存储的value类型比较丰富,如字符串、哈希、列表、集合、有序集合等,并提供了丰富的操作命令。
项目中引入Redis的地方是:查询店铺营业状态。在本项目中,店铺营业状态有两种:营业中/打烊。它属于高频查询,只要用户浏览到这个店铺,前端就要自动发送请求到后端查询店铺营业状态。Redis把数据放到缓存中,而不是磁盘,有效缓解了这种高频查询给磁盘带来的压力。
此外,在缓存菜品和缓存套餐中也用到了Redis。用户端小程序展示的菜品数据都是通过查询数据库获得的,如果用户端访问量比较大,数据库访问压力随之增大。---->系统响应慢、用户体验差---->通过Redis来缓存菜品数据,减少数据库查询操作。
问:在你的项目中Redis作为缓存,MySQL的数据如何与Redis进行同步呢?(双写一致)
答:在本项目中,用户在查看店铺营业状态时,需要让数据库与Redis高度保持一致。因为如果店铺没有营业的话就不能点单了,所以它要求实时性比较好,所以采用redisson实现的读写锁保证的强一致性。在读数据时添加共享锁,可以保证读读不互斥,读写互斥。当更新数据时添加排他锁,它是读写、读读都互斥,这样就能保证在写数据的同时不会让其他线程读数据,避免了脏数据。这里需要注意的是读方法和写方法上需要使用同一把锁才行。
问:这个排他锁是如何保证读写、读读互斥的呢?
答:排他锁底层使用的是setnx,保证了在一个时刻只能有一个线程操作锁住的方法。
问:你听说过延时双删吗?为什么不用它呢?
答:延时双删,如果是写操作,先把缓存中的数据删除,然后修改数据库,最后再延时删除缓存中的数据。其中这个延时多久不太好确定,在延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。
问:如何解决Redis的缓存穿透问题?
答:缓存穿透指查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库,可能会导致数据库挂掉,这种情况大概率是遭到了攻击。
在本项目中,使用redisson实现的布隆过滤器来解决缓存穿透:它主要是用于检索一个元素是否在集合中。它的底层主要是先去初始化一个比较大的数组,数组中每个单元只能存储二进制数0或1,一开始都是0。当一个key来了之后经过3次hash计算找到数组对应位置,然后把数组中原来的0改为1,这样的话,3个数组位置就能表明一个key的存在。查找的过程也是一样的。但布隆过滤器可能会产生一定的误判,可以设置误判率,大概不会超过5%。其实误判是必然存在的,要不就增加数组的长度,5%以内的误判率一般的项目也能接收,不至于高并发下压倒数据库。
问:Redis的淘汰机制是怎么样的?
答:数据的淘汰策略,是指当Redis中的内存不够用时,此时再向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。
Redis提供了多种数据淘汰策略,默认是noeviction,不淘汰任何key,但是内存满时不允许写入新数据。还有随机淘汰、LRU(最近最少使用)以及LFU(最少频率使用)等。
问:Redis的IO多路复用是什么?
答:Redis的IO多路复用是一种技术,允许Redis同时监听多个客户端连接,并在有数据到达时及时处理,提高了IO效率和性能。它通过一种机制来管理和处理多个连接,使得Redis能够高效地处理大量客户端请求。