史上最强苍穹外卖话术

前言

这是我集百家之所长和几十次面试千锤百炼最后自己整理得到的话术文档。为什么我要开源出来呢?当然是我自己秋招不会用苍穹外卖了觉得有用的欢迎关注我,点赞本文章和送小红花。

打个小广告:

我手上有个7000多字的轮子项目的话术,需要的可以和我交流学习下

超详细八股笔记和外卖项目话术专栏:https://www.nowcoder.com/creation/manager/columnDetail/j8ZZ

我的八股速成和架构设计专栏:https://www.nowcoder.com/creation/manager/columnDetail/0ybvLm

我的胡言乱语专栏,里面有我想写的小说素材:https://www.nowcoder.com/creation/manager/columnDetail/MVZWqy

专栏质量都挺高的,欢迎大家订阅!

我的简历描述在文章最底下

-------------------------------------

不会有人以为我项目没上线吧?中南美食速递堂堂登场!

-1.项目介绍

中南美食速递这个项目最初是我参与制作的大创项目,是一款为中南学生提供校园外卖送至宿舍服务的软件,包含系统管理后台和小程序端两部分。其中系统管理后台主要提供给食堂内部员工使用,可以对食堂各个窗口、员工、订单、菜品等进行维护管理;小程序端可以在线浏览菜品、添加购物车、下单等,由学生兼职做跑腿送餐上门服务。这是个前后端分离的项目,我主要是负责后端的用户登录、员工管理,菜品管理,订单管理模块的编码实现。

-1 项目部署在哪里?

拆分为前后端分离的项目后,最终部署时,后端工程会打成一个jar包,运行在Tomcat中 (springboot内嵌的tomcat)。 前端工程的静态资源,会直接部署在Nginx中进行访问。

怎么打jar包?

  • 使用命令mvn package(需要服务器安装maven环境)
  • 使用命令cd target/进入到目录就能看到打好的jar包(这里的jar包是ruoyi.jar)
  • 将jar包拷贝到上级目录,防止target目录清理导致jar包丢失

-1.建了哪些表?

每张表的说明:

1

employee

员工表

2

category

分类表

3

dish

菜品表

4

dish_flavor

菜品口味表

5

setmeal

套餐表

6

setmeal_dish

套餐菜品关系表

7

user

用户表

8

address_book

地址表

9

shopping_cart

购物车表

10

orders

订单表

11

order_detail

订单明细表

employee表结构:

id

bigint

主键

自增

name

varchar(32)

姓名

username

varchar(32)

用户名

唯一

password

varchar(64)

密码

phone

varchar(11)

手机号

sex

varchar(2)

性别

id_number

varchar(18)

身份证号

status

Int

账号状态

1正常 0锁定

create_time

Datetime

创建时间

update_time

datetime

最后修改时间

create_user

bigint

创建人id

update_user

bigint

最后修改人id

0.技术亮点

1.使用Nginx部署前端界面实现前后端分离,并实现反向代理和负载均衡

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器

前端页面部署到Nginx服务器中,后端代码部署到后端服务器中,使用Nginx对后端服务器进行反向代理,使用户只需要访问Nginx服务器便可获得后端服务器的服务(便于后期扩展集群,提高系统并发量)。

1.Nginx反向代理

前端请求地址:http://localhost/api/employee/login

后端接口地址:http://localhost:8080/admin/employee/login

前端请求地址后端接口地址

很明显,两个地址不一致,那是如何请求到后端服务的呢?

nginx 反向代理,就是将前端发送的动态请求由 nginx 转发到后端服务器

那为什么不直接通过浏览器直接请求后台服务端,需要通过nginx反向代理呢?

nginx 反向代理的好处:

  • 提高访问速度因为nginx本身可以进行缓存,如果访问的同一接口,并且做了数据缓存,nginx就直接可把数据返回,不需要真正地访问服务端,从而提高访问速度。
  • 进行负载均衡所谓负载均衡,就是把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器。
  • 保证后端服务安全因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。

2.Nginx负载均衡

当如果服务以集群的方式进行部署时,那nginx在转发请求到服务器时就需要做相应的负载均衡。其实,负载均衡从本质上来说也是基于反向代理来实现的,最终都是转发请求。

在nginx的配置文件设置负载均衡策略。

nginx有很多负载均衡策略,比如轮询,weight权重方式,url分配方式,我们项目用的是轮询方式,共有3台后端服务器

