Welcome to my blog! 👋

  • “再见是为了再次相见”     —《EVA》
  • Hi,这里是我记录笔记的地方,如果你感兴趣,可以通过下面的方式找到我一起交流学习!

C++何时会阻止默认的特殊成员函数的生成

在C++中,编译器会根据类的定义情况自动决定是否生成默认的特殊成员函数(如构造函数、拷贝/移动操作、析构函数)。 1. 用户显式声明相关成员函数 显式声明或删除某个函数: 如果用户显式声明(即使使用 =default 或 =delete)某个特殊成员函数,编译器将不再生成默认版本。例如: class Example { public: Example() = default; // 允许生成默认构造函数 Example(const Example&) {} // 用户定义的拷贝构造函数 // 编译器不再生成默认的移动构造函数和移动赋值运算符 }; 2. 用户定义析构函数、拷贝/移动操作的影响 定义析构函数: 如果用户定义了析构函数(即使为空),编译器会删除默认的移动操作(移动构造函数和移动赋值运算符),但拷贝操作仍可能生成(除非其他条件阻止)。 class Example { public: ~Example() {} // 用户定义的析构函数 // 移动操作被隐式删除,拷贝操作可能生成(若无其他限制) }; 定义拷贝操作: 如果用户定义了拷贝构造函数或拷贝赋值运算符,编译器会删除默认的移动操作。 class Example { public: Example(const Example&) {} // 用户定义的拷贝构造函数 // 移动操作被隐式删除 }; 定义移动操作: 如果用户定义了移动构造函数或移动赋值运算符,编译器会删除默认的拷贝操作。 #include <utility> #include <string> #include <iostream> struct Example { std::string str; Example() = default; Example(const std::string& s): str(s) { std::cout << "Example()\n"; } Example(Example&& other) { str = std::move(other....

2025-03-13 · 1 min · 157 words · Kerolt

【CMU15-445 Fall2023】Project3 Query Execution 小结

该系列博客只是为了记录自己在写Lab时的思路,按照课程要求不会在Github和博客中公开源代码。欢迎与我一起讨论交流! 这个project和之前就不一样了,开始深入数据库内核的实现了。需要理清楚一条sql语句是如何被执行的,方才能写出代码。 前置奶酪 一条SQL语句的执行 这里需要去看看一条sql语句传入bustub内部之后的代码:src/common/bustub_instance.cpp:ExecuteSqlTxn: auto BustubInstance::ExecuteSqlTxn(const std::string &sql, ResultWriter &writer, Transaction *txn, std::shared_ptr<CheckOptions> check_options) -> bool { if (!sql.empty() && sql[0] == '\\') { // 处理元命令 ... } // binder,但是在其中会使用libpg_query来解析sql语句 bustub::Binder binder(*catalog_); binder.ParseAndSave(sql); // 经过上一步后,binder中的statement_nodes_存储着所有的语句解析节点 for (auto *stmt : binder.statement_nodes_) { // 将stmt转换成BoundStatement对象,方便后面处理数据 auto statement = binder.BindStatement(stmt); // 只有不需要构建plan树、不需要进行优化的sql语句才会在switch之后继续执行 switch (statement->type_) { ... } // 生成初步的执行计划 bustub::Planner planner(*catalog_); planner.PlanQuery(*statement); // 优化刚刚的执行计划 bustub::Optimizer optimizer(*catalog_, IsForceStarterRule()); auto optimized_plan = optimizer.Optimize(planner.plan_); ....

2025-03-11 · 10 min · 1995 words · Kerolt

Hugo配置Github Actions

最近把博客的构建工具从Hexo换成了Hugo,感觉Hugo配置和使用起来更简洁方便。 由于我的博客总体来说有两个仓库,一个私有仓库是放置建站工具的目录,其中包含博客 Markdown 内容、一些配置还有主题;另一个就是通过 GitHub Pages 来访问公共仓库。为了方便,之前在使用 Hexo 的使用使用了 Github Actions 来一键部署博客,换成 Hugo 后这个 actions 需要修改一下。 .github/workflows/hugo.yml: name: GitHub Pages on: push: branches: - master # 监听 master 分支的推送事件 pull_request: jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: submodules: true # 拉取 Hugo 主题子模块 fetch-depth: 0 # 获取完整提交历史 - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: '0.126.2' extended: true - name: Build run: hugo --minify # 启用压缩优化 - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: personal_token: ${{ secrets....

2025-02-07 · 1 min · 132 words · Kerolt

Linux下微信无法使用中文输入法问题解决

微信在不久前终于有了Linux原生版本,我的电脑是Fedora41,之前安装的是flatpak打包的微信,现在在官网下载rpm包后运行发现无法使用fcitx的中文输入法,找了一下是环境遍历的问题。 ...

2024-12-31 · 1 min · 28 words · Kerolt

在VSCode中配置LLDB

为了 CMake Tool 能调试代码,先装好 codelldb 插件,然后还需要一个 launch.json 文件,以下内容可以一键配置好调试: { "version": "0.2.0", "configurations": [ { "name": "LLDB", "type": "lldb", "request": "launch", "program": "${command:cmake.launchTargetPath}", "args": [], "cwd": "${workspaceFolder}", } ] }

2024-12-31 · 1 min · 29 words · Kerolt

【MIT6.S081】Lab10 mmap

什么是mmap? mmap 是一种用于将文件或设备与进程的地址空间关联起来的内存映射技术。通过 mmap,可以将文件的内容直接映射到进程的虚拟内存地址空间,使得文件的内容可以像操作普通内存一样进行读取和写入。 ...

2024-11-22 · 5 min · 1017 words · Kerolt

【MIT6.S081】Lab9 file system

Intro 在这个实验中,我们需要让xv6支持更大的文件和软链接。实验总体不是特别难,不过需要我们理解好文件系统是如何工作的。Lab8 lock中的Buffer Cache也是文件系统的一部分,不过它位于文件系统的下层,这里我们需要处理的更多在上层,偏应用层。 ...

2024-11-19 · 4 min · 784 words · Kerolt

【MIT6.S081】Lab8 lock

Intro 这个实验个人感觉挺难的,需要我们重新设计数据结构,还要考虑在并发(并行)情况下对于锁的操作,以减少多核情况下对于锁的竞争。其中主要涉及内存分配和IO缓冲块分配,在这个lab之前,xv6对于这两个分配都是使用的全局对象,并只有一把全局锁进行操作,这样的话在并行情况下锁的竞争是很激烈的,我们的任务就是重新设计这两个分配器,它们的重构思路并不完全一致,需要具体问题具体分析。 ...

2024-11-17 · 5 min · 859 words · Kerolt

【MIT6.S081】xv6进程调度分析

在做thread lab的时候,阅读xv6的源码后对于进程调度的实现有了大致的了解,但是其中锁的获取与释放顺序让我困惑了好久:在yield函数中,不是先获取了进程p的锁吗,那么之后在调度器中又获取p的锁,那不是会死锁吗?在调度器内使用swtch发生进程切换后,又会跳转到哪里? 而在我观摩大佬的一些博客和视频后,发现我之前的想法有很大的问题,归根结底是没有弄明白xv6何时发生了切换,切换后应该从哪里开始运行。这篇笔记就是对于分析xv6进程调度的总结。 ...

2024-11-16 · 2 min · 326 words · Kerolt

【MIT6.S081】Lab6 multithreading

本次的实验总体都不是很难,第一个练习让我们在用户态模拟了线程的切换,这里重要的就是进程/线程上下文的保存与恢复;第二三个练习则是让我们跳出了xv6,去熟悉pthread库和线程的同步互斥。 ...

2024-11-15 · 4 min · 669 words · Kerolt