CMU15445(2025 Fall) lab PROJECT #0 - C++ PRIMER + 环境配置(VS2026+WSL2)

前言

发现前几年做的15445内容忘得差不多了,最近再来搓一遍玩玩。

由于教授要求非public,本博客将不会出现完整代码,顶多出现代码片段。

项目依旧基于C++17构建,现在看来当年算新鲜的标准已经有点落后了()

相关链接

官方网站
之前做23Spring的环境配置
FAQ(发现这个版本还专门提了池先森。。)

相关环境

配置:14700K + 64G
IDE:Visual studio 2026 insiders
主机环境:Windows11
Linux环境:WSL2 + Ubuntu24.04

0. 环境配置

本次选用Visual Studio配合WSL2搭建环境,关于VS,安装这个东西:
在这里插入图片描述

Github仓库

然后拉仓库,参考官方链接

首先创建一个私有库
在这里插入图片描述
记下来URL:
在这里插入图片描述

WSL配置

在WSL里创一个文件夹,然后拉公共仓库并镜像到自己的仓库:

git clone --bare https://github.com/cmu-db/bustub.git bustub-public
cd bustub-public
git push git@github.com:JMC2002/15445_25Fall.git master # 记得换成你自己的!

在这里插入图片描述

删除本地克隆,拉取自己的,这里建议用https,不然很慢

cd ..
rm -rf bustub-public 
git clone https://github.com/JMC2002/15445_25Fall.git # 记得换成你自己的!

在这里插入图片描述
将公共仓库添加为第二个远程用来更新:

git remote add public https://github.com/cmu-db/bustub.git

git remote -v

在这里插入图片描述
拉取公共仓库的更改,这样更新:

git pull public master

由于是私有仓库,我们禁用Action,免得用完配额
在这里插入图片描述
然后我们运行脚本安装必要的包:

sudo build_support/packages.sh

在这里插入图片描述
构建:

mkdir build
cd build
cmake ..
make

这里提一下,这个年份默认是用的clang15,如果你想要别的版本的话就同时改一下安装脚本和cmake:
在这里插入图片描述
在这里插入图片描述
另外,这里可能会跳一个警告,说你的编译器用的不是clang-15怎么怎么样,就手动指定一下编译器再make:

cmake .. -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15
make

此外,make的时候默认是单线程,很慢,可以这样线程拉满编译:

rm -rf build
mkdir build && cd build

cmake .. -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15

make -j$(nproc)

单线程的时候用了两分多钟
在这里插入图片描述
这里开了28线程半分钟就搞好了:
在这里插入图片描述
本地测试:

make check-tests

在这里插入图片描述
由于还没开始写,会报错,这是正常的,后面我们就用这个测试。

Visual Studio

VS直接打开WSL的项目的话会卡卡的,不好用,这里我们在Windows里再拉一份,刚刚我们做好了自己的仓库,这里直接克隆下来:
在这里插入图片描述

接下来,我们在Windows上用VS打开,选择打开文件夹,比如我这是\\wsl.localhost\Ubuntu\home\jmc\15445_25fall\15445_25Fall

在打开后,可能啥也看不见,这个时候我们在解决方案资源管理器里选择文件夹视图:
在这里插入图片描述
这时候可能会扫描到我们的CMake然后弹配置,如果没弹的话就找到本地文件夹,然后删掉.vs后再打开这个文件夹试试
在这里插入图片描述
选择我们需要的WSL主机:
在这里插入图片描述
然后在设置里选择始终使用CMake预设
在这里插入图片描述
这里会默认给一个Linux-Debug,我们点这个管理配置
在这里插入图片描述
插入这样一段,其中,debug模式下开启了"BUSTUB_SANITIZER": "address,leak"


    {
      "name": "wsl-clang-debug",
      "displayName": "WSL: Ubuntu (Clang Debug)",
      "description": "在WSL上使用Clang15",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/out/build/${presetName}",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "BUSTUB_SANITIZER": "address,leak",
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
        "CMAKE_C_COMPILER": "clang-15",
        "CMAKE_CXX_COMPILER": "clang++-15"
      },
    {
      "name": "wsl-clang-release",
      "displayName": "WSL: Ubuntu (Clang Release)",
      "description": "在WSL上使用Clang15",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/out/build/${presetName}",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
        "CMAKE_C_COMPILER": "clang-15",
        "CMAKE_CXX_COMPILER": "clang++-15"
      },
      "environment": {
      },
      "condition": {
        "type": "equals",
        "lhs": "${hostSystemName}",
        "rhs": "Linux"
      },
      "vendor": { "microsoft.com/VisualStudioRemoteSettings/CMake/2.0": { "remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}" } }
    },

在这里插入图片描述
随便选一个启动项,比如bustub-shell
在这里插入图片描述
运行,然后发现跳了个异常,因为我们没实现,说明环境配置大功告成,可喜可贺!

这时候我们发现git不可信任:
在这里插入图片描述
我们右键信任即可。
然后就可以做第一个提交了:
在这里插入图片描述
然后在Git>管理远程仓库中添加一个public用来拉取公共库的更新,提取写https://github.com/cmu-db/bustub.git,推送也可以写这个(反正也推不上去,不用管):
在这里插入图片描述
或者也可以Ctrl+ˋ打开命令行,然后直接执行前面那几个命令拉取:
在这里插入图片描述