nginx 负载均衡策略:

轮询

默认方式,每个请求会按时间顺序逐一分配到不同的后端服务器。

weight

权重方式,默认为1,权重越高,被分配的客户端请求就越多

ip_hash

依据ip分配方式,这样每个访客可以固定访问一个后端服务

least_conn

依据最少连接方式,把请求优先分配给连接数少的后端服务

url_hash

依据url分配方式,这样相同的url会被分配到同一个后端服务

fair

依据响应时间方式,响应时间短的服务将会被优先分配

http请求报文和响应报文

http报文的三个组成部分 http报文是一个格式化数据块。报文类型包括客户端请求,服务器响应。

http请求报文由3个部分组成:

请求行(start line):由请求方法(GET/POST/PUT)、请求URL(不包括域名 | 、HTTP协议版本组成

请求头(header):请求头部由关键字/值对组成,每行一对;主要包含Content-Length标头:实体的长度,Content-Tyep标头:实体的媒体类型

请求体(body) :GET(从服务器获取数据)请求体为空,POST(向服务器发送要处理的数据)有数据

http响应报文组成:

1.状态行服务器HTTP协议版本响应状态码状态码的文本描述

状态码由3位数字组成,第一个数字定义了响应的类别:

1xx:指示信息,表示请求已接收,继续处理

2xx:成功,表示请求已被成功接受,处理。

3xx:重定向

4xx:客户端错误

5xx:服务器端错误,服务器未能实现合法的请求。

2.首部行:主要包含Content-Length标头:实体的长度,Content-Tyep标头:实体的媒体类型

3.实体:实体包含了Web客户端请求的对象

Apifox测试接口流程

step1.选择请求方法->填写请求url->填写url参数->填写body参数和header参数(如果有)

step2.手动发送请求

step3.查看返回参数是否正常,是否符合接口文档的约定

0.项目哪里用了设计模式?

使用工厂模式和策略模式实现布隆过滤器的大概流程如下:

  1. 定义布隆过滤器接口:首先定义一个布隆过滤器接口,包括添加元素和判断元素是否存在两个基本操作。
  2. 实现具体的布隆过滤器类:创建一个具体的布隆过滤器类,实现布隆过滤器接口中的方法。在这个类中,需要定义布隆过滗器的数据结构(比如位数组)、大小等属性。
  3. 定义哈希策略接口:定义一个哈希策略接口,包含计算哈希值的方法。
  4. 实现具体的哈希策略类:创建多个具体的哈希策略类,实现哈希策略接口中的方法,每个类对应一种哈希函数的计算方法。
  5. 创建布隆过滤器工厂类:定义一个布隆过滤器工厂类,其中包含一个用于创建布隆过滤器对象的工厂方法。工厂方法接受布隆过滤器的大小和哈希策略对象作为参数,并返回一个具体的布隆过滤器对象。
  6. 使用布隆过滤器工厂:在需要创建布隆过滤器对象的地方,调用布隆过滤器工厂的工厂方法来创建布隆过滤器对象,并传入相应的哈希策略对象。

使用工厂和策略设计模式的好处?

使用工厂模式和策略模式来实现布隆过滤器带来以下好处:

  1. 解耦性:工厂模式和策略模式的结合可以将对象的创建和哈希函数的选择分离,使得各部分之间的耦合度降低。这样在需要修改布隆过滤器的具体实现或者切换哈希函数时,只需要修改相应的工厂类或策略类,而不影响其他部分。
  2. 可扩展性:通过工厂模式和策略模式,我们可以方便地添加新的布隆过滤器实现类和哈希函数策略类,而不需要修改现有代码。这样在需要增加新的布隆过滤器类型或者新的哈希函数时,只需添加相应的类即可。
  3. 代码复用:工厂模式和策略模式可以提高代码的复用性。通过工厂模式,我们可以在不同地方调用工厂方法来创建布隆过滤器对象,避免重复的创建逻辑。通过策略模式,不同的哈希函数策略可以被多个布隆过滤器共享使用。
  4. 易于维护:将对象的创建和哈希函数的选择分开管理,使得代码结构清晰,易于维护和理解。当需要修改布隆过滤器的实现或者哈希函数时,只需修改相应的工厂类或策略类,而不会对其他部分造成影响。

1.使用工厂模式和策略模式实现布隆过滤器解决缓存穿透问题

1.什么是缓存穿透问题

缓存穿透:请求根本不存在的资源(DB本身就不存在,Redis更是不存在),这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。这种情况大概率是遭到了攻击。

使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截

2.什么是布隆过滤器?

布隆过滤器主要是用于检索一个元素是否在一个集合中。

布隆过滤器的核心思想是使用多个哈希函数来将元素映射到位数组中的多个位置上。当一个元素被加入到布隆过滤器中时,它会被多次哈希,并将对应的位数组位置设置为1。当需要判断一个元素是否在布隆过滤器中时,我们只需将该元素进行多次哈希,并检查对应的位数组位置是否都为1,如果其中有任意一位为0,则说明该元素不在集合中;如果所有位都为1,则说明该元素可能在集合中(因为有可能存在哈希冲突),需要进一步检查。

3.怎么用布隆过滤器解决缓存穿透问题

使用BitMap作为布隆过滤器,使用多个hash函数对key进行hash运算,得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash函数都会得到一个不同的位置,将这几个位置的值置为1。

向布隆过滤器查询某个key是否存在时,先把这个 key 通过相同的多个 hash 函数进行运算,查看对应的位置是否都为 1,

只要有一个位为零,那么说明布隆过滤器中这个 key 不存在;

如果这几个位置全都是 1,那么说明极有可能存在但不是一定存在;

因为这些位置的 1 可能是因为其他的 key 存在导致的,也就是前面说过的hash冲突

什么是bitmap

bitmap是redis的一种数据类型

Bitmap 存储的是连续的二进制数字(0 和 1),本来int数字占4字节32位,但通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态(比如:01表示1,001表示2) 。,所以 Bitmap 本身会极大的节省储存空间。

# 将名为myBitmap的bitmap的第5位设置为1
SETBIT myBitmap 5 1  //SETBIT key offset value
获取位值:GETBIT key offset
java实现:redisTemplate.opsForValue().getBit(checkItem, index);

4.设置布隆过滤器的误判率

设置布隆过滤器的误判率为1%

布隆过滤器工厂接收预期数据量n和误差率p,根据上面两个数据计算出布隆过滤器的大小m(size)和哈希函数个数k。

当布隆过滤器实际的数据存储量超过预期数据量之后,误判率也会随之上涨。但是布隆过滤器是不能删除已有元素的,在这里我们采取的方案是再创建一个布隆过滤器

5.怎么用的设计模式?

使用工厂模式和策略模式实现布隆过滤器的大概流程如下:

  1. 定义布隆过滤器接口:首先定义一个布隆过滤器接口,包括添加元素和判断元素是否存在两个基本操作。
  2. 实现具体的布隆过滤器类:创建一个具体的布隆过滤器类,实现布隆过滤器接口中的方法。在这个类中,需要定义布隆过滗器的数据结构(比如位数组)、大小等属性。
  3. 定义哈希策略接口:定义一个哈希策略接口,包含计算哈希值的方法。
  4. 实现具体的哈希策略类:创建多个具体的哈希策略类,实现哈希策略接口中的方法,每个类对应一种哈希函数的计算方法。
  5. 创建布隆过滤器工厂类:定义一个布隆过滤器工厂类,其中包含一个用于创建布隆过滤器对象的工厂方法。工厂方法接受布隆过滤器的大小和哈希策略对象作为参数,并返回一个具体的布隆过滤器对象。
  6. 使用布隆过滤器工厂:在需要创建布隆过滤器对象的地方,调用布隆过滤器工厂的工厂方法来创建布隆过滤器对象,并传入相应的哈希策略对象。

使用工厂和策略设计模式的好处?

使用工厂模式和策略模式来实现布隆过滤器带来以下好处:

  1. 解耦性:工厂模式和策略模式的结合可以将对象的创建和哈希函数的选择分离,使得各部分之间的耦合度降低。这样在需要修改布隆过滤器的具体实现或者切换哈希函数时,只需要修改相应的工厂类或策略类,而不影响其他部分。
  2. 可扩展性:通过工厂模式和策略模式,我们可以方便地添加新的布隆过滤器实现类和哈希函数策略类,而不需要修改现有代码。这样在需要增加新的布隆过滤器类型或者新的哈希函数时,只需添加相应的类即可。
  3. 代码复用:工厂模式和策略模式可以提高代码的复用性。通过工厂模式,我们可以在不同地方调用工厂方法来创建布隆过滤器对象,避免重复的创建逻辑。通过策略模式,不同的哈希函数策略可以被多个布隆过滤器共享使用。
  4. 易于维护:将对象的创建和哈希函数的选择分开管理,使得代码结构清晰,易于维护和理解。当需要修改布隆过滤器的实现或者哈希函数时,只需修改相应的工厂类或策略类,而不会对其他部分造成影响。

5.使用Mysql自带的二进制日志功能,实现MySQL主从复制,Sharding-JDBC实现读写分离,减轻单台数据库读写压力,避免发生单点故障

1.为什么主从复制

刚开始系统只部署了一台服务器,读和写数据的所有压力全都由一台数据库承担,压力大,数据库服务器磁盘损坏则数据丢失,单点故障。后来使用 MySQL进行主从复制,一主一从,主库进行增删改操作,从库进行查询操作,从而减轻数据库负担。主库的数据会实时同步到从库中,实现了主库数据的备份,就算主库损毁也有备份,安全性大大提高。随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以提高数据库的可用性。本项目使用Sharding-JDBC在程序中实现读写分离(优点在于数据源完全有Sharding托管,写操作自动执行master库,读操作自动执行slave库。不需要程序员在程序中关注这个实现了。)。

主从复制实际上就是将主库的数据同步到从库数据,通过Mysql主从复制就可以实现从库中的数据和主库中的数据一致。

2.MySQL怎么主从复制

MySQL复制过程分为三步:

第一:主库在事务提交时,会把数据变更记录在二进制日志文件 Binlog 中。

第二:从库读取主库的二进制日志文件 Binlog ,写入到从库的中继日志 Relay Log 。

第三:从库重做中继日志中的事件,在slave库上做相应的更改。

3.Sharding-JDBC怎么实现读写分离

对于同一时刻有大量并发读操作和较少写操作类型的应用来说,将数据库拆分为主库和从库,主库就负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁(innodb引擎支持的就是行锁),使得整个系统的性能得到极大改善。

Sharding-JDBC介绍Sharding-JDBC定位为轻量级java框架,在java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。使用Sharding-JDBC可以在程序中轻松的实现数据库读写分离,优点在于数据源完全有Sharding托管,写操作自动执行master库,读操作自动执行slave库。不需要程序员在程序中关注这个实现了。

6.使用Redis,采用一主两从+哨兵的集群方案,缓存营业状态、菜品分类等信息,解决了数据一致性问题;

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

我的笔记专栏,内容包含:(1)多一句没有少一句不行的最精简八股整理,完全可以应付校招社招的八股拷打;(2)面试时非技术问题的话术整理;(3)智力题题解汇总。敬请期待!专栏每增加一篇文章费用就会上涨一点,如果你喜欢的话建议你尽早订阅。

全部评论
不错的,如果不说 “苍穹外卖”,都认不出来这是 “苍穹外卖”
151 回复 分享
发布于 2024-06-24 22:42 上海
把你话术背下来,项目都不用做了,直接省了15天项目期
72 回复 分享
发布于 2024-06-30 10:42 广东
牛的,不过外卖项目不管怎么包装,投互联网确实太减分了
32 回复 分享
发布于 2024-06-24 21:30 北京
25号,昨天才发的,恐怖的收藏量
26 回复 分享
发布于 2024-06-25 10:18 上海
手握苍穹外卖,笑傲宇宙苍穹。
24 回复 分享
发布于 2024-06-24 23:01 北京
哥们确实牛逼啊,缺不缺男性朋友
19 回复 分享
发布于 2024-06-24 23:28 北京
我是一眼看出来的,就是不知道面试官几眼看出来😋
15 回复 分享
发布于 2024-06-25 11:49 广东
觉得有用的给我送几多小红花吧,就快凑齐衣服碎片了
10 回复 分享
发布于 2024-07-06 17:43 湖北
偷了,其实用的东西都是那些,哥们总结得很精炼
9 回复 分享
发布于 2024-06-25 08:29 重庆
没啥东西😅,不过对985够用了
7 回复 分享
发布于 2024-06-25 11:10 重庆
订阅下我的专栏吧,这才是对我真金白银的支持
6 回复 分享
发布于 2024-06-29 11:02 湖北
蓝子哥有实力的👍🏻
6 回复 分享
发布于 2024-06-25 09:50 陕西
无敌
5 回复 分享
发布于 2024-06-24 21:27 北京
能抽空把文章排下版吗?这里面的标题内容乱序看起来真麻烦
3 回复 分享
发布于 2024-09-08 10:39 四川
只想买单篇😕
2 回复 分享
发布于 2024-07-31 15:56 湖北
拉倒吧,如果你不是中南的,你这也是破外卖
2 回复 分享
发布于 2024-07-17 16:29 湖南
感觉是不是博主自己在自己的项目里加了这些内容啊 咋感觉外卖里面没讲这些
1 回复 分享
发布于 2024-11-22 21:46 四川
佬,还有推荐做的项目吗?没有我就订阅你专栏了😀
1 回复 分享
发布于 2024-09-29 19:10 天津
获取用户信息,并将其存储在ThreadLocal中,以避免在每次请求时都去解析JWT令牌,请问是怎么实现通过ThreadLocal避免重复解析的呀,这里不太理解
1 回复 分享
发布于 2024-09-22 22:43 湖南
订阅专栏了大佬,小白没盘明白文章的逻辑,编号一会大一会小,弱弱地提个建议,能否按照1/1.2/1.2.1这种分级标题重新标一下文章的逻辑,照顾一下菜鸡,万分感谢
1 回复 分享
发布于 2024-08-27 17:07 北京

相关推荐

头像
03-20 20:50
已编辑
北京体育大学 测试工程师
双非本逆袭进大厂,普通本科秋招变成offer收割机……这样的情况是有的,但是也是稀有的,你去跟他们比的话,那么是很难比得过的。国家奖学金,acm拿奖牌。在核心的开源项目提交过代码,好多篇sci论文,这些当然都是简历的加分项,但是我们都是普通人,一般最多也就是班级奖学金,普通话证书,计算机二级,英语四六级这些没有差异性的一些奖项,那么如何去写一个能达到及格分的?能够进入大厂面试的一个简历呢,1.首先你要有一个不是那么烂大街的项目,如果你是做外卖或者做点评,那么这个项目既不是加分项,也不是减分项,只能让你的简历稍微长一点儿,然后也不必过分追求JAVA,JAVA这个东西虽好,但也不一定适合每个人,2.第二点就是你最好是有一个实习经历。然后也不要写得太空太泛,找出1~2个亮点,然后深入的讲讲遇到什么问题,用了什么方法去解决问题,得到什么结果,有什么样的收获,这样在面试的时候可以让面试官对你有一个解决问题能力的基本认知。3.然后就是要写写你的技术栈,什么数据库,线程池。分布式锁类似的技术。然后也是可以稍微挑一点儿比较独特的东西。写出来让面试官对你有兴趣,然后你也可以有的放矢的准备一些相关的内容,让面试官眼前一亮4.然后还是就要有全日制的本科学历,因为如果是专科,在现在这个时代想走互联网还是有点儿太难了,最后再说点儿奇技淫巧,针对于投递简历的我的血泪史首先你要坚持投递,日常实习跟暑期实习,其实没有特别大的分别,几乎都是有转正机会的,你只要坚持,那么还有可能就遇到急招人的组,然后很容易就进去了,聊聊天儿就能够拿一个实习机会,然后转正也是极大概率的,第二点就是稍微准备好了再去投递字节跳动,因为字节跳动的面评会记录比较长的时间,如果你第一次没准备好,那么以后你可能也没有办法复活了,然后就是遇到KPI面要淡定一点儿,因为面试官上班儿也不容易,你天天投简历找工作也不容易,大家都不容易,那还是各自放过,互相安好吧,第四点就是如果有的offer你没拿到,也可能是老天在救你,这个offer说不定就是不好呢。去了就难受了。最后一点就是认真考虑你到底想要什么,是比较稳定的。小城市安居乐业,成家能团团圆圆吃上一口热乎饭的还是那种北漂,沪漂,深漂,大半夜回到出租屋,好不容易周末休息就睡到下午,或者说是周末加班儿的,虽然钱也不老少真的需要好好想想自己真正要的是啥。#满分简历要如何准备?#
Java抽象小篮子:对于双非我第一个建议的是首先选择好一个具体的方向,前后端测试运维客户端,不建议一上来无脑梭哈后端,确定方向后之际猛猛造就完事了
投递字节跳动等公司6个岗位 满分简历要如何准备?
点赞 评论 收藏
分享
评论
1112
5650
分享

创作者周榜

更多
牛客网
牛客企业服务