好久没更博客了 , 暑假参加字节青训营,记录一下备战经历,水水博客 。
因该博客持续更新,文中部分链接是写该博客时预存占坑位的,如有忘记补充的,烦请大佬踢我一下!
数据结构与算法部分
1、以下哪些排序算法是不稳定的?
A. 快速排序
B. 归并排序
C. 基数排序
D. 堆排序
答案:AD
选项A 解析请点击 【深度剖析】 快速排序为什么不稳定?!
选项D 解析请点击 【深度剖析】堆排序为什么不稳定?!
不稳定的排序算法有 选择排序、希尔排序、堆排序、快速排序助记:
选
(选择排序)艾希
(希尔)堆
(堆排序)攻速
(快速排序)下路不稳
(不稳定)。选艾希堆攻速下路不稳
!
2、在最好情况下,下列排序算法中,哪些排序算法所需比较的关键次数最少?
A. 冒泡
B. 归并
C. 快速
D. 直接插入
答案:AD
A. 冒泡 排序,最好情况 是待排序序列已经是有序的情况,此时冒泡排序仍然需要进行一轮比较来确认序列已经有序,但不需要进行任何元素的交换操作。假设待排序序列的长度为n,冒泡排序算法只需要进行一轮比较,所需比较的 关键次数 为 n-1 次。
B. 归并 排序,最好情况 为,每次合并操作时,两个子序列的长度相等,并且每个元素只需比较一次即可确定其位置。因此,对于长度为n的序列,需要进行log2(n)次合并操作,即 归并排序算法所需比较的 关键次数 为 n * log2(n) 次。
C. 快速 排序,最好情况 为,每次选择的基准元素都刚好是当前子数组的中位数,将数组均匀地分割成两个大小相等的子数组。最终完成排序时,需要进行log₂(n)次分割,每次分割都需要n/2-1次比较,因此总共所需比较的 关键次数 为 (n/2-1)log₂(n) 次。
D. 直接插入 排序,最好情况 为 待排序的数组已经是按照升序排列,这种情况下,每个元素只需与它前面的一个元素进行比较。此时所需比较的 关键次数 为 n-1次。更多排序内容可见 【基础算法】细说十大排序!
3、关于红黑树以下说法正确的是?
A. 红黑树是平衡二叉树,任意两个子树的高度差不超过 1
B. 红黑树从一个节点到该节点的子孙节点的所有路径上包含相同数目的红色节点
C. 红黑树插入节点时最多经过 3 次旋转达到平衡
D. 红黑树进行插入操作时需要解决红红冲突
答案:CD
需要明确,红黑树是一种自平衡的二叉搜索树,具有以下性质:
- 根节点和所有叶子结点(NIL节点)是黑色。(根叶黑)
- 每条从根到叶子的路基上不能出现连续两个红色节点。(不红红)
- 从任一节点到所有叶子结点的路径上的黑色节点数量相同。(黑路同)
A. 红黑树并不是严格的平衡二叉树,而是近似平衡的二叉树。从根节点到任意叶子节点的 最长路径不超过最短路径 的
两倍
,而不是限制子树的高度差不超过 1。
B.从一个节点到该节点的子孙节点的所有路径上包含相同数目的 黑色 节点, 从而 保证了红黑树的黑色平衡性。
C .插入最多2次旋转达到平衡、删除最多3次旋转达到平衡;所以红黑树最多三次旋转达到平衡
D. 在红黑树中,当插入一个红色节点导致红色节点与其父节点均为红色时,就会产生红红冲突。解决红红冲突的操作称为红黑树的插入修复操作,通常包括旋转和颜色调整等步骤。关于红黑树内容,详细可见 【深情数据结构】红黑树 | 你就是我心中的红黑树,平衡了我的感情,让我在爱的世界找到根基
4、关于排序算法以下结论正确的是?
A. 归并排序任何情况下都能保持时间复杂度为 O(n*log n)
B. 插入排序时间复杂度为 O(n2),所以在任何情况下都比快速排序慢
C. 快速排序的最坏情况下的时间复杂度为 O(n2)
D. 希尔排序任何情况下都比插入排序更快
答案:AC
B.对于非常小的输入规模或者已经接近有序的输入序列,插入排序可能会表现得更好。
D.非常小的输入规模或者已经接近有序的输入序列,或者输入数据具有一定的分布特性,使得希尔排序的间隔序列不利于快速减少逆序对的数量,插入排序可能比希尔排序更快更多排序可见 【基础算法】细说十大排序!
5、以下哪些是解决哈希冲突的手段?
A. 拉链
B. 开放地址
C. 再散列
D. 滑动窗口
答案:ABC
ABC 详见 【深情数据结构】哈希表是爱情的默契,快速映射出彼此的特性和情感
D.滑动窗口 主要用于处理数据流或时间序列的技术,并非解决哈希冲突的手段
6、关于 MD5 以下哪些说法是正确的?
A. MD5 可以用于加密密码
B. MD5 不可逆
C. 对于不同的输入, MD5 一定输出不一样的结果
D. 对于不同长度的输入,MD5 一定输出相同长度的结果
答案:BD
C.MD5 可能输出相同的结果
更多内容可参考 【计算机安全】MD5 | 唯一密码,爱的安全守护者
7、以下哪些是操作系统中堆和栈的区别?
A. 增长方向
B. 空间大小
C. 分配方式
D. 管理方式
答案:ABCD
堆 和 栈 的区别主要有以下几点:
- 管理方式不同。
栈
的管理方式是后进先出(LIFO),即最后分配的内存最先释放。由操作系统自动分配释放,无需我们手动控制。每次函数调用会压入栈帧,函数返回时会弹出栈帧,使得栈的管理非常高效。堆
的管理方式是通过指针来进行,开发者需要手动跟踪和管理堆中分配的内存,确保在不需要使用时及时释放,否则会导致内存泄漏。 `- 空间大小不同。每个进程拥有的
栈
大小要 远远小于堆
的大小。栈
的大小是固定的,由操作系统预先分配,用于存储局部变量、函数调用等。堆
的大小是动态的,由开发者手动申请和释放。理论上进程可申请的堆大小为虚拟内存大小,进程栈的大小64bits的Windows默认1MB,64bits的Linux默认10MB;- 生长方向不同。
堆
的生长方向向上,内存地址由低到高;栈
的生长方向向下,内存地址由高到低。- 分配方式不同。
堆
都是 动态分配的,没有静态分配的堆。栈
有2种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配是由alloca()函数分配,但是栈的动态分配是由系统进行释放,无需我们手工实现。- 分配效率不同。
栈
是由系统自动分配,会在硬件层次对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆
则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请与管理容易产生内存碎片,故堆的效率比栈低的多。
8、常见的存储系统 IO 性能优化方式有哪些?
A. 尽可能多设计随机读写逻辑
B. 预读
C. 减少 IO 路径上的内存拷贝
D. batch 写入
答案:BCD
9、以下哪些操作可能触发本地 CPU cache 失效?
A. 本地读取
B. 本地写入
C. 远端读取
D. 远端写入
答案:D
10、Client 在使用 Https 协议访问网站进行通信的过程中,以下说法正确的是?
A. 只用到了对称加密技术
B. 只用到了非对称加密技术
C. 没有用到任何加密技术
D. 同时用到了对称加密和非对称加密技术
答案:D
11、建立 TLS1.2 连接需要几次握手?
A. 3
B. 4
C. 6
D. 7
答案:D
- Client Hello:客户端向服务器发送 Client Hello 消息,包含支持的加密套件和其他参数。
- Server Hello:服务器选择加密套件和其他参数,并向客户端发送 Server Hello 消息作为响应。
- Certificate:服务器发送包含其数字证书的消息,以验证其身份。
- Server Key Exchange:如果服务器需要,它将发送 Server Key Exchange 消息,包含用于密钥交换的额外信息。
- Certificate Request:服务器可以要求客户端发送其数字证书,以进行客户端身份验证。
- Client Key Exchange:客户端生成密钥并向服务器发送 Client Key Exchange 消息,包含用于密钥交换的信息。
- Finished:客户端和服务器分别发送 Finished 消息以验证握手过程的完整性。
12、在 MTU=1500 字节的以太网中,TCP 报文的最大分段大小为多少字节?
A. 1440
B. 1460
C. 1420
D. 1480
答案:B
MTU这个概念是指数据帧中有效载荷的最大长度,不包括帧首部的长度。所以TCP报文的有效载荷=1500B-20B(IP数据报首部)-20B( TCP报文首部)=1460
13、以下哪些是 RDBMS 跟常见的对象存储系统的不同点?
A. 数据库支持事务
B. 数据库向用户暴露 put/get 接口
C. RDBMS 一般存储结构化数据
D. 数据库里的数据不能修改,只能删除后重新写入
答案:AC
14、MySQL 数据库中是通过以下哪种日志实现 MVCC 机制的?
A. Undo Log
B. Redo Log
C. Binary Log
D. Slow Log
答案:A
15、关于 Go 语言以下结论正确的是?
A. 在多核机器中,核数越多,使用多个 goroutines 写入 sync.Map 的性能越好
B. 只调用一次 rand.Seed,则之后 rand.Int 的生成序列是固定的
C. 放入 sync.Pool 中的结构体可能随时被回收
D. Goroutine 的栈不仅会增长而且还会缩容
答案:BCD
16、以下哪些是 Go 支持的指针运算?
A. 通过 & 取地址
B. 对指针进行自增
C. 下标运算
D. 通过 * 解引用
答案:AD
17、Go 中关于整型切片的初始化,以下正确的是?
A. s := []int{1, 2, 3, 4, 5}
B. s := make([]int)
C. s := make([]int, 0)
D. s := make([]int, 5, 10)
答案:ACD
18、关于经典的 Skiplist(原始论文实现)以下结论正确的是?
A. 每次的查找都从 head 节点的第 0 层(最底层)开始寻找
B. skiplist 的插入节点的层级都是固定的
C. skiplist 的元素都是有序的
D. skiplist 平均查询时间复杂度为 O(log n)
答案:CD
- 每次的查找都从 head 节点的最顶层开始查找
- 跳表的插入节点的层级是随机的,使用了randomLevel概率算法来确定节点的层级
实现一个 36 进制的加法 0-9 a-z。
示例
输入:[“abbbb”,“1”],输出:“abbbc”
先转换为 十进制,加减后,再转换为 三十六进制
#include
using namespace std;
string change_r(long long n, int r)
{
if (!n)
return "0";
string ans;
while (n)
{
if (n % r < 10)
ans += (n % r) + '0';
else
ans += (n % r) - 10 + 'a';
n /= r;
}
reverse(ans.begin(), ans.end());
return ans;
}
long long change_10(string num, int r)
{
long long ans = 0;
for (int i = 0; i < num.length(); i++)
{
if (num[i] >= '0' && num[i] <= '9')
ans = ans * r + num[i] - '0';
else
ans = ans * r + num[i] - 'a' + 10;
}
return ans;
}
int main()
{
string n,m;
cin >> n >> m;
int n1,m1;
n1 = change_10(n,36);
m1 = change_10(m,36);
n1 -= m1;
cout << change_r(n1,36);
return 0;
}
具体思路讲解 可以参考 【算法基础】十进制与其他进制的转换