Yucan Huang

Project

如何设计秒杀系统

什么是秒杀设计 秒杀设计 是一种针对高并发、大流量场景的系统设计,通常应用于电商活动中(如限时抢购、促销等),用户在非常短的时间内大量涌入系统,抢购有限的商品或优惠。这种场景下,系统需要能够承受巨大的瞬时并发请求,同时保证数据的一致性和业务的正确性。 秒杀技术分析 秒杀系统贯穿活动、商品和下单三个领域,涵盖了页面静态化、接口限流、Redis预减库存、异步下单和接口动态化等技术。 需要迎接的挑战有: 1. 高并发和压力测试:秒杀活动会带来巨大的流量,服务器和数据库的并发处理能力是关键。 2. 保证数据一致性:抢购涉及到商品库存的实时减少,需要保证在高并发场景下库存数据的准确性和一致性 3. 防止超卖和重复购买:确保同一商品不会被重复购买,同时避免超卖,即使是在极端的高并发情况下 4. 分布式锁和限流:使用分布式锁来保护关键资源,限制用户访问频率以免系统崩溃 5. 性能优化:包括代码层面的优化、数据库的优化、缓存的使用等,以提高系统性能和响应速度。 页面静态化 秒杀页面静态化是将动态生成的秒杀页面转换为静态HTML页面,从而提高页面响应速度和系统性能

By Yucan Huang

Project

分布式系统下雪花算法生成全局唯一ID

