Dawn-K's Blog

「From ashes to the empire」

「操作系统」 系统调用

系统调用 应用程序执行系统调用 受限直接执行(LDE, limited direct execution)是操作系统的关键底层机制之一,让用户程序受限的运行在硬件上,只是在进行危险操作时向操作系统发出请求。 现代 CPU 存在两个状态 (intel 有 4 个,不过 linux 只使用其中的两个),一个是用户态,一个是内核态。 操作系统为了保护资源,自身是运行在内核模式的,能够执行所...

「C++」 可执行文件与加载

编译后文件的结构 加载 程序的内存布局 注意,这是说的进程,要和可重定向文件和可执行文件的结构分开。 linux x86-64 中,代码段总是从地址 0x400000 开始, bss 段 (bss segment) 通常是指用来存放程序中未初始化的全局变量的一块内存区域。 数据段 (data segment) 通常是指用来存放程序中已初始化的全局变量的一块内存区域。 ...

「操作系统」 进程同步

进程同步 临界区 我们假设 balance 是个全局变量,多线程同时执行以下操作。 1 balance = balance + 1 以上这句并不是原子性的,分为三步(实际上更复杂,还涉及到多CPU情况下的问题,比如有可能写入某个核自身的缓存,未必被其他核可见) 读取balance的值 将读到的值加1 将计算后的值写回内存 如果两个线程同时执行上面这行代码,就会产生...

「Linux」 用户管理

创建用户 将用户加入 sudo 首先要安装 sudo ,然后通过 usermod添加。 -a 表示追加, -G 后跟用户组 1 usermod -aG sudo <username> 检查一下是否成功。 1 sudo whoami # 输出为 root 则为正常

「软件工程」 metaprogramming

概述 The Missing semester 的 metadataprograming 这节课不是讲某个特定的技术, 也并不是讲编程语言中的元编程, 而是讲软件工程中的一些工具. 构建工具 大型复杂的软件通常构建起来也很复杂. 有很多的步骤, 而且步骤之间还有依赖关系. 构建工具就能帮助我们自动化的进行构建过程, 并且在每次构建时都会分析出最少需要新构建的内容. 以 make 为例....

「CodeNote」 kickstart2022D

Kickstart 2022 D 这场 700 名多点,除了D的大数据点之外都过了。 A. Image Labeler Image Labeler 题意 给你 n 个任务,m个分类。每个任务都有一个值,将这些任务分配给这些类别。要求每个任务只能属于一个类别,且一个类别里面至少有一个任务。每个类别的值是其中所有任务的中位数。最终分数是所有类别的值的和。求这个和的最小值。 范围 1...

「Linux」 X11 转发

X11 转发 背景 X11 是 linux 目前使用的图形界面,是 cs 架构,可以在 linux 上运行 server,然后在另一台计算机上运行 client,这样就可以通过网络实现界面的转发。 使用场景有很多,比如虚拟机,云服务器,WSL。 参考资料 linux 配置 linux 安装 xorg 组件 首先要安装好 server 端,也就是要转发的系统。以 archlinu...

「垃圾回收的算法和实现」 第七章-分代垃圾回收

分代垃圾回收 背景 分代垃圾回收基于这样一个事实: 很多对象出生不久就会死亡 已经存在了很久的对象在未来一段时间内大概率还是存活 分代垃圾回收并没有创造新的算法,而是根据代的不同而采用不同的算法。对象刚创建是新生代,然后存活一段时间后就 晋升 老年代。 JVM 中就是这个算法。 Ungar 的分代垃圾回收 堆空间总的分为两个,一个是新生代空间,一个是老年代空间。其中新...

「垃圾回收的算法和实现」 第六章-保守式 GC

保守式 GC 背景 保守式 GC 并不是一种算法。而是要针对之前的一些问题进行更现实的讨论。 比如我们之前的所有判断都基于一点,就是算法本身能直接分辨出一个域是指针还是其他类型。这个实际上是不一定的。我们可以假设一种语言,这种语言本身没有 gc,gc 只是作为一个附加库存在的,gc 面对内存时,只能看见一个一个的字节。 在这种情况下,普通类型是很容易被误认为指针的。比如前文复用对象的...

「垃圾回收的算法和实现」 第五章-标记压缩算法

标记压缩算法 思路 标记压缩算法也是移动对象进行垃圾回收的算法。不过和 gc 复制不同的是,它自始至终只使用一个空间。每次复制的时候,都是向堆的低地址端进行复制,就像把所有活动对象一口气挤到了最左端,把垃圾挤没了一样。 算法实际上是不可能一遍就直接把对象给挪到合适的位置的。因为如果直接挪动的话,会无法修正其指向子对象的指针。 所以需要两次扫描,一次先设定好这个对象要去的位置,把指针也...