06 mysql all查询 和 主键查询 和 非索引列查询

news2024/9/24 11:22:45

前言

本文主要调试一下 mysql 的如下两种查询语句 

我们也来深入的看一下, 究竟如下两个普通的查询, mysql 做了什么事情 

1. select * from `user` where id = '991';

2. select * from `user`;

3. select * from `user` where name = 'jerry991';

 

 

环境介绍

测试表 `user` schema 如下 

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT '0',
  `name` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

`user` 表中的测试数据如下 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

 

select * from `user` where id = '991'

我们这里会着重介绍这个 case, 这里面会详细的看一下 index page, data page 的情况, 以及其具体的执行的流程 

另外这个过程中我们会忽略掉一些细节, 尽量只查看这个业务查询的核心业务流程 

 

 

获取 index page 

index -> page 为 3, 表示第三个 page 为索引页面, pageNo 初始化为 index->page, 该 page 的地址为 block->frame : 0x1217f4000 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们 inspect 一下 0x1217f4000 

可以看出 offset 为 3, 对应于上面的 pageNo 

pagePrev, pageNext 为 0xffffffff, 表示只有一个索引页面 

pageNDirSlots 表示当前 page 存在两个 pageDirectory 

pageHeapTop 表示当前页面的 FreeSpace 位于 0xa2 

pageNHeap 表示有 5 个元素, 三个索引元素 + infimum + supremum 

pageNRecords 表示有三个索引元素 

pageLevel 为 1 表示下面一级才是叶子节点[存储数据的节点] 

再看下面的索引信息 [1, 302) -> page4, [302, 719) -> page5, [719, supremum] -> page6 

(lldb) x 0x1217f4000 -c 0x100
0x1217f4000: c2 b7 03 ad 00 00 00 03 ff ff ff ff ff ff ff ff  ·.�....��������
0x1217f4010: 00 00 00 00 00 1d 34 e5 45 bf 00 00 00 00 00 00  ......4�E�......
0x1217f4020: 00 00 00 00 00 06 00 02 00 a2 80 05 00 00 00 00  .........�......
0x1217f4030: 00 9a 00 02 00 02 00 03 00 00 00 00 00 00 00 00  ................
0x1217f4040: 00 01 00 00 00 00 00 00 00 16 00 00 00 06 00 00  ................
0x1217f4050: 00 02 00 f2 00 00 00 06 00 00 00 02 00 32 01 00  ...�.........2..
0x1217f4060: 02 00 1b 69 6e 66 69 6d 75 6d 00 04 00 0b 00 00  ...infimum......
0x1217f4070: 73 75 70 72 65 6d 75 6d 00 10 00 11 00 0e 80 00  supremum........
0x1217f4080: 00 01 00 00 00 04 00 00 00 19 00 0e 80 00 01 2e  ................
0x1217f4090: 00 00 00 05 00 00 00 21 ff d6 80 00 02 cf 00 00  .......!��...�..
0x1217f40a0: 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x1217f40b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x1217f40c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x1217f40d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x1217f40e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x1217f40f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................


# FileHeader 
FIL_PAGE_SPACE = c2 b7 03 ad 
FIL_PAGE_OFFSET = 00 00 00 03 
FIL_PAGE_PREV = ff ff ff ff 
FIL_PAGE_NEXT = ff ff ff ff 
FIL_PAGE_LSN = 00 00 00 00 00 1d 34 e5 
FIL_PAGE_TYPE = 45 bf 
FIL_PAGE_FILE_FLUSH_LSN = 00 00 00 00 00 00 00 00 
FIL_PAGE_ARCH_LOG_NO = 00 00 00 06 

# PageHeader 
PAGE_N_DIR_SLOTS = 00 02 
PAGE_HEAP_TOP = 00 a2 
PAGE_N_HEAP = 80 05 
PAGE_FREE = 00 00 
PAGE_GARBAGE = 00 00 
PAGE_LAST_INSERT = 00 9a 
PAGE_DIRECTION = 00 02 
PAGE_N_DIRECTION = 00 02 
PAGE_N_RECS = 00 03 
PAGE_MAX_TRX_ID = 00 00 00 00 00 00 00 00 
PAGE_LEVEL = 00 01 
PAGE_INDEX_ID = 00 00 00 00 00 00 00 16 
PAGE_BTR_SEG_LEAF = 00 00 00 06 00 00 00 02 00 f2 
PAGE_BTR_SEG_TOP = 00 00 00 06 00 00 00 02 00 32 

