实战篇(3):优惠券秒杀[Redis]
3、优惠卷秒杀
3.1 全局唯一ID
每个店铺都可以发布优惠券:
当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题:
id的规律性太明显
受单表数据量的限制
场景分析:
如果我们的id具有太明显的规则,用户或者说商业对手很容易猜测出来我们的一些敏感信息,比如商城在一天时间内,卖出了多少单,这明显不合适。
随着我们商城规模越来越大,mysql的单表的容量不宜超过500W,数据量过大之后,我们要进行拆库拆表,但拆分表了之后,他们从逻辑上讲他们是同一张表,所以他们的id是不能一样的, 于是乎我们需要保证id的唯一性。
全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:
为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其它信息:
ID的组成部分:符号位:1bit,永远为0
时间戳:31bit,以秒为单位,可以使用69年
序列号:32bit,秒内的计数器,支持每秒产生232个不同ID
3.2 Redis实现全局唯一Id
123456789101112131415161718192021222324252627282930313233@Componentpublic class RedisIdWorker { /** * 开始时间戳 */ private static final long BEGIN_TIMESTAMP = 1640995200L; /** * 序列号的位数 */ private static final int COUNT_BITS = 32; private StringRedisTemplate stringRedisTemplate; public RedisIdWorker(StringRedisTemplate stringRedisTemplate) { this.stringRedisTemplate = stringRedisTemplate; } public long nextId(String keyPrefix) { // 1.生成时间戳 LocalDateTime no ...
实战篇(2):商户查询缓存[Redis]
在原本笔记的基础上作出修改
2、商户查询缓存
2.1 什么是缓存?实战篇Redis[1]
视频教程地址实战篇哔哩哔哩_bilibili
在原本笔记的基础上作出修改
学习内容
短信登录
使用redis共享session来实现
商户查询缓存
通过本章节,我们会理解缓存击穿,缓存穿透,缓存雪崩等问题,让小伙伴的对于这些概念的理解不仅仅是停留在概念上,更是能在代码中看到对应的内容
优惠卷秒杀
通过本章节,我们可以学会Redis的计数器功能, 结合Lua完成高性能的redis操作,同时学会Redis分布式锁的原理,包括Redis的三种消息队列
附近的商户
我们利用Redis的GEOHash来完成对于地理坐标的操作
UV统计
主要是使用Redis来完成统计功能
用户签到
使用Redis的BitMap数据统计功能
好友关注
基于Set集合的关注、取消关注,共同关注等等功能,这一块知识咱们之前就讲过,这次我们在项目中来使用一下
达人探店
基于List来完成点赞列表的操作,同时基于SortedSet来完成点赞的排行榜功能
1、短信登录
1.1、导入黑马点评项目
1.1.1 、导入SQL
1.1.2、有关当前模型
手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的事HTTP协议,可以实现基于Lua直接绕开tomcat访问redis,也可以作为静态资源服务器,轻松扛下上万并发, 负载均衡到下游tomcat服务器,打散流量,我们都知道一台4核8G的tomcat,在优化和处理简单业务的加持下,大不了就处理1000左右的并发, 经过nginx的负载均衡分流后,利用集群支撑起整个项目,同时nginx在部署了前端项目后,更是可以做到动静分离,进一步降低tomcat服务的压力,这些功能都得靠nginx起作用,所以nginx是整个项目中重要的一环。
在tomcat支撑起并发流量后,我们如果让tomcat直接去访问Mysql,根据经验Mysql企业级服务器只要上点并发,一般是16或32 核心cpu,32 或64G内存,像企业级mysql加上固态硬盘能够支撑的并发,大概就是4000起~7000左右,上万并发, 瞬间就会让Mysql服务器的cpu,硬盘全部打满,容易崩溃,所以我们在高并发场景下,会选择使用mysql集群,同时为了进一 ...
实战篇(1):短信登录[Redis]
实战篇Redis[1]
视频教程地址实战篇哔哩哔哩_bilibili
在原本笔记的基础上作出修改
学习内容
短信登录
使用redis共享session来实现
商户查询缓存
通过本章节,我们会理解缓存击穿,缓存穿透,缓存雪崩等问题,让小伙伴的对于这些概念的理解不仅仅是停留在概念上,更是能在代码中看到对应的内容
优惠卷秒杀
通过本章节,我们可以学会Redis的计数器功能, 结合Lua完成高性能的redis操作,同时学会Redis分布式锁的原理,包括Redis的三种消息队列
附近的商户
我们利用Redis的GEOHash来完成对于地理坐标的操作
UV统计
主要是使用Redis来完成统计功能
用户签到
使用Redis的BitMap数据统计功能
好友关注
基于Set集合的关注、取消关注,共同关注等等功能,这一块知识咱们之前就讲过,这次我们在项目中来使用一下
达人探店
基于List来完成点赞列表的操作,同时基于SortedSet来完成点赞的排行榜功能
1、短信登录
1.1、导入黑马点评项目
1.1.1 、导入SQL
1.1.2、有关当前模型
手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的事HTTP协议,可以实现基于Lua直接绕开tomcat访问redis,也可以作为静态资源服务器,轻松扛下上万并发, 负载均衡到下游tomcat服务器,打散流量,我们都知道一台4核8G的tomcat,在优化和处理简单业务的加持下,大不了就处理1000左右的并发, 经过nginx的负载均衡分流后,利用集群支撑起整个项目,同时nginx在部署了前端项目后,更是可以做到动静分离,进一步降低tomcat服务的压力,这些功能都得靠nginx起作用,所以nginx是整个项目中重要的一环。
在tomcat支撑起并发流量后,我们如果让tomcat直接去访问Mysql,根据经验Mysql企业级服务器只要上点并发,一般是16或32 核心cpu,32 或64G内存,像企业级mysql加上固态硬盘能够支撑的并发,大概就是4000起~7000左右,上万并发, 瞬间就会让Mysql服务器的cpu,硬盘全部打满,容易崩溃,所以我们在高并发场景下,会选择使用mysql集群,同时为了进一步降低Mysql的压力,同时增加访问的性能,我们也会加入Redis,同 ...
基础篇[Redis]
Redis安装
首先准备一台虚拟机
参考VMware16的安装及VMware配置Linux虚拟机(详解版)_何故M的博客-CSDN博客_vm16安装教程
当前使用centos7
centos 7 启动与切换图形界面
123456789systemctl get-default# 查看centos当前开机启动模式systemctl set-default graphical.target # 设置开机启动图形界面(GUI)systemctl set-default multi-user.target # 设置开机启动为命令行模式#快速切换#图形到dos:ctrl+alt+f2#dos到图形:输入startx
安装Redis
如果一直显示安装失败( 可以检查一下是否是网络出现问题 )
yum属于在线安装,及联网获取安装包,如果安装失败的话,一般和网络脱不了关系。
网络问题解决参考 : VMware 虚拟机里连不上网的五种解决方案_菜鸟也秃头的博客-CSDN博客_虚拟机上不了网
1.安装gcc与tcl
Redis依赖gcc与tcl环境, 因此需要先安装gcc以及tcl
安装gcc
注意需要切换到root
1yum install gcc-c++
安装tcl
1yum install -y tcl
2.安装并配置redis
下载redis压缩包
1wget https://download.redis.io/releases/redis-6.2.6.tar.gz
解压
1tar -zxvf redis-6.2.6.tar.g
把解压出来的目录移到/usr/local/bin/redis6
1mv redis-6.2.6 /usr/local/redis6
运行编译命令:
1make && make install
如果没有出错,应该就安装成功了。
默认的安装路径是在 /usr/local/bin目录下:
该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:
redis-cli:是redis提供的命令行客户端
redis-server:是redis的服务端启动脚本
redis-sentinel:是redis的哨兵启动脚本
3.启动Redis
redis的启动方式有很多种,例如:
默认启动
指定配置启动
开 ...
leetcode题目(4)
1694. 重新格式化电话号码
难度简单65
给你一个字符串形式的电话号码 number 。number 由数字、空格 ' '、和破折号 '-' 组成。
请你按下述方式重新格式化电话号码。
首先,删除 所有的空格和破折号。
其次,将数组从左到右每 3 个一组分块,直到 剩下 4 个或更少数字。剩下的数字将按下述规定再分块:
2 个数字:单个含 2 个数字的块。
3 个数字:单个含 3 个数字的块。
4 个数字:两个分别含 2 个数字的块。
最后用破折号将这些块连接起来。注意,重新格式化过程中 不应该 生成仅含 1 个数字的块,并且 最多 生成两个含 2 个数字的块。
返回格式化后的电话号码。
题目解读
其实就是每三个字符添加一个分隔符,
处理最后剩的那一批字符, 如果是4个那么就 加成 - 2 - 2
如果是三个就继续 -3
如果是两个字符就是 -2
代码如下
123456789101112131415161718192021222324class Solution { public String reformatNumber(String number) { StringBuilder res = new StringBuilder(""); number=number.replace(" ","").replace("-","");// 删除- 以及空格 char[]chars=number.toCharArray(); for(int i=0;i<chars.length;i+=3){ if(res.length()!=0){ res.append("-"); } if(i+4>=chars.length){ if(i+3>=chars.length){ res.append(number.substring(i)); }else{ res.append(number.substring(i,i+2)).append("-").append(number.substring(i+2)); } ...
leetcode题目(3)
reverse ListNode
步步拆解:如何递归地反转链表的一部分 - 反转链表 II - 力扣(LeetCode)
1️⃣翻转整个链表
206. 反转链表
难度简单2760
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
基本的迭代写法, 不再赘述
1234567891011121314class Solution { public ListNode reverseList(ListNode head) { if(head==null||head.next==null) return head; ListNode pre=null; ListNode cur=head; while(cur!=null){ ListNode tmp=cur.next; cur.next=pre; pre=cur; cur=tmp; } return pre; }}
递归翻转链表
1234567ListNode reverse(ListNode head) { if (head.next == null) return head; ListNode last = reverse(head.next); head.next.next = head; head.next = null; return last;}
具体来说,我们的 reverse 函数定义是这样的:
输入一个节点 head,将「以 head 为起点」的链表反转,并返回反转之后的头结点。
明白了函数的定义,在来看这个问题。比如说我们想反转这个链表:
那么在我们输入reverse(head)后 , 会在这里递归
ListNode last = reverse(head.next);
这里不要去想递归的过程,
简单的递归还可以去想想, 复杂的递归凭空想象难以进行
我们直接来看递归的结果
结果:
再来看reverse的定义, 会在返回链表之后返回函数的头结点, 也就是上面的last
现在再来看下面的代码:
head.next.next = head;
接下来:
head.nex ...
(二)计算机的计算方法[计组]
转载自:计算机组成原理 – Here_SDUT (fangkaipeng.com)
根据实际学习内容有一定的添加以及修改
2.1 数据与文字的表示方式
2.1.1 实际数的表示方法
1.定点数表示法
将数据分为纯整数和纯小数两类,用n+1位表示一个定点数,xn为符号位,放在最左边,0表示正号,1表示负号。
故一个数 x 可以表示为 x=xnxn−1…x1x0
定点小数 x为纯小数:0≤|x|≤1−2−n
定点整数 x为纯整数:0≤|x|≤2n−1
计算机中多采用定点纯整数表示,将定点数表示的运算简称整数运算。
2.浮点数表示法
任何一个数都可以写成浮点数形式
小数点随着阶码的不同而浮动,数的范围和精度分别表示。
格式:N=S*rj
r : 基数, r=2 (与当前的数字的进制有关)
j : 阶码, 带符号的纯整数(定点整数)
S: 尾数, 带符号的纯小数(定点小数)
在机器中,尾数用定点小数形式表示,指数用定点整数形式表示,称为阶码。
3. 浮点数表示范围
4. 浮点数的规格化
规格化形式:
基数 r = 2 ,尾数最高位为 1
基数 r = 4 ,尾数最高 2 位不全为 0
基数 r = 8 ,尾数最高 3 位不全为 0
基数不同,浮点数的规格化形式不同。
规格化方式:
r = 2 左规 尾数左移 1 位,阶码减 1
右规 尾数右移 1 位,阶码加 1
r = 4 左规 尾数左移 2 位,阶码减 1
右规 尾数右移 2 位,阶码加 1
r = 8 左规 尾数左移 3 位,阶码减 1
右规 尾数右移 3 位,阶码加 1
基数 r 越大,可表示的浮点数的范围越大,基数 r 越大,浮点数的精度降低。
举例:
1.设 m = 4,n = 10,r = 2,求尾数规格化后的浮点数表示范围。
最大正数 = 2+1111∗0.1111111111=215∗(1−2−10)
最小正数 = 2−1111∗0.1000000000=2−15∗(2−1)=2−16 (尾数第一位规格化后必须为1)
最大负数 = 2−1111∗−0.1000000000=−2−15∗2−1=−2−16
最小负数 – 2+1111∗−0.1111111111=−215∗(1−2−10)
例 6.13 将 x = + 19/128 写成二进制定点数、浮点数及在定点机和浮点 ...
leetcode题目(2)
typora编辑的md文件过长会导致卡顿, 因此继续分文件存笔记
🎈62. 不同路径: DP
难度中等1542
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
dp数组定义: dp[i][j]表示 走到下标为(i,j) 的种数,
状态转移: 由于题目中规定机器人只能向下以及向右走, 那么对于当前的dp[i][j]
dp[i][j]=dp[i-1][j]+dp[i][j-1]
走到当前的坐标的路径种数就等于走到当前的坐标的左边以及上边的坐标的路径之和
dp数组初始化
为了方便后续的计算,我们可以直接初始化 第一行以及第一列的元素为1 , 因为机器人只能往下往右走
for (int i = 0; i < m; i++) dp[i][0]=1; for (int i = 0; i < n; i++) dp[0][i]=1;
返回值: 返回dp[m-1][n-1] 表示走到终点的路径总数
12345678910111213class Solution { public int uniquePaths(int m, int n) { int[][] dp=new int[m][n];// dp[i][j]表示走到i ,j 的路径的种数 for (int i = 0; i < m; i++) dp[i][0]=1; for (int i = 0; i < n; i++) dp[0][i]=1; for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } return dp[m-1][n-1]; }}
🎈63. 不同路径 II :DP
难度中等876
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机 ...
(一)计算机系统概论[计组]
课堂内容+ 视频教程1.1 计算机组成原理(唐朔飞)_哔哩哔哩_bilibili
转载自:计算机组成原理 – Here_SDUT (fangkaipeng.com)
根据实际学习内容有一定的添加以及修改
1.1 计算机的分类
一、两大类
电子模拟计算机:数值由连续量表示,运算过程连续,受干扰大。
电子数字计算机:按位运算,不连续地跳动计算,抗干扰能力强。
二、电子计算机分类
专用计算机:最高效、经济、快速的方式,适应性差。
通用计算机:适应性强,牺牲效率、速度、经济性,细分为超级计算机、大型机、服务器、PC机、单片机、多核机。
1.2 计算机的发展简史
1.2.1计算机五代变化
1946-1957 电子管计算机——数据处理机
1958-1964 晶体管计算机——工业控制机
1965-1971 中小规模集成电路计算机——小型计算机
1972-1990 大规模和超大规模集成电路计算机——微型计算机,分为:多板机(多个印刷板)、单板机、单片机(一个芯片)
1991- 现在 巨大规模集成电路计算机——单片机
1.2.2 计算机的性能指标
衡量计算机性能的基本指标
响应时间(执行时间、等待时间)
吞吐量 (带宽): 表征一台计算机在某 一时间间隔内能够处理的信息量。
基本的性能评价标准是:CPU的执行时间
基准程序:专门用来进行性能评价的一组程序 , 用基准程序来评测计算机的性能
运算速度
响应时间:表征从输入有效到系统产生响应之间的时间度量,用时间单位来度量,包括等待时间和处理时间。
利用率:在给定的时间间隔内系统被实际使用的时间所占的比率,用百分比表示,实际处理时间/响应时间。
处理机字长:指处理机运算器中一次能够完成二进制数运算的位数,如32位、64位。
总线宽度:一般指CPU中运算器与存储器之间进行互连的内部总线二进制位数。
存储器容量:存储器中所有存储单元的总数目, 通常用KB、MB、GB、TB来表示。
存储器带宽:单位时间内从存储器读出的二进制数信息量,一般用字节数/秒表示。
主频/时钟周期:CPU的工作节拍受主时钟控制,主时钟不断产生固定频率的时钟,主时钟的频率(f)叫CPU的主频。度量单位是MHz(兆赫兹)、GHz(吉赫兹)。主频的倒数称为CPU时钟周期(T),T=1/f, 度量单位是μs、ns。 ...
(零)前置知识--数字电路[计组]
前置知识–数字电路[计组]
一.晶体三极管与数字电路
物体按导电性可以分为:
绝缘体:不导电 (塑料, 橡胶 , 陶瓷)
导体: 双向导电(金银铜铁等)
半导体:单项导电(硅锗等)
导电性介于绝缘体和导体之间, 加热单向导电,冷却绝缘
三极管: 集电极,发射极,基极 (相当于一个电子开关)
实现逻辑取反的功能
输入1 => 0
输入0 => 1
如果我们把两个晶体三极管并联在一起:
1.两种基础的门电路:
与非门
或非门
(1)与非门
输入输出
A
B
输出
0
0
1
0
1
1
1
0
1
1
1
0
总结:
两路输入都高, 才为低
两个三极管都导通 , 输出低电平
(2)或非门
输入输出
A
B
输出
0
0
1
0
1
0
1
0
0
1
1
0
总结:
任何一路输入为高, 输出都为低
两个三极管都导通 , 输出低电平
在此基础上可以制作 与门, 或门 电路
2.三态门电路
是具有三种逻辑状态的门电路, 是构成计算机总线的理想电路
输出状态取决于输入信号与控制信号
三态
低电平(0)
高电平(1)
高阻态(截止)
输出高阻态:
输入与输出信号直接处于截止状态, 电路与所连接的线路断开
输入输出
G
D
输出: Q
0
0
0
0
1
1
1
任意
高阻
通过三态门我们可以改变信号传输的方向
二.逻辑运算与数字电路
1.电路中的信号
模拟信号 :随着时间连续变化的信号
数字信号: 时间和幅度都是离散的
2.基础逻辑运算⭐
逻辑表达式
运算逻辑符号
逻辑真值表
与
或
Y=A+B
非
与非
或非
与或非
同或
异或
3.基础门电路⭐
注意电路中的"小圆圈" , 表示的是取非的意思
异或: 相异为一 ,相同为零
同或: 相异为零 ,相同为一
4.异或电路的特殊功能举例
(1)控制输入输出信号之间的关系
记为 F=A^c
设置控制信号C=0
此时,输出信号等于输入信号F=A
A=1 F=1A=0 F=0
设置控制信号C=1
此时,输出信号等于输入信号取反F ...

![实战篇(3):优惠券秒杀[Redis]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/e017d5fed2K88RY.jpg)
![实战篇(2):商户查询缓存[Redis]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/a949a0e835Hco6n.jpg)
![实战篇(1):短信登录[Redis]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/e89c2d5ac1VKhiR.jpg)
![基础篇[Redis]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/149a8bdf31m2m1u.jpg)


![(二)计算机的计算方法[计组]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/09a0b025fdfbQ5F.jpg)