注册账号

gradescope注册个号,点击右上角Sign Up
在这里插入图片描述Student
在这里插入图片描述
课程号填5R4XPZ(2025Fall),学校填Carnegie Mellon University,填好其他信息及邮件,会给你的邮箱发送一封设置密码的邮件,密码要求最短12位。这个验证码是专门提供给非CMU学生的,来自FAQ
弄好后是这样的,可以提交:
在这里插入图片描述

1. Project 0

OK,终于可以开始做Project0了,这里我会详细演示一下工作流,以及简单点评一下这个Project。

签出分支

我们做每一个project前,先签出一个分支,做完后再合并回master(因为后一个project往往强依赖于前一个),这样避免把代码搞乱
在这里插入图片描述

在这里插入图片描述

作业背景

这次的p0与前几次大相径庭,是做一个并发数据结构在这里插入图片描述
先给了你一个背景,假设你是一个网站管理员,现在你想找哪个IP的访问量最大,最直接的想法是用一个哈希表(ip, cnt)去存每个IP对应的访问次数,但这在数据量很大的时候占用的内存是非常高的,于是引入了CM Sketch这个东西。

这个是一种概率数据结构,简单来说,前面哈希表存的key太多,那我直接不存key本身,改为直接维护哈希值的计数,这样就省去了很大的内存开销,但是很显然,哈希函数是有冲突的,因此我们可以在每一个IP插入的时候,做depth次哈希,给每次哈希算出来的哈希值加一个计数,在要查询的时候再次做depth次哈希,找到里面的最小值,认为这个最小值就是我们IP的计数,这样尽管严格来说还是不完全准确,但可以得到一个相对准确的计数值。

内存上,假设我们把哈希值(比如取模之类的、相当于再做一次哈希)约束到width内,我们只需要维护一个w*d的二维数组,就减少了很多内存。

Task

然后看一下任务,我们要实现的就是一个构造函数(带参+移动构造)、一个移动赋值、插入、查询、清除、合并、查询TopK
在这里插入图片描述
有几点注意事项是要使用他提供的哈希函数、在做插入时要线程安全,同时还要杜绝一把大锁锁完的情况,锁尽量细粒度或者无锁
在这里插入图片描述

文件

我们要写的就是这个count_min_sketch.h/count_min_sketch.cpp
在这里插入图片描述

一些细节

  • 我们可以存一个std::unique_ptr<std::atomic<uint32_t>[]> table_;,就可以避免使用锁了
  • Top-k的时候,可以使用std::nth_element+std::sort,先做快选再排k,这样的时间复杂度是 O ( n + k log ⁡ k ) O(n+k\log k) O(n+klogk),类似的可以用std::partial_sort,这样的时间复杂度是 O ( n log ⁡ k ) O(n\log k) O(nlogk),考虑到 k k k一般比较小,还是选前者比较好
  • 原始的哈希函数产生器是捕获的this指针,在做移动的时候,如果直接std::move哈希函数数组就会导致垂悬引用,因此我们在捕获的时候改为值捕获width即可

提交代码

写完代码后,我们选择count_min_sketch_test
在这里插入图片描述
如果没问题的话,在远程控制台就能看到测试通过的输出以及跑分
在这里插入图片描述
这个时候正常就该跑一下clang-tidy的检查了

make format
make check-clang-tidy-p0

我们打开终端、选择WSL,正常应该启动就在这个目录,或者在外面开一个终端也行:
在这里插入图片描述
打开~/.vs/15445_25Fall/out/build(这个路径对应之前填的地方)
在这里插入图片描述
然后打开对应的文件,进去就可以看到cmake生成的文件了
在这里插入图片描述
由于我们之前用的生成器是ninja,因此这里执行:

ninja format
ninja check-clang-tidy-p0

最后不报错就说明检查通过:
在这里插入图片描述
关于内存泄漏检测,如果你使用前面我提供的设置,换用Debug跑一下能过就行。

另外,值得注意的一点是,提交要求UTF-8,右下角这里如果不是UTF-8的话需要手动保存成UTF-8(无签名)
在这里插入图片描述
此外,不知道为什么直接本地format不会应用头文件顺序的检查,因此最好手动把头文件按字母顺序排列一下,免得提交上去格式检查不通过。

一切无误后,生成一个提交

ninja submit-p0

如果是全新的环境,可能需要安装zip

sudo apt update
sudo apt install zip

然后可以看见生成了一个zip到(生成的)项目根目录下
在这里插入图片描述
然后提交
在这里插入图片描述
提交上去后会自动给你打分
在这里插入图片描述
等一会后就会显示是否通过/哪个地方没通过:
在这里插入图片描述

合并分支

通过后就可以合并分支了,先推送更改:
在这里插入图片描述
然后切换到master,再右键p0,合并到当前分支:
在这里插入图片描述
顺便还能打一个tag:
在这里插入图片描述

3. 结语

本文也算开了个头,演示了一下这个东西的基本工作流程,后面应该就不会把工作流写这么细了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值