# page4
0x 00 = nulls
0x 1 = delete flag
0x 0 = number of records owned by the record
0b 0000 0000 0001 0 = 2 = order number of this record
0b 001 = node pointer (inside B-tree)
0x 00 0e = next record offset -> page05
minId = 0x 80 00 00 01 = 1
pageNo = 0x 00 00 00 04

# page5
0x 00 = nulls
0x 0 = delete flag
0x 0 = number of records owned by the record
0b 0000 0000 0001 1 = 3 = order number of this record
0b 001 = node pointer (inside B-tree)
0x 00 0e = next record offset -> page06
minId = 0x 80 00 01 2e = 302
pageNo = 0x 00 00 00 05

# page6
0x 00 = nulls
0x 0 = delete flag
0x 0 = number of records owned by the record
0b 0000 0000 0010 0 = 4 = order number of this record
0b 001 = node pointer (inside B-tree)
0x ff d6 = next record offset -> supremum
minId = 0x 80 00 02 cf = 719
pageNo = 0x 00 00 00 06

 

根据 index page 确定数据所在 page 

通过上面 index page 里面的索引信息, 以及我们这里查询的 991 限定来确定数据属于哪一个 page 

这里的查询会有两层搜索, 通过 pageDirectory 的搜索, 通过最近的 pageDirectory 线性查询目标索引, 这里 991 属于 page6 

看这里的 low_rec, 指向的记录就是上面的 [719, supremum] -> page6 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

获取数据 page 

pageNo 为 6, 获取 page6, 该 page 的地址为 block->frame : 0x121804000 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们来 inspect 一下 0x121804000