雪花算法 在分布式系统中,为了避免多个节点生成相同的唯一标识符id,我们通常使用一种全局唯一ID生成策略,而Snowflake Algorithm就是广泛使用的解决方案之一。 雪花算法简介 雪花算法生成的 ID 是一个 64 位的二进制整数,具有以下组成部分: 部分 字节长度 描述 符号位 1bit 固定为0,因为生成的ID是整数 时间戳 41bits 表示时间戳,单位是毫秒,可以存储大约68年的时间 机器ID 10bits 用于标识不同的机器(节点)。10位可以将其分数据中心ID(5位)和机器ID(5位),共支持1024台机器同时生成ID 序列号 12bits 同一毫秒内的序列号,用来区分在同一台机器、同一时间戳下生成的多个ID,最大支持同一毫秒生成4096个唯一ID 代码实现 package com.can.springbootmessage; public class SnowflakeIdGenerator { // 起始时间戳,Long是64位,

By Yucan Huang

Project

责任链设计模式

什么是责任链模式 项目有个请求,需要有对应的服务来处理,然后这个请求可能需要被很多个层级权限的服务来处理。我们将这些处理该请求的服务放在一条链上,链从前往后,是层级更高的服务,第一个服务处理不了,传递到链上的下一个服务,直到这个请求被处理成功。 责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理器成功处理该请求,责任链模式把多个处理器串成链,然后让请求在链上传递。 1. 如何把多个处理器串成链,然后让请求在链上传递 客户端发送请求,处理类去处理它的请求,所以有个处理方法(handleRequest),处理类要连接在一起,所以**处理类要有一个方法(成员变量nextHandler)**指向下一个处理类。 我们抽象出一个公共的父类,然后去定义不同的处理类,这些处理类通过nextHandler连接起来。 2. 代码演示 package interview.pattern; public class ChainRespPattern { Handl

By Yucan Huang
外卖点餐系统07

Project

外卖点餐系统07

缓存菜品 问题说明 用户通过微信小程序查询菜品,小程序会将请求发送给后端服务,后端就会查询MySQL数据库。 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大,就会造成系统响应慢,用户体验差。 解决思路 * 通过Redis来缓存菜品数据,减少数据库查询操作。 微信小程序查询数据后,会向后端服务发送请求,判断请求的数据在缓存中是否存在,如果存在直接读取缓存,不存在再查询MySQL,并将该数据载入缓存。 * 缓存逻辑分析 微信小程序展示菜品粒度是根据分类展示,所以缓存数据应该根据分类缓存菜品。 1. 每个分类下的菜品保存一份缓存数据 * 使用分类id作为key,分类下的菜品数据使用String字符串保存,分类下的菜品应该是List集合,在Java中可以通过序列化将这个集合转换成Redis的字符串类型 2. 数据库中菜品数据有变更时及时清理缓存数据 代码开发 1. 修改用户端接口 DishContr

By Yucan Huang
如何建立个人网站

如何建立个人网站

需要一个管理网站的平台 现在有很多可以管理网站的平台,例如SquareSpqce、WordPress、ghost等,这些平台能够让使用者轻松的管理和维护网站,包括自定义个人网站的界面,轻松的发布文章。 这些平台只需要挑选一个你自己喜欢的即可,然后注册账号即可使用。我使用的是ghost,需要付费,一个月9 dollar。 如何使用 1. 注册一个ghost账号 网址:ghost.org 注册完,登陆之后,你就进入了ghost的管理界面 2. 发文章 我们有了一个平台之后,就可以尝试着发布一篇文章,这是我们的个人网站,所以我们想发布什么都可以,只有实操去发布一篇文章,你就会发现并没有想象中那么有难度。 但是我强烈建议学习如何使用Markdown格式进行学习记录,有以下三点好处: * Markdown格式可以在IntelliJ IDEA,CSDN, 有道云以及ghost,几乎所有的笔记软件平台上通用 * Markdown格式的文件还可以直接保存在本地 * 其次有时候如果我们直接拿word或者有道云做笔记,然后我们想要

By Yucan Huang
外卖点餐系统05

Project

外卖点餐系统05

Redis简介 Redis在MySQL基础上提高数据存取效率 Redis是一个基于内存的key-value结构数据库。 MySQL是基于磁盘实现的数据库,由于数据读写需求越来越大,这种基于磁盘的读取速度就不够了,于是是否能够像CPU一样为了提高速度,也搞一个类似内存的东西。于是Redis就产生了。 应用程序从MySQL查询到的数据在Redis中进行登记,后续再查询数据先搜索Redis,Redis没有再搜索MySQL。 Redis缓存内容设置超时时间 Redis缓存的数据都是在内存上,但是内存的空间资源很有限,所以需要给缓存内容设置一个超时时间,具体设置多久交给应用程序设置,Redis只需要在时间过期后及时删除数据。 Redis删除策略 * 定期删除,eg:每100ms随机清理部分缓存数据,这里不清理所有Redis内存过期数据,是因为全面扫描一遍需要时间过久 * 但是由于随机算法,有可能使得某些键值长期不被随机到,未被清理 * 触发删除,为了避免有些键值长期不被清理,于是有了出发删除 * 主动发起请求检查key是否过期,如果过期立马删除,这种方式

By Yucan Huang
剑指offer 树

剑指offer 树

递归是一个过程或函数在其定义或说明中直接或间接调用自身的一种方法,它通常将一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程中,最重要的是查看 能否将问题分解为更小的子问题,这是使用递归的关键。 二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数不断进入子树。 JZ55 二叉树的深度 思路一 —— 递归 二叉树的深度等于根节点这个1层加上左子树和右子树深度的最大值,即root_depth = max(left_depth, right_depth) + 1。而每个子树我们都可以看出一个根节点,于是我们可以对这个问题划分为子问题,利用递归来解决: * 终止条件:当进入叶子节点后,再进入子节点,即为空,没有深度可言,返回0。 * 返回值:每一级按照上述公式,返回两边子树深度的最大值加上本级的深度,即加1。 * 本级任务:每一级的任务就是进入左右子树,求左右子树的深度。 import java.util.*; /** public class Tr

By Yucan Huang
剑指offer-链表

剑指offer-链表

JZ24 反转链表 描述 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。数据范围: 0≤n≤10000≤n≤1000要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。以上转换过程如下图所示: 思路一 — 头插法 没有头结点的头插法 public class ReverseList { public static void

By Yucan Huang