类似于 CS61C 提出的体系结构经典 idea
6.824 Lab2B Raft
2022.12.18 完成了 Lab2B
Livelock
有时会发生这种情况
类似地nextIndex[]
并重试
错误地认为 log 冲突导致不必要的删除
在 Raft Paper Figure 2 中
If an existing entry conflicts with a new one (same index but different terms), delete the existing entry and all that follow it.
我曾经在比较 term 时出错
这会导致问题的场景是
助教的这篇博文也提到了这一问题
这个 bug 是我阅读代码发现的
CommitIndex 的激进更新导致某些机器做出错误 commit
问题在于
If leaderCommit > commitIndex, set commitIndex = min(leaderCommit, index of last new entry).
这个 new 很重要nextIndex[]
并重试 AppendEntry RPCnextIndex[]
减少到正确值的时候发送
要定位这个 bug 还是很困难的
Committing entries from previous terms
我在 Leader 上的 CommitIndex 更新采用的方法是matchIndex[]
中第 n/2+1
大的数
复读大三
开学的时候
目标
考虑到我同时需要科研以及工作效率并不如想象中高
- 严格按照要求完成实验
主要关注分数要求, 所有通过性测试必须通过( 跑分性测试达到较高分数线, 和任务点要求) 如 6.s081 的( 两个功能选择一个实现“ 不能不选” ) - 清楚明白地了解自己在做什么
不能做完实验还感到有哪里含糊, 不清楚、 如果有疑问。 至少需要具体地列出来, 并在能力范围内尝试解决,
更高的要求包括
视前几周的精力情况决定要不要做6.824
计划
目前的计划
如果计划理想进行
注意到这里没有编译原理
本文每周一更新
进度记录
2022.9.20
这周突然特别想手搓OS
2022.12.18
成功地复刻了之前的每个学期都没能坚持学完网课的历史…好在这学期不是一事无成
手搓 OS 在虚拟机里已经跑得很不错了
bomb lab 做完了
6.824 lab 2B 今天刚刚做完
科研方面在做一个DSL
6.824 Lab1 MapReduce
前前后后做了15个小时PASSED ALL 30 TESTING TRIALS
的那一刻
概述
这个实验要求实现经典论文MapReduce的模型
实现过程流水账
先读论文花了3h左右
然后开始实现if-else
第二次写代码之前switch-case
今天是第三次碰这个东西
第一个教训
把语言学明白 : 勤编译勤测试 , 。
我查看输出文件的前三行
第二个教训
测试要认真严谨 : 。
然后又改了若干年
做的不错的地方
- 画DFA
- 头脑不清楚的时候出门转转
可以花掉长达20分钟的时间, 但是回来之后你就复活了, !
想要做得更好的地方
- 阶段性编译
测试、 例如我的DFA设计好了。 这时候就可以测试下转移有没有问题, 然后再在转移前后加功能, 。 - 有设计测试点的能力
对于这个实验。 我是用户, 而且一定程度上可以说是赶时间, 所以用老师的脚本来测试, 调试没有什么错、 但是一旦成为真正意义上的开发者。 bug都要自己找, 不提开源社区之类( ) 需要有能力设计若干测试来检验自己的代码在各方面的正确性/性能, 这确实需要写一些。 没用的“ 代码” 但是它们通常很简单, 而且很有用, 如算法竞赛里的对拍程序和暴力程序( ) 例如。 我尽管知道各个操作的时间/空间复杂度, 但还是不知道我这个实现并发性如何, 究竟有多少CPU时间是overhead, 。 - 证明我的DFA的正确性
- Challenge
- 阅读老师的测试脚本
学习写脚本,
CF Edu123 题解
F. Basis
考虑一群在操作 2 下可以互相变换的数组
接下来考虑操作1
- 如果$arr'$只有一个数
就是说$arr$中全都是相同的数字, 我们发现$arr$一定可以由某个改写前有至少两个不同数的原型经一次操作1, $F(a, n)$生成: 于是不用对$arr$计数, 也就是说。 题目中给的$k>1$时, 不用考虑这种情况, 如果$k=1$。 输出1即可, 。 - 如果$arr'$不只有一个数
去掉$arr'$的最后一个数, 考察前面的那些数, 如果它们的$gcd$不为1。 则$arr$可以被别的原型由操作1生成, 不用对$arr$计数, 对一个$gcd$。 有$A(\lceil {n\over gcd}\rceil)$个原型可以被别的原型$a$生成, 将$arr$中每连续$gcd$个数绑定( 再计算原型数, 也就是$A(\lceil {n\over gcd}\rceil)$, ) 注意$A$是从2开始加的( 因为数字全部相同的原型并不能由操作1生成$arr$, ) 如果这个$gcd$是合数。 可能这些冗余数组会被它的因子删除多次, 需要控制这个次数, 解决方法是用mobius函数, 就是说。 对$gcd$: 我们计$\mu(gcd)$次$A(\lceil {n\over gcd}\rceil)$, 。
这里的mobius函数就是在对$gcd$的质因子集合$S$做容斥
对一个给定的$gcd$
也就是实现了
直接整除分块求这个东西的一个上界是
注意不是$O(n\sqrt{n}\log n)$
Trie树维护集合相交性
这篇文章讲一个 trick
维护一个结构
可以添加和删除集合 , 可以询问 , 对询问中给定的新集合 : 结构中有多少集合与之不交 , ?
用这个 trick
对两个集合 $A$ 和 $B$
$A\cap B=\emptyset$ 时形式上是$0^0$不定式
现在我们维护一个 Trie 树
然后考虑询问
ARC136题解
这场 ARC 比较考验观察能力
C - Circular Addition
收获的思路
- 在差分数组上看区间加减
- 问最小操作次数时
找几个下界, 尝试证明其最大值可以取到, 证明时可以尝试把创造过程逆转为消除过程。 因为消除时的信息更多, 而创造是在, 创造“ 信息” 。
我看到了第一个切入点
然后我发现过不了最后一个样例
按照题解来讲的话
实际应用中
- 观察总结此前得到的事实
提出猜想, - 代入样例
若有误返回1, - 尝试证明
若证伪返回1, - 如果证明或不会证而自信
开码, - 如果没证出来且不太自信
多造点样例, 再次手玩或对拍, 若有误返回1, 否则开码,
按照步骤
- $L_1<L_2$
此时数组中不可能有 0: 否则为了从 0 增加到 $L_2$, 差分数组中正值部分至少是 $L_2$, 这与 $L_1<L_2$ 矛盾, 于是全体 -1 即可。 这样能使 $L_2$ 减小 1, 。 - $L_1>L_2$
如果数组中有 0: 我们只要挑选一段包含最大值的极大非零区间来全体 -1, 这样能使 $L_1$ 减小 1, 如果数组中没有 0。 数组中一定有若干, 山谷“ ” 所以一定可以找一段极大的, 连续最大值区间“ ” 要求其左右不再是最大值( 来减 1) 这能使 $L_1$ 减小 1, 。 - $L_1=L_2$
如果数组中有 0: 一定是单调增加到 $L_2$ 再单调减小到 0, 将非零部分 -1 即可同时减小 $L_1$ 和 $L_2$, 如果数组中没有0。 数组中一定有若干, 山谷“ ” 如果*极大的。 连续最大值区间“ *唯一” 那么将其减 1 即可, 否则。 一定可以找到一个区间覆盖所有的最大值, 例如除去最小值后获得的区间, 将这个区间全体减 1 即可。 。
把这个过程反过来想会变得更难想
D - Without Carry
收获
推荐博文
读完博文直接就会做了
E - Non-coprime DAG
收获我观察能力低下
- 不够耐心
一条思路还没想透彻就放弃, - 可以把结论写出来
更容易发现规律, 形式的不同会影响思考方式,
在看题解之前
对 $i<j$
- $i\equiv 0,\;j\equiv 0$
此时一定可达, 。 - $i\equiv 0,\;j\equiv 1$
此时来到了第一个重要观察, 可以尝试经过 $j - f(j)$ 这一偶数到达 $j$: 所以不超过 $j-f(j)$ 的偶数都 ok, 即要求$i\leq j-f(j)$, 而比它大的偶数。 和 $j$ 的差距已经小于其最小质因子了, 没有机会走到 $j$ 了, 。 - $i\equiv 1,\;j\equiv 0$
类似于 2, 要求$i+f(i)\leq j$, 。 - $i\equiv 1,\; j\equiv 1$
此时来到了第二个重要观察, 也是我卡住的地方, 由于我没有将上面的观察列出来。 我并没有注意经过偶数到达奇数这条路, 或者隐约觉得这效率低下, 其实这个类比还是比较明显的。 大脑好用时起码可以猜一个结论出来, 先写结论。 $i+f(i)\leq j-f(j)$ 即可: 首先。 两者都是奇数, 这就决定了只加一个, 一定为奇的( 质因数并不能使 $i$ 到达 $j$) 至少要加 2 个, 如果想由偶数搭桥。 显然, i -> i+f(i) -> j-f(j) -> j
的路径就是最优的 如果不这样做。 要么 $i,j$ 有公因子, 此时 $i+f(i)\leq j-f(j)$ 必成立( 或者仍然可以理解为从偶数搭桥, ) 要么还是需要转到 $j-fac(j)$ 再转到 $j$, 其中 $fac(j)$ 是 $j$ 的某个因子, 而这一个转变最少也要加 $f(i)$。 转变后最少也要再加 $f(j)$ 到达 $j$, 本质还是从偶数搭桥, 。
现在我们获得了
- $i+1\leq j$
- $i+1\leq j-f(j)+1$
- $i+f(i)\leq j$
- $i+f(i)\leq j-f(j)+1$
可以总结为
$i$ 可达 $j$ $\Leftrightarrow$ $up(i)\leq low(j)$
再次总结这个表达
ARC135题解
F暂时有个地方没搞明白
C - XOR to All
关键在于发现若干次操作一定可以等价于一次操作
假设进行了多次操作
现在只需要比较选择每个数对数组元素之和的影响
E - Sequence of Multiples
赛后自己做出来了
下面记题目描述的数列本身为$A_i$
初见端倪的朴素算法
观察一个特殊的例子
证明
于是我们发现这个$k$的变化趋势是很重要的
在特殊例子上构造$\{B_n\}$会给我们一些最基本的认识
为了解出$B_i\leq i+1$的时刻
得到了$\{A_i\}$的变化趋势1e18 1e18
的输入需要计算20秒
正解
$B_i$有一个类似于反比函数的
在Linux上使用clash
更新
以下为原文
以东方网络为例
步骤
- 在releases页面中下载最新版clash内核
一般的64位机器下载amd64版本即可, 解压后为一个可执行文件。 重命名为, clash
后执行chmod +x clash
为其加上执行权限。 - 在机场网站上下载配置文件
命名为, config.yaml
执行, ./clash -t -f config.yaml
如果没有问题说明配置文件正确, 。 - 执行
./clash -f config.yaml
开启代理服务, 。 - 配置系统代理
选择"use manually specified proxy configuration": 填入代理日志显示的代理地址+端口号, - 配置浏览器使用系统代理/配置浏览器代理指向clash
现在应该已经可以访问google了。 如果不行。 检查配置文件的mode, 如果是direct, 改成rule或者global, 。 - 按照官方wiki的步骤将其配置为守护进程
。
这样就足以支持日常需求了
页面调度算法
最优调度算法为什么最优
我们发现换页时换入的页总是固定的
- 如果A在下次访问A前未被调出
那么换出A仍能使得下次访问B前B未被调出, - 如果A在下次访问A前被调出了
那么换出A有可能可以使得B不用被调出, 因为B的下次访问更早,
于是换出A一定不比换出B差
堆栈式算法
堆栈式算法是指
堆栈式算法的好处
这种算法没有Belady现象
证明
最优调度算法/LRU为什么是堆栈式算法
用数学归纳法
假设对某个访问序列满足$S\subset S'$
若$P\notin S'$
综上
这个证明的核心在于