Java 项目
1. 坦克大战 (停止维护)
- Repo:
2. 多用户通信系统 (暂停维护)
- Repos:
3. 从 0 实现 Tomcat (暂停维护)
Repo:
Notes:
已完结
(详情见 JavaWeb 相关部分)
4. 家居网购 (暂停维护)
Assets:
Repo:
Notes:
技术栈:
- 原生 Servlet / 过滤器,WEB-Service-DAO-Entity
软件项目开发流程
需求分析阶段
设计阶段
- 开发阶段
- 测试阶段
- 实施阶段
- 维护阶段
项目设计
后端三层架构
项目分包方案
MVC
- MVC 全称:Model、View、Controller
- 最早出现在 JavaEE 三层中的 Web 层,可有效指导 Web 层的代码分离,单独工作(解耦)
- View 视图:负责数据和界面显示,不接受任何与数据无关的代码
- Controller 控制器:负责接收请求,调用业务层的代码处理请求,然后派发页面(调度者)
- Model 模型:将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂与数据处理相关的代码
代码归档(Version of Git’s message)
开发环境搭建(1.x)
会员注册前端校验与后端表设计(2.x)
会员注册后端服务(3.x)
会员登录(4.x)
登录错误提示,表单回显用户名(5.x)
Servlet 瘦身优化(6.x)
后台管理 - 家居显示(7.x)
后台管理 - 家居添加(8.x)
- 中文乱码问题解决:要在 BasicServlet(父类)中设置 req 编码
- 表单重复提交问题解决:设置重定向(重定向本质为两次请求)
- 后端数据校验:捕获异常并返回信息
后台管理 - 家居删除(9.x)
后台管理 - 家居修改(10.x)
后台分页 - 家居分页显示(11.x)
- 数据模型:高频变化的数据封装为 Bean(如导航条数据)
首页分页(12.x)
首页搜索(13.x)
会员显示登录名(14.x)
注销登录(15.x)
注册验证码(16.x)
添加家居到购物车(17.x)
购物车的显示、修改、清空等界面前后端交互(18.x)
添加购物车操作库存校验(19.x)
过滤器权限验证(20.x)
事务管理(21.x)
- ThreadLocal 统一管理数据库连接
统一错误页面(22.x)
AJAX 重构(23.x)
家居图片更新功能(24.x)
项目完结
5. 黑马点评(Redis 笔记)
短信登录(Session to Redis)
- Session 不方便进行多台 Tomcat 横向部署
- 拦截器内取 token 不能使排除页面获取 token
缓存(Cache)
缓存更新
更新策略
- 内存回收,自动更新(低一致 性需求)
- 设置超时,定时更新(低一致性 需求)
- 编码,主动更新(高一致性 需求)
缓存一致性问题
- 先删缓存,再更新数据库
- 先更新数据库,再写缓存(✅缓存更新速度快,相对影响小)
缓存穿透
指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库
缓存空对象
优:实现简单,维护方便
缺:
- 额外内存消耗
- 可能造成短期数据不一致
布隆过滤(用数据索引布尔值来做存在判断)
- 优:内存占用少,无多余 key
- 缺:
- 实现复杂
- 存在误判可能
缓存雪崩
指同一时段大量缓存 key 同时失效或 Redis 服务宕机,导致大量请求到达数据库,带来巨大压力
- 给不同的 key 的 TTL 添加随机值
- 利用 Redis 集群提高服务可用性
- 给缓存业务添加降级限流策略(如提前返回、拒绝服务)
- 给业务添加多级缓存(如 Nginx 缓存、JVM 本地缓存)
缓存击穿
查询过程较慢导致大量请求打到数据库
互斥锁
- 优:
- 无额外内存消耗
- 保证一致性
- 实现简单
- 缺:
- 线程需要等待,性能受影响
- 可能有死锁风险
- 优:
逻辑过期
- 优:
- 线程无需等待,性能较好
- 缺:
- 不保证一致性
- 有额外内存消耗
- 实现复杂
- 优:
缓存工具封装
优惠券秒杀(Redisson)
全局唯一 ID
实现优惠券下单
超卖问题(JMeter 实测)
加锁
乐观锁
不加锁,在更新时判断是否有其它线程在修改
版本号法
在表中加一个版本号字段,用于判断
CAS 法(比较和替换)
库存与版本号同时变化,那么库存同时具有与版本号相同的功能
优:性能好
缺:存在成功率低的问题
可分批加锁 或 低要求加锁
悲观锁
添加同步锁,让线程串行执行
- 优:简单粗暴
- 缺:性能一般
一人一单
判断同人同单的订单是否存在
因为是插入操作而不是更新,所以采用悲观锁
快捷键:Ctrl + Alt + M -> 封装所选代码段为私有方法
加锁位置
对用户加锁而不是操作
要对同一用户加锁,故将锁加在 userId 字段上,注意以值判断是否等价(getId() 返回的是新对象,toString() 方法返回的也是新对象)
释放锁后事务可能未提交
要对封装方法加锁
非代理对象事务失效
return 处调用的函数的对象为 this,还未被 Spring 代理,会造成事务失效
取得代理对象后用代理调用方法
使用代理对象需要的配置
引入依赖 org.aspectj
暴露代理对象
集群并发安全(⬇️分布式锁⬇️)
分布式锁
满足分布式系统或集群模式下 多进程可见 并且 互斥 的锁
实现方案
两个基本方法
自动拆箱注意空指针问题
锁误删
问题剖析:释放锁时应确认锁是否属于自己(线程锁标识可用 UUID 表示)
判断与释放的原子性问题(Lua 脚本)
Redis 提供了 Lua 脚本功能,在一个脚本中编写多条 Redis 命令,确保多条命令执行时的原子性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
static {
UNLOCK_SCRIPT = new DefaultRedisScript<>();
UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));
UNLOCK_SCRIPT.setResultType(Long.class);
}
public void unlock() {
stringRedisTemplate.execute(
UNLOCK_SCRIPT,
Collections.singletonList(KEY_PREFIX + lockName),
ID_PREFIX + Thread.currentThread().getId()
);
}Redisson
基于 setnx 实现的分布式锁存在问题
Redisson:在 Redis 基础上实现的 Java 驻内存数据网络(In-Memory Data Grid)。它不仅提供了一系列的分布式 Java 常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现
6. 扎堆网(PileUp) - (伙伴匹配系统)
- Repos:
- Notes:
需求分析
- 用户添加标签,标签分类
- 搜索、标签搜索
- Redis 缓存
- 组队
- 允许用户修改标签
- 推荐
- 相似度计算算法 + 本地分布式计算
技术栈
前端
- Vue3(提高页面开发效率)
- Vant UI (基于 Vue 的移动端组件库)(React 版 Zent)
- Vite(打包工具)
- Nginx 单机部署
后端
- Java + SpringBoot
- SpringMVC + MyBatis + MyBatis Plus
- MySQL 数据库
- Redis 缓存
- Swagger + Knife4j 接口文档
代码归档
前端项目初始化(1.x)
前端主页 + 组件概览(2.x)
- 设计
- tabbar
- 首页(推荐 + 广告)
- 推荐信息流(含广告)
- 发现页(搜索/热搜)
- 消息(邮件)
- 用户页(我)
- 首页(推荐 + 广告)
- tabbar
- 开发
- 设计
数据库表设计
标签表
- 性别:男、女
- 方向:Java、C++、Go、前端、网安
- 正在学:Spring
- 目标:考研、春招
- 段位:初级、中级、高级、王者
- 身份:大一、大二、大三、大四、学生、待业、已就业、研一、研二、研三
- 状态:乐观、有点丧、单身、已婚、有对象
- 用户自定义标签
- 字段
- id int 主键
- 标签名 varchar 非空(必须唯一,唯一索引)
- 上传标签的用户 userId int(根据 userId 查已上传标签,普通索引)
- 父标签 id parentId int(分类)
- 是否为父标签 isParent tinyint (0 -> 不是父标签 / 1 -> 是父标签)
- 创建时间 createTime datetime
- 更新时间 updateTime datetime
- 是否删除 isDelete tinyint (0/1)
修改用户表(根据需求)
补充 tags 字段,存 json 字符串 :white_check_mark:
优:查询方便、不用新建关联表,标签是 用户的固有属性 (除该系统之外还可能用到)
性能低可用 Redis
缺:用户表多一列
加一个关联表,记录用户和标签的关系
优:(应用场景:)查询灵活、可正查反查
缺:要多建一个表、多维护一个表
企业大项目开发中尽量减少关联查询,很影响扩展性,而且影响查询性能
后端接口开发(3.x)
用户中心集中提供用户的检索、操作、注册、登录、鉴权
- 根据标签搜索用户
根据标签搜索用户 - 前端()
x. 硅谷课程(SpringBoot 后)
含公众号开发、文件上传、点播、直播…