2023年4月13日 23:27 周四科目
#
1022/9:00-11:30
- 00024 普通逻辑 2010
- 02197 概率论与数理统计(二)2018
- 02318 计算机组成原理 2016
- 02324 离散数学 2014
- 02331 数据结构 2012
- 03709 马克思主义基本原理概论 2018
- 04747 Java语言程序设计(一) 2019
1022/14:30-17:00
- 00023 高等数学(工本) 2019
- 00342 高级语言程序设计(一)2017
- 02326 操作系统 2017
- 04730 电子技术基础(三) 2006
- 04735 数据库系统原理 2018
1023/09:00-11:30
- 02325 计算机系统结构 2012
- 03708 中国近现代史纲要 2018
- 04737 C++程序设计 2019
1023/14:30-17:00
- 0015 英语(二)2012
- 02333 软件工程 2011
- 04741 计算机网络原理 2018
2023年4月5日 17:23 周三yum源替换成阿里云
#
yum install -y wget
## 备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
## 下载
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
## 重建缓存
yum clean all
yum makecache
Java环境搭建
#
yum search java | grep jdk
yum install -y java-1.8.0-openjdk-devel.x86_64
# java -version 正常
# javac -version 正常
解压相关
#
-zxvf
tar -zxvf redis* -C /usr/local/redis*
# z :表示 tar 包是被 gzip 压缩过的 (后缀是.tar.gz),所以解压时需要用 gunzip 解压 (.tar不需要)
# x :表示 从 tar 包中把文件提取出来
# v :表示 显示打包过程详细信息
# f :指定被处理的文件是什么
# 适用于参数分开使用的情况,连续无分隔参数不应该再使用(所以上面的命令不标准),
# 应该是 tar zxvf redis* -C /usr/local/redis*
主题修改
#
oh my zsh
...
2023年3月29日 17:23 周三安装
#
虚拟机向导
#
- 典型—稍后安装–linux–RedhatEnterpriseLinux7 64
- 虚拟机名称rheCentos700
- 接下来都默认即可(20G硬盘,2G内存,网络适配器(桥接模式))
安装界面
#
日期–亚洲上海,键盘–汉语,语言支持–简体中文(中国)
软件安装
最小安装—> 兼容性程序库+开发工具
其他存储选项–配置分区
- /boot 1G 标准分区,文件系统ext4
- swap 2G 标准分区 ,文件系统swap
- / 17G 标准分区,文件系统ext4
网络和主机名
打开网络+设置主机名(rheCentos700)
完成—过程中配置密码 默认用户root+其他用户ly
安装完成后修改ip及网关
#
Centos
#
vi /etc/sysconfig/network-scripts/ifcfg-ens**
修改部分键值对
BOOTPROTO="static"
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=223.5.5.5
DNS2=223.6.6.6
systemctl restart network
Debian
#
查看当前网卡
ip link
#1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
# link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
#2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
# link/ether 00:0c:29:ed:95:f5 brd ff:ff:ff:ff:ff:ff
# altname enp2s1
得知网卡名为ens33
...
2023年3月14日 22:34 周二转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
本文来自公号 MySQL 技术,JavaGuide 对其做了补充完善。原文地址:https://mp.weixin.qq.com/s/d5OowNLtXBGEAbT31sSH4g
优化 SQL 的第一步应该是读懂 SQL 的执行计划。本篇文章,我们一起来学习下 MySQL EXPLAIN 执行计划相关知识。
什么是执行计划?
#
执行计划 是指一条 SQL 语句在经过 MySQL 查询优化器 的优化会后,具体的执行方式。
执行计划通常用于 SQL 性能分析、优化等场景。通过 EXPLAIN 的结果,可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引可以被命中、哪些索引实际会命中、每个数据表有多少行记录被查询等信息。
如何获取执行计划?
#
-- 提交准备数据
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dept_emp
-- ----------------------------
DROP TABLE IF EXISTS `dept_emp`;
CREATE TABLE `dept_emp` (
`id` int(0) NOT NULL,
`emp_no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`other1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`other2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `index_emp_no`(`emp_no`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dept_emp
-- ----------------------------
INSERT INTO `dept_emp` VALUES (1, 'a1', 'o11', '012');
INSERT INTO `dept_emp` VALUES (2, 'a2', 'o21', 'o22');
INSERT INTO `dept_emp` VALUES (3, 'a3', 'o31', 'o32');
INSERT INTO `dept_emp` VALUES (4, 'a4', 'o41', 'o42');
INSERT INTO `dept_emp` VALUES (5, 'a5', 'o51', 'o52');
SET FOREIGN_KEY_CHECKS = 1;
MySQL 为我们提供了 EXPLAIN 命令,来获取执行计划的相关信息。
...
2023年3月12日 17:53 周日转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
题目来源于:
牛客题霸 - SQL 必知必会
检索数据
#
select 用于从数据库中查询数据。
从 Customers 表中检索所有的 ID
#
现有表 Customers 如下:
编写 SQL 语句,从 Customers 表中检索所有的 cust_id。
答案:
select cust_id
from Customers;
检索并列出已订购产品的清单
#
表 OrderItems 含有非空的列 prod_id 代表商品 id,包含了所有已订购的商品(有些已被订购多次)。
编写 SQL 语句,检索并列出所有已订购商品(prod_id)的去重后的清单。
答案:
select distinct prod_id
from OrderItems;
知识点:distinct 用于返回列中的唯一不同值。
检索所有列
#
现在有 Customers 表(表中含有列 cust_id 代表客户 id,cust_name 代表客户姓名)
...
2023年3月12日 17:52 周日转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
本文整理完善自下面这两份资料:
基本概念
#
数据库术语
#
数据库(database) - 保存有组织的数据的容器(通常是一个文件或一组文件)。数据表(table) - 某种特定类型数据的结构化清单。模式(schema) - 关于数据库和表的布局及特性的信息。模式定义了数据在表中如何存储,包含存储什么样的数据,数据如何分解,各部分信息如何命名等信息。数据库和表都有模式。列(column) - 表中的一个字段。所有表都是由一个或多个列组成的。行(row) - 表中的一个记录。主键(primary key) - 一列(或一组列),其值能够唯一标识表中每一行。
SQL 语法
#
SQL(Structured Query Language),标准 SQL 由 ANSI 标准委员会管理,从而称为 ANSI SQL。各个 DBMS 都有自己的实现,如 PL/SQL、Transact-SQL 等。
SQL 语法结构
#

SQL 语法结构包括:
子句 - 是语句和查询的组成成分。(在某些情况下,这些都是可选的。)表达式 - 可以产生任何标量值,或由列和行的数据库表谓词 - 给需要评估的 SQL 三值逻辑(3VL)(true/false/unknown)或布尔真值指定条件,并限制语句和查询的效果,或改变程序流程。查询 - 基于特定条件检索数据。这是 SQL 的一个重要组成部分。语句 - 可以持久地影响纲要和数据,也可以控制数据库事务、程序流程、连接、会话或诊断。
SQL 语法要点
#
- SQL 语句不区分大小写,但是数据库表名、列名和值是否区分,依赖于具体的 DBMS 以及配置。例如:
SELECT 与 select 、Select 是相同的。 - 多条 SQL 语句必须以分号(
;)分隔。 - 处理 SQL 语句时,所有空格都被忽略。
SQL 语句可以写成一行,也可以分写为多行。
...
2023年2月27日 22:11 周一转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
主从复制原理

哨兵模式(简单)

哨兵模式详解
先配置主从模式,再配置哨兵模式
所有的哨兵 sentinel.conf 都是配置为监听master–> 192.168.14.101,如果主机宕机,sentinel.conf 中的配置也会自动更改为选举后的
Java客户端连接原理
客户端是和Sentinel来进行交互的,通过Sentinel来获取真正的Redis节点信息,然后来操作.实际工作时,Sentinel 内部维护了一个主题队列,用来保存Redis的节点信息,并实时更新,客户端订阅了这个主题,然后实时的去获取这个队列的Redis节点信息.
/**
代码相对比较简单
**/
//1.设置sentinel 各个节点集合
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.14.101:26379");
sentinelSet.add("192.168.14.102:26380");
sentinelSet.add("192.168.14.103:26381");
//2.设置jedispool 连接池配置文件
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(1000);
//3.设置mastername,sentinelNode集合,配置文件,Redis登录密码
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster",sentinelSet,config,"123");
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
//获取Redis中key=hello的值
String value = jedis.get("hello");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(jedis != null){
jedis.close();
}
}

...
2023年2月24日 09:31 周五转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
看到很多小伙伴简历上写了“熟练使用缓存”,但是被我问到“缓存常用的3种读写策略”的时候却一脸懵逼。
在我看来,造成这个问题的原因是我们在学习 Redis 的时候,可能只是简单了写一些 Demo,并没有去关注缓存的读写策略,或者说压根不知道这回事。
但是,搞懂3种常见的缓存读写策略对于实际工作中使用缓存以及面试中被问到缓存都是非常有帮助的!
下面介绍到的三种模式各有优劣,不存在最佳模式,根据具体的业务场景选择适合自己的缓存读写模式。
Cache Aside Pattern(旁路缓存模式)
#
Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。
Cache Aside Pattern 中服务端需要同时维系 db 和 cache,并且是以 db 的结果为准。
下面我们来看一下这个策略模式下的缓存读写步骤。
写 :
简单画了一张图帮助大家理解写的步骤。

读 :
- 从 cache 中读取数据,读取到就直接返回
- cache 中读取不到的话,就从 db 中读取数据返回
- 再把数据放到 cache 中。
简单画了一张图帮助大家理解读的步骤。

你仅仅了解了上面这些内容的话是远远不够的,我们还要搞懂其中的原理。
比如说面试官很可能会追问:“在写数据的过程中,可以先删除 cache ,后更新 db 么?”
答案: 那肯定是不行的!因为这样可能会造成 数据库(db)和缓存(Cache)数据不一致的问题。
举例:请求 1 先写数据 A,请求 2 随后读数据 A 的话,就很有可能产生数据不一致性的问题。
这个过程可以简单描述为:
请求 1 先把 cache 中的 A 数据删除 -> 请求 2 从 db 中读取数据【此时请求2把脏数据(对于请求1来说是)更新到缓存去了】->请求 1 再把 db 中的 A 数据更新,即请求1的操作非原子
...
2023年2月24日 09:26 周五转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
什么是内存碎片?
#
你可以将内存碎片简单地理解为那些不可用的空闲内存。
举个例子:操作系统为你分配了 32 字节的连续内存空间,而你存储数据实际只需要使用 24 字节内存空间,那这多余出来的 8 字节内存空间如果后续没办法再被分配存储其他数据的话,就可以被称为内存碎片。

Redis 内存碎片虽然不会影响 Redis 性能,但是会增加内存消耗。
为什么会有 Redis 内存碎片?
#
Redis 内存碎片产生比较常见的 2 个原因:
1、Redis 存储存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间。
以下是这段 Redis 官方的原话:
To store user keys, Redis allocates at most as much memory as the maxmemory setting enables (however there are small extra allocations possible).
Redis 使用 zmalloc 方法(Redis 自己实现的内存分配方法)进行内存分配的时候,除了要分配 size 大小的内存之外,还会多分配 PREFIX_SIZE 大小的内存。
zmalloc 方法源码如下(源码地址:https://github.com/antirez/redis-tools/blob/master/zmalloc.c):
void *zmalloc(size_t size) {
// 分配指定大小的内存
void *ptr = malloc(size+PREFIX_SIZE);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(zmalloc_size(ptr));
return ptr;
#else
*((size_t*)ptr) = size;
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)ptr+PREFIX_SIZE;
#endif
}
另外,Redis 可以使用多种内存分配器来分配内存( libc、jemalloc、tcmalloc),默认使用
jemalloc,而 jemalloc 按照一系列固定的大小(8 字节、16 字节、32 字节……)来分配内存的。jemalloc 划分的内存单元如下图所示:
...
2023年2月23日 23:02 周四转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
除了 5 种基本的数据结构之外,Redis 还支持 3 种特殊的数据结构 :Bitmap、HyperLogLog、GEO。
Bitmap
#
介绍
#
Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 Bitmap 本身会极大的节省储存空间。
你可以将 Bitmap 看作是一个存储二进制数字(0 和 1)的数组,数组中每个元素的下标叫做 offset(偏移量)。

常用命令
#
| 命令 | 介绍 |
|---|
| SETBIT key offset value | 设置指定 offset 位置的值 |
| GETBIT key offset | 获取指定 offset 位置的值 |
| BITCOUNT key start end | 获取 start 和 end 之前值为 1 的元素个数 |
| BITOP operation destkey key1 key2 … | 对一个或多个 Bitmap 进行运算,可用运算符有 AND, OR, XOR 以及 NOT |
Bitmap 基本操作演示 :
...