(lldb) x 0x121804000 -c 0x100 
0x121804000: e5 86 89 21 00 00 00 06 00 00 00 05 ff ff ff ff  �..!........����
0x121804010: 00 00 00 00 00 1d a6 f8 45 bf 00 00 00 00 00 00  ......��E�......
0x121804020: 00 00 00 00 00 06 00 47 27 fc 81 1b 00 00 00 00  .......G'�......
0x121804030: 27 df 00 02 01 18 01 19 00 00 00 00 00 00 00 00  '�..............
0x121804040: 00 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00  ................
0x121804050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00  ................
0x121804060: 02 00 1c 69 6e 66 69 6d 75 6d 00 06 00 0b 00 00  ...infimum......
0x121804070: 73 75 70 72 65 6d 75 6d 08 00 00 00 10 00 24 80  supremum......$.
0x121804080: 00 02 cf 00 00 00 00 41 75 f1 00 00 01 e7 01 10  ..�....Au�...�..
0x121804090: 80 00 00 16 6a 65 72 72 79 37 31 39 08 00 00 00  ....jerry719....
0x1218040a0: 18 00 24 80 00 02 d0 00 00 00 00 41 76 f2 00 00  ..$...�....Av�..
0x1218040b0: 01 e8 01 10 80 00 00 16 6a 65 72 72 79 37 32 30  .�......jerry720
0x1218040c0: 08 00 00 00 20 00 24 80 00 02 d1 00 00 00 00 41  .... .$...�....A
0x1218040d0: 77 f3 00 00 01 e9 01 10 80 00 00 16 6a 65 72 72  w�...�......jerr
0x1218040e0: 79 37 32 31 08 00 04 00 28 00 24 80 00 02 d2 00  y721....(.$...�.
0x1218040f0: 00 00 00 41 78 f4 00 00 01 ea 01 10 80 00 00 16  ...Ax�...�......

# FileHeader 
FIL_PAGE_SPACE = e5 86 89 21 
FIL_PAGE_OFFSET = 00 00 00 06 
FIL_PAGE_PREV = 00 00 00 05 
FIL_PAGE_NEXT = ff ff ff ff 
FIL_PAGE_LSN = 00 00 00 00 00 1d a6 f8 
FIL_PAGE_TYPE = 45 bf 
FIL_PAGE_FILE_FLUSH_LSN = 00 00 00 00 00 00 00 00 
FIL_PAGE_ARCH_LOG_NO = 00 00 00 06 

# PageHeader 
PAGE_N_DIR_SLOTS = 00 47 
PAGE_HEAP_TOP = 27 fc 
PAGE_N_HEAP = 81 1b 
PAGE_FREE = 00 00 
PAGE_GARBAGE = 00 00 
PAGE_LAST_INSERT = 27 df 
PAGE_DIRECTION = 00 02 
PAGE_N_DIRECTION = 01 18 
PAGE_N_RECS = 01 19 
PAGE_MAX_TRX_ID = 00 00 00 00 00 00 00 00 
PAGE_LEVEL = 00 00 
PAGE_INDEX_ID = 00 00 00 00 00 00 00 16 
PAGE_BTR_SEG_LEAF = 00 00 00 00 00 00 00 00 00 00 
PAGE_BTR_SEG_TOP = 00 00 00 00 00 00 00 00 00 00 

# UserRecords 
jerry719 -> jerry720 -> jerry721 ... -> jerry999

 

我们来 inspect 一下 0x121807f00

从上面元数据可以知道, pageDirectory 总共有 71 个, 合计 142 字节, 加上末尾的 8 字节 FileTailer 合计 150 字节 

0x121807fff - 0x121807f6a + 1 = 0x96 = 150 字节 

可以看到这里的 pageDirectory 也是逆序排列的 infimum -> 0xeb -> 0x017b -> ... -> supremum [根据 id 排序]

(lldb) x 0x121807f00 -c 0x100
0x121807f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x121807f60: 00 00 00 00 00 00 00 00 00 00 00 70 27 2b 26 9b  ...........p'+&.
0x121807f70: 26 0b 25 7b 24 eb 24 5b 23 cb 23 3b 22 ab 22 1b  &.%{$�$[#�#;"�".
0x121807f80: 21 8b 20 fb 20 6b 1f db 1f 4b 1e bb 1e 2b 1d 9b  !. � k.�.K.�.+..
0x121807f90: 1d 0b 1c 7b 1b eb 1b 5b 1a cb 1a 3b 19 ab 19 1b  ...{.�.[.�.;.�..
0x121807fa0: 18 8b 17 fb 17 6b 16 db 16 4b 15 bb 15 2b 14 9b  ...�.k.�.K.�.+..
0x121807fb0: 14 0b 13 7b 12 eb 12 5b 11 cb 11 3b 10 ab 10 1b  ...{.�.[.�.;.�..
0x121807fc0: 0f 8b 0e fb 0e 6b 0d db 0d 4b 0c bb 0c 2b 0b 9b  ...�.k.�.K.�.+..
0x121807fd0: 0b 0b 0a 7b 09 eb 09 5b 08 cb 08 3b 07 ab 07 1b  ...{.�.[.�.;.�..
0x121807fe0: 06 8b 05 fb 05 6b 04 db 04 4b 03 bb 03 2b 02 9b  ...�.k.�.K.�.+..
0x121807ff0: 02 0b 01 7b 00 eb 00 63 14 23 33 ed 00 1d a6 f8  ...{.�.c.#3�..��

 

根据数据page 定位 id = 991

这里的查询会有两层搜索, 通过 pageDirectory 的搜索, 通过最近的 pageDirectory 线性查询目标索引, 这里 991 对应于 up_rec  

看这里的 up_rec, 指向的记录就是上面的 (991, 22, jerry991) 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们来 inspect 一下 up_rec, 正是我们这里期望查询的 id = '991' 对应的记录 

(lldb) x 0x1218066bf
0x1218066bf: 80 00 03 df 00 00 00 00 42 85 81 00 00 01 32 01  ...�....B.....2.
0x1218066cf: 10 80 00 00 16 6a 65 72 72 79 39 39 31 08 00 00  .....jerry991...

 

外部的业务函数 row_search_for_mysql

上面这里查询到了 id = '991' 对应的记录, 封装在了 pcur->btr_cur->page_cur->rec 里面 

上面的流程是在 row_search_for_mysql 的 btr_pcur_open_with_no_init 这里, 这里的作用就是初始化 pcur, 为后面的业务迭代做准备 

接下来走的便是根据 pcur->btr_cur->page_cur->rec 进行迭代, 比较是否符合查询条件, 输出记录信息到客户端等等流程 

 

所以这里会做的事情是, 当前 rec 是在 id = '991', 然后 比较是否符合查询条件, 这里是符合, 然后将记录输出到客户端 

然后会进入 prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE 的条件, 继续下一个元素的迭代 

迭代到 rec 是在 id = '992', 然后 比较是否符合查询条件, 这里是不匹配, 走的时候 normal_return, 退出查询 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们来 inspect 一下 0x1218066bf

(lldb) x 0x1218066bf
0x1218066bf: 80 00 03 df 00 00 00 00 42 85 81 00 00 01 32 01  ...�....B.....2.
0x1218066cf: 10 80 00 00 16 6a 65 72 72 79 39 39 31 08 00 00  .....jerry991...

 

迭代元素 id = '992'

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们来 inspect 一下 0x1218066e3 

(lldb)  x 0x1218066e3
0x1218066e3: 80 00 03 e0 00 00 00 00 42 86 82 00 00 01 35 01  ...�....B.....5.
0x1218066f3: 10 80 00 00 16 6a 65 72 72 79 39 39 32 08 00 00  .....jerry992...

 

explain 的结果

我们来看一下 explain 的结果, 会使用 primary key 来索引, 大约会扫描 1 行记录

20210331094127251.png

 

 

select * from `user`

初始化 pcur->btr_cur->page_cur->rec

这个查询相对来说 走的流程比较简单, 查询的最小的 数据page的 infimum, 然后不断往后迭代, 直到所有元素迭代完成 

这里是初始化 pcur->btr_cur->page_cur->rec 为最小的 数据page的 infimum 

这里的迭代是从 index page 开始的, 从 level 最高的 index page 开始向下迭代, 如果是 fromLeft 表示最终取最小的数据页的 infimum, 如果是 !fromLeft 表示最终取最大的数据页的 supremum 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

根据 pcur->btr_cur->page_cur->rec 进行迭代 

然后接下来就是不断地向后迭代, 输出查询的元素信息到客户端 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

当前 page 到达了末尾, 切换到下一个 page 

btr_pcur_is_after_last_in_tree 判断当前 page 是否是最后一个 page, 判断的方式是 pageNext 是否为 0xffffffff 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

explain 的结果

我们来看一下 explain 的结果, 全表扫描, 大约会扫描 906 行记录

20210331094249330.png

 

 

select * from `user` where name = 'jerry991'

初始化 pcur->btr_cur->page_cur->rec 

这里的初始化过程 和上面的 "select * from `user`" 的初始化是一样的, 初始化 pcur->btr_cur->page_cur->rec 为 page4->infimum 

然后不断向后迭代数据, 直到全表的数据迭代完成 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

我们来 inspect 一下 这一页的数据 

(lldb) x 0x11cf1c000 -c 0x100
0x11cf1c000: 94 8c b5 2e 00 00 00 04 ff ff ff ff 00 00 00 05  ..�.....����....
0x11cf1c010: 00 00 00 00 00 1d 34 e5 45 bf 00 00 00 00 00 00  ......4�E�......
0x11cf1c020: 00 00 00 00 00 06 00 36 3b 0d 81 a3 1d b0 1d 64  .......6;..�.�.d
0x11cf1c030: 00 00 00 05 00 00 00 d0 00 00 00 00 00 00 00 00  .......�........
0x11cf1c040: 00 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00  ................
0x11cf1c050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00  ................
0x11cf1c060: 02 00 1c 69 6e 66 69 6d 75 6d 00 01 00 0b 00 00  ...infimum......
0x11cf1c070: 73 75 70 72 65 6d 75 6d 05 00 00 00 10 00 21 80  supremum......!.
0x11cf1c080: 00 00 01 00 00 00 00 2b 07 04 00 00 01 56 04 7b  .......+.....V.{
0x11cf1c090: 80 00 00 1c 6a 65 72 72 79 04 00 00 00 18 00 20  ....jerry...... 
0x11cf1c0a0: 80 00 00 02 00 00 00 00 35 04 83 00 00 01 36 01  ........5.....6.
0x11cf1c0b0: 10 80 00 00 16 6c 75 63 79 06 00 00 00 20 00 22  .....lucy.... ."
0x11cf1c0c0: 80 00 00 05 00 00 00 00 3d 14 8a 00 00 01 91 01  ........=.......
0x11cf1c0d0: 10 80 00 00 16 6a 65 72 72 79 35 06 00 04 00 28  .....jerry5....(
0x11cf1c0e0: 00 22 80 00 00 07 00 00 00 00 3d 0b 84 00 00 01  ."........=.....
0x11cf1c0f0: 37 01 10 80 00 00 16 6a 65 72 72 79 37 06 00 00  7......jerry7...

 

根据 pcur->btr_cur->page_cur->rec 进行迭代 

然后接下来就是不断地向后迭代,  输出查询的元素信息到客户端 

todo, 这里根据条件过滤, 以及数据传递, 还需要再找找 

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMzkzMzI=,size_16,color_FFFFFF,t_70

 

 

完 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/908188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

极限学习机(ELM)的原理和matlab代码实现

单隐含层前馈神经网络(Single - hidden Layer Feedforward Neural Network,SLFN)以其良好的学习能力在许多领域得到了广泛的应用。然而,传统的学习算法(如 BP算法等)固有的一些缺点,成为制约其发展的主要瓶颈。前馈神经网络大多采用梯度下降方法,该方法主要存在以下几个方面的缺…

机器人操作系统【02】:如何在 ROS2 中对点云数据进行建模

一、说明 RViz和Gazebo中RADU的模拟进展顺利。在上一篇文章中&#xff0c;我们学习了如何启动机器人并使用远程节点进行操作。在本文中&#xff0c;我们将添加两个视觉传感器。首先&#xff0c;一个图像摄像机&#xff0c;用于在机器人四处移动时查看机器人的实时馈送。其次&am…

Nginx高可用集群

目录 一.简介二.案例1.实现思路2.配置文件修改3.实现效果故障转移机制 一.简介 以提高应用系统的可靠性&#xff0c;尽可能地减少中断时间为目标&#xff0c;确保服务的连续性&#xff0c;达到高可用的容错效果。例如“故障切换”、“双机热备”、“多机热备”等都属于高可用集…

03:TIM定时器

目录 一:TIM 1:介绍 2:定时器的分类 3:基本定时器 4:通用定时器 5:高级定时器 6:定时器的基本结构 二:定时中断功能 A:定时器定时器中断 1:连接图 ​编辑 2:步骤 3:函数介绍 4:代码 三:外部时钟功能 A:定时器外部时钟 1:连接图 2:函数介绍 3:外部时钟代码 一…

【FreeRTOS】【应用篇】任务创建

前言 从本篇开始&#xff0c;将不再太过于关心 FreeRTOS 的内核细节&#xff0c;把重心转移到对 FreeRTOS 的应用上来。 本篇代码大部分参考野火的 FreeRTOS 教程。 一、静态任务和动态任务创建的区别 1. 概念解析 在 FreeRTOS 中&#xff0c;我们可以选择两个不同的函数进…

微信小程序,封装身高体重选择器组件

wxml代码&#xff1a; // 微信小程序的插值语法不支持直接使用Math <wxs src"./ruler.wxs" module"math"></wxs> <view class"ruler-container"><scroll-view scroll-left"{{scrollLeft}}" enhanced"{{tru…

探索软件项目管理的本质及概念

什么是软件项目管理&#xff1f; 软件项目管理是指对软件项目从规划、组织、指挥、控制到最终交付的全过程进行有效管理的一种方法。它通过合理的资源分配、有效的沟通和高效的协作&#xff0c;确保软件项目能够按照预定的目标、时间和质量要求完成。在现代信息技术逐渐普及和…

互联网企业内部FAQ的设计指南:帮助企业用户快速解决常见问题!

在互联网企业中&#xff0c;内部FAQ&#xff08;Frequently Asked Questions&#xff09;是帮助企业用户快速解决常见问题的重要工具。一个优秀的内部FAQ不仅可以提高用户满意度&#xff0c;还可以减轻客服团队的负担。本文将介绍互联网企业内部FAQ的设计指南&#xff0c;帮助企…

知识储备--基础算法篇-动态规划

1.前言 第一次接触动态规划&#xff0c;不知道具体什么意思&#xff0c;做了题才发现动态规划就是把大问题变成小问题&#xff0c;并解决了小问题重复计算的方法称为动态规划。比如上楼梯&#xff0c;一次上一阶或二阶&#xff0c;求有多少种算法&#xff0c;就可以拆成最后一…

Flutter 小技巧之 3.13 全新生命周期 AppLifecycleListener

Flutter 3.13 在 Framework 里添加了 AppLifecycleListener 用于监听应用生命周期变化&#xff0c;并响应退出应用的请求等支持&#xff0c;那它有什么特殊之处&#xff1f;和老的相比又有什么不同&#xff1f; 简单说&#xff0c;在 Flutter 3.13 之前&#xff0c;我们一般都…

计网第三章(数据链路层)(五)

目录 一、以太网交换机自学习和转发帧的过程 1.两层交换机和三层交换机 2.以太网交换机的基本原理 3.具体实现过程 一、以太网交换机自学习和转发帧的过程 1.两层交换机和三层交换机 大家可能注意到平常做题时有叫两层交换机&#xff0c;或者三层交换机的。 两层交换机就…

为什么需要websocket?

一、为什么需要websocket&#xff1f; 前端和后端的交互模式最常见的就是前端发数据请求&#xff0c;从后端拿到数据后展示到页面中。如果前端不做操作&#xff0c;后端不能主动向前端推送数据&#xff0c;这也是http协议的缺陷。 因此&#xff0c;一种新的通信协议应运而生---…

使用kabeja库解析DXF格式文件

DXF格式是一种开源的CAD文件格式&#xff0c;如何实现Java代码对齐的解析&#xff0c;在网上找了很久&#xff0c;也没有找到非常成熟的库。很奇怪&#xff0c;开源的格式&#xff0c;正常应该会有很多的库来支持。只找到了一个kabeja库&#xff0c;最新版本还是2008年出的0.4版…

GTK3实现自定义列表

使用gtk,如果想自己定义列表,思路可以将每个列表项作为一个hbox,整个列表是一个vbox。通过对容器动态的添加删除,实现列表操作,同时添加任何自己所需要的控件。 下面的例子是实现一个显示图片、按钮和进度条的列表,并且进行上移下移,具有添加和删除列表项功能但没有演示…

网站巡查与SEO:爱校对如何确保内容的最佳质量?

随着互联网的飞速发展&#xff0c;企业和个人正在寻找优化他们网站内容的最佳方式。在这个数字化时代&#xff0c;网站巡查和SEO已成为维持网站高度相关性和可见性的关键。此时&#xff0c;工具如“爱校对”不仅帮助检查文本的质量&#xff0c;还确保内容对搜索引擎优化&#x…

STM32使用定时器实现微秒(us)级延时

STM32使用定时器实现微秒&#xff08;us&#xff09;级延时 引言前期准备介绍系统时钟定时器时钟 项目项目介绍STM32CubeMX程序 引言 目前开发STM32普遍使用HAL库&#xff0c;但 HAL 库封装的延时函数目前仅支持 ms 级别的延时&#xff0c;日常很多情况下会用到 us 延时&#…

IC封装——从基本概念到TSV

一、IC封装 在之前文章中有大致提过封装&#xff0c;这里展开讲讲 芯片生产流程_沧海一升的博客-CSDN博客每个半导体产品的制造都需要数百个工艺&#xff0c;泛林集团将整个制造过程分为八个步骤&#xff1a;晶圆加工-氧化-光刻-刻蚀-薄膜沉积-互连-测试-封装。_芯片生产流程h…

spring异步框架使用教程

背景 在需求开发过程中&#xff0c;为了提升效率&#xff0c;很容易就会遇到需要使用多线程的场景。这个时候一般都会选择建一个线程池去专门用来进行某一类动作&#xff0c;这种任务到来的时候往往伴随着大量的线程被创建调用。而还有另外一种场景是整个任务的执行耗时比较长…

ElasticSearch 7.4学习记录(DSL语法)

上文和大家一起初次了解了很多ES相关的基础知识&#xff0c;本文的内容将会是实际企业中所需要的吗&#xff0c;也是我们需要熟练应用的内容。 面对ES&#xff0c;我们最多使用的就是查询&#xff0c;当我负责这个业务时&#xff0c;现不需要我去考虑如何创建索引&#xff0c;添…

ubuntu18.04安装keil5(踩坑)看完再享用,别直接上手

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装winewine的总结 二、安装Keil5总结 前言 切记看完再享用&#xff0c;别直接上手&#xff0c;不然安装的时候会和我一样踩坑的&#xff08;走了很多弯路…