2025焦糖工作室招新

焦糖工作室是干什么的

是一个西点屋

焦糖工作室(Jotang Studio)是电子科技大学信软学院的一个学生技术团体,大家一起学习课业、打比赛、做科研和玩耍~

焦糖工作室全部由本科生组成,在这里可以拓宽技术的视野,和小伙伴们一起开展课程安排中没有的技术实践,焦糖的目标是让每一位成员都能得到成长

2025招新活动安排

工作室永远欢迎对技术和团队热爱的新人!无论你是大一还是大二,都可以加入这次技术马拉松赛,并在这个过程中掌握技能和探索自己的方向,相信你自己,很多事情没有那么难。

  1. 为期一个月的技术马拉松赛 从2025.9.5日开始,到2025.10.19日截止
  2. 工作室招新面试阶段:在技术马拉松中达到通过标准的同学可进入工作室面试阶段

如果你不是萌新,可以将简历发送到邮箱 jotang_recruit@outlook.com (邮件命名格式:年级-姓名-简历,如:21-段衍凯-简历),我们将组建专业团队(误)对简历进行评析并在3个工作日内给与答复。

规则

  • 完成任意题目后请将需要提交的内容放到新文件夹(命名格式为:题目序号-姓名,如#2-段衍凯),最终将所有文件打包(命名格式为:年级-姓名-发送日期-做题题号,如:21-段衍凯-9.14-127)并发送至邮箱 jotang_recruit@outlook.com
  • 完成度较高后,题目提交次数不限,且每次提交的都应是所有你要完成的题目的完整的解答,不要做一点交一点,以最后提交版本为准。
  • 每道题都需要提交记录了学习过程的markdown文件,如果要求代码,请上传至Github并将访问链接一同提交。如果你还不知道什么是Markdown和Github,请先做科普福利题#1 啥是Git#2 Markdown
  • 招新对题目数量不做硬性要求,你可以深入一题,体现你的技术深度,也可以“我全都要”,探索自己的兴趣方向。
  • 如果需要与我们交流(比如题目太简单了,题目出现错误等等),请同样写下你的具体想法发送邮件到上述邮箱,或者在招新群中找到对应的出题人私聊
  • 截止日期后约半个月的时间里,我们会根据 题目的完成度 和在 Markdown文档记录与细节 给出评分表,并将其汇总为一个总评分表,达到通过标准的同学可以进入面试阶段
  • 科普福利向题目是帮助同学们热身和入门学习的,请一定至少选择一道代码技能向题目完成,题目的完成度最重要
  • PS:
    • 诚信是Jotanger的底线,一旦我们发现解答中存在严重的copy现象,无论技术力如何,我们都将拒绝您的加入
    • 在马拉松过程中,如若题目有表述不清或其他问题和疑问,请及时反馈给出题者。出题者在招新群中统一以 2024#题号-姓名 (如2024#1-段衍凯)命名
    • 焦糖时刻欢迎各位萌新在群里提问,也鼓励同学间互帮互助。但焦糖依然希望同学们养成在提问前先自行谷歌的习惯,因而对于一些能直接Google百度出来的答案,焦糖学长们可能不会全部解答,望理解。

题目目录

科普福利向(科班基础,强烈推荐完成)

专业技能向(至少选择一个完成)

焦点计划

焦点计划是面向 24 级对机器学习机器学习系统感兴趣的同学的,难度相对大一些,当然,25 级的有能力的同学也可以完成。

1 Like

#0 Let’s Warm Up!

欢迎加入这场奇妙的冒险!:sparkles:
这是 JoTang Studio 招新系列 的开胃菜——热身题。

焦糖工作室为 202[4-5] 级的小伙伴们(没错,正则就是这么万能)精心设计了若干题目。它们不会让你从一开始就卷到掉头发,而是让你自由选择:

  • 想要深入某个方向?ok,沉浸其中。
  • 想要多点尝鲜?也行,了解多个方向。

目标只有一个:让你认识到软件的世界远比你想象的要广阔,请尽情探索自己感兴趣的方向吧! :earth_asia:


新人日常 vs 老鸟日常

萌新:师兄!这代码为何报错?
大佬:少侠,请先问问“谷哥”。
萌新:谷哥无果啊!
大佬:那便前往 Stack Overflow 武林圣地。
萌新:小的功力太浅,恐怕一去不返……

别慌,焦糖是友好型社团,我们不会丢下你自生自灭。接下来就带你从最基础的技能点开始。


搜索必修课 :mag_right:

遇到问题的第一反应是什么?
不是“学长/学姐救我”,而是——搜索

  • 通用搜索引擎:Google(万能选手),Bing/百度(搜中文时勉强能用,不推荐)。
  • 新工具 bonus:2023 年之后,AI 工具已经成为大家的“编程搭子”。许多AI工具可供选择:ChatGPTDeepSeekPoeQwen等等。它们各有特色:有的回答更细致,有的更擅长写代码,有的对中文支持更友好。B 站上有不少教程教你如何注册chatgpt账号(前提是你得会科学上网),也有免科学上网的替代方案,按需选择就行。
  • 聚合推荐:虫部落快搜
  • 想要进阶?试试这些 搜索引擎高级指令

如果是编程相关问题:

“为什么 Google 打不开?” “这就是为什么每一个程序员都需要学会科学上网” :point_right: 推荐科普文:深入理解 GFW


提问的艺术 :bulb:

搜索不够时,才轮到提问。
但提问也分水平:差的问题没人回,聪明的问题收获满满。

推荐阅读:How To Ask Questions The Smart Way

一句话总结:你提问的方式,决定了别人愿不愿意帮你。


计算机的世界:远比你想的要大 :milky_way:

刚入学时,很多同学以为 “学计算机 = 前端 / 后端”
但其实,这只是打怪的新手村。真正的地图远不止于此:

  • 前端 / 后端开发:让你能从 0 到 1 搭建一款能跑起来的网站或应用。
  • 人工智能 & 机器学习:和大模型、数据打交道,调教出能写诗能写代码的“聪明家伙”。
  • 编译器 & 编程语言:语言是怎么翻译成机器能听懂的指令?这里就是“魔法工厂”。
  • 操作系统 & 计算机体系:研究一台机器是如何被管理、调度和优化的。
  • 数据库 & 存储系统:信息的仓库,如何高效存取?
  • 图形学 / 游戏开发:光影、建模、动画背后的秘密。
  • 分布式系统 & 机器学习系统:如何让上千台机器协同完成一件“大工程”?

每一个领域都是一片全新的大陆,你完全可以挑一个方向去“深潜”。

我们也准备了一些资源:计算机世界漫游 :world_map:
它未必能让你一夜之间写出黑科技代码,但一定能帮你打开眼界,了解一个更广阔的计算机世界。


热身任务 :joystick:

  1. 获得一台属于自己的电脑。
  2. 学会科学上网(F**k the GFW)(计算机人不能不会科学上网啊喂)。
  3. 闷声发大财,本题无需提交。
  4. 如果你觉得有趣,就去漫游一下计算机导论。

Tips for 萌新

  • 没电脑?去网吧!(但你最好真的是去写代码…)
  • 想玩点硬核?买个树莓派+屏幕练练 Linux。
  • 手机/平板能不能替代电脑?能,但体验嘛……你懂的。
  • 最佳方案:早日拥有一台属于自己的笔记本,省心又省力。
  • 科学上网 对于咱们计算机科学家来说十分重要捏,请将这件事情放在首位。

:point_right: 第一关考察的,不是你会多少,而是你敢不敢迈出第一步。


#1 啥是 Git

01 背景

有些同学刚入学,写代码的方式还停留在:

  • QQ 群里丢一份 .zip 压缩包
  • 改文件名用 final.c → final_final.c → final_final真的最后版.c
  • 一边 debug 一边疯狂复制粘贴

:eyes: 当学姐第无数次收到某位同学的 debug 求助和神秘压缩包时,心中只有一个疑问:
“同学,你真的不想试试 Git 吗?”

一开始你可能感觉不到它的魅力:作业文件一个人改,复制粘贴照样能活。
但当项目一旦变大、多人协作,没有 Git 简直就是灾难

  • 你改代码的时候,别人不敢动,只能傻等。
  • 别人悄悄改了模块,你完全不知道对自己有什么影响。
  • 甲方说:还是第一版好看 → 你翻遍电脑找不到第一版的存档。
  • 改出 bug,想回到昨天的版本 → 抱歉,你的后悔药 CD 已过期。

这就是为什么,Git = 软件工程的救命稻草

所以希望在痛心疾首地安利 Git 之后,希望每一位同学都能够掌握 Git,并且习惯使用它来管理自己的代码。


关于 GitHub

GitHub 是全球最大的 开源协作社区 + Git 托管平台
2018 年被微软收购后,私人仓库也免费了(这波直接赢麻了)。

它能让你:

不仅能用,还能学。看到感兴趣的项目,点个 :star: star 收藏就是最简单的参与。


准备工作

  1. 安装 Git 环境

  2. 本地尝试 Git 操作
    Linux 环境体验最佳,建议 WSL/虚拟机/双系统 等Linux环境配置一波

  3. 学习 GitHub 基础操作

  4. 进阶资料

温馨提示:在合作项目中,commit 信息的书写也是很重要的哦~

任务

  • 注册一个 GitHub 账号,建一个名为JoTang2025的仓库并设为 public 用于管理你在本次“招新马拉松”中的答题文件 :open_file_folder: 随邮件提交网址或账号,我们就可以看到啦。

    • 如果你可以写一写遇到的问题或者学习的过程就更好了~
    • commit message 写清楚一点,能帮你加分哦~
  • 如果有余力:

    1. 尝试 GitHub 学生认证(免费用 Copilot!白嫖不香吗)
      GitHub Student Pack
    2. 用 GitHub Pages 搭建一个属于自己的博客 :writing_hand:
      • 搭建教程,或者自行搜索哦
      • 成功后,你将拥有一个属于自己的博客

提示

  • 访问慢? → 科学上网 or 搜索“GitHub 加速镜像”。

  • 真的打不开? → 备选方案:Gitee (国内替代品,但生态差一截)或者也可以试试前面提到的GitHub Desktop。但还是还是墙裂建议uu萌学会科学上网。

  • 小技巧:如果你已经会用 WSL,可以试试给终端配置代理 →


题外话

  • GitHub 的私有仓库已经对个人免费,请不用害羞。
  • 没事多逛逛 Trending,看看全球开发者最近在玩什么,探索一下 Github 这个世界上最大的开发者社区~
  • star 你喜欢的项目,说不定未来就能参与贡献哟。

:pushpin: 提交要求:随邮件附上你的 GitHub 主页链接,如果搭了博客也可以一并交上来!


#2 Markdown

背景

若干年前,某学姐兴冲冲地点开邮箱,满心期待能看到新鲜有趣的招新题答案,结果迎接她的却是满屏的 .docx 作业。她愣住了:
“这到底是编程社团的招新,还是 Word 格式排版锦标赛?”

与此同时,另一个角落的宿舍里,学妹正和 Word 展开世纪大战:

  • 标题怎么调都对不齐
  • 图片总是神秘地“乱跑”
  • 回车一次,整个版式土崩瓦解

:exploding_head: 你是否也曾经被 Word 折磨到想直接 Ctrl+Alt+Del 自己?

好消息! 世界上有一种优雅的解决方案,它的名字叫——Markdown。当年小小的我学会Markdown后,就再也不想碰word了(哭


Markdown 是啥?

Markdown 是一种 轻量级标记语言,简单来说就是:

  • 写起来像 txt 一样清爽
  • 渲染出来却能像 Word 一样整齐美观
  • 常见于 GitHub 的 README、博客、技术文档,甚至知乎和简书都支持

:point_right: 换句话说:
用 Markdown,你就能用极少的格式代码,写出好看的文档。

而且它不是软件,几乎任何文本编辑器都能写。


学习资源


任务

  • 坏消息:你所有的招新题答案都要用 Markdown 写。
  • 好消息:这题本身不用交。

Tips:

  • 源代码请放 GitHub 仓库里,并在 Markdown 里附上仓库链接。
  • 插图不要用本地路径!学姐没法访问你电脑的 C:\Users\xxx\Pictures\1.png
    • 建议用相对路径(把图片和 Markdown 放一起打包)。
    • 或者自己查查“图床”是什么神器。
  • 所有提交文件的命名请一定要清晰,最好是以题号命名,分级标题也是哦~

备注

尤记得往年收到过这样的提交:

![图片](C:\Users\桌面\可爱猫猫.png)

结果打开一看,啥也没有。
所以,记住:图片要么打包使用相对路径,要么上图床!

:point_right: 从这一题开始,你就已经和“Word 格式崩溃地狱”说再见了,欢迎进入 Markdown 的清爽世界。


#3 Linux & WSL & Docker

背景

新学期刚开始,小文同学为了完成 Jotang 的招新题,热情满满地搭建环境:

  • 装了 Python 环境,结果马上又要配 JDK
  • 配完 Go,又跑去折腾 Node 包管理器
  • 环境变量越来越花,版本号乱成拼图

更糟糕的是:
一不小心点开了“某软件园”的下载链接,桌面瞬间布满奇怪的快捷方式,小文的眼泪在眼眶打转。:sob:

Windows 是生活环境,重装太伤筋动骨,那咋办?

这时候,WSL2 像救星一样出现了:
在 Windows 下直接运行一个完整的 Linux 内核,让你体验开发环境切换的丝滑。

不过新的问题来了:

  • 有人嫌弃命令行太“硬核”,想要 GUI。命令行虽好,但是同时拥有 GUI 确实很香
  • 有人想要彻底隔离环境,避免把宿舍 WiFi 搞崩

于是虚拟机和双系统闪亮登场!

  • 虚拟机:想怎么配就怎么配,炸了直接删,一键新建
  • 双系统:显卡支持更好,机器学习党狂喜嘿嘿
  • Docker:环境打包神器,谁用谁说好~

到这一步,小文终于不用再担心把 Windows 玩坏了!


题目内容

任务(三选一,勇敢者可全都要 :eyes:):

  1. 安装 WSL2:在 Windows 下配置 Ubuntu(或其他主流 Linux 发行版,但别用 CentOS)。
  2. 安装虚拟机:用 VMware/VirtualBox/UTM 装一个 Linux 发行版(GUI 党必选)。
  3. 装双系统:在电脑里直接和 Windows 并肩作战,适合深度折腾和训练 AI 的同学。咳咳,稍微有点硬核咱就是说,下次自己装电脑可以试试

:point_right: 建议萌新优先选择 Ubuntu LTS 版本(long-term support,稳定第一),中文资料多到飞起。

想扩展知识?推荐看看 计算机世界漫游 的 Linux 章节。

选择哪条分支根据个人兴趣以及需求来即可。


加分项

  • VS Code Remote 插件连上 WSL2 / 虚拟机

  • 配置 SSH 免密登录,摆脱输入密码的痛苦

  • 把后续的题目项目都打包成 Docker 镜像,推到 Docker Hub

    • 写好 README.md
    • 提供一键运行脚本
    • 让学姐一行命令就能跑起你的代码,你在本地的效果 → 爽!

划重点

  • 除非你专门写 Windows 应用(或 Java 这种跑在 JVM 上的),否则我们 强烈建议你用 Linux 作为主力开发环境
  • Docker 是个神器,但日常课程不一定常用,选择性了解即可,不用死磕。

提交内容

  • 安装过程的截图
  • 每一步的文字说明以及实际遇到的问题
  • 最后的个人感想

:point_right: 请全部用 Markdown 整理提交。


参考资料


#4 Makefile & CMakeLists

单文件编译的起点

萌新小卷写下了人生第一行 C 语言代码:

#include <stdio.h>
int main() {
    printf("Hello, World!\n");
    return 0;
}

保存为 hello.c 后,在终端敲下:

gcc hello.c
./a.out

屏幕上出现了那句熟悉的 Hello, World! :tada:

小卷兴奋之余,发现背后其实暗藏玄机:编译器不是直接“吃掉源码吐出可执行文件”,而是经过了一整个流水线。


从源码到可执行文件

  1. 预处理(Preprocessing)

    • 展开 #include
    • 替换宏定义
    • 处理条件编译
    gcc -E hello.c > hello.i
    
  2. 编译(Compilation)

    • 把 C 代码翻译成汇编(针对不同架构:x86、ARM、RISC-V…)
    • 检查语法,但逻辑 bug 不会报错
    gcc -S hello.i
    

    编译是检查词法和语法规则,所以,如果程序没有词法或语法错误,那么不管逻辑是怎样错误的,都不会报错,这可能会解释一些小卷写的程序在编译后没有问题,但是实际运行会报段错误这类的错

  3. 汇编(Assembling)

    • 汇编代码 → 机器码 → 目标文件 .o
    gcc -c hello.s
    objdump -d hello.o
    
  4. 链接(Linking)

    • 把目标文件 + 库函数拼在一起
    • 静态链接:直接编进程序里(大但独立)
    • 动态链接:运行时再找库(小但依赖外部环境)
    gcc hello.o -o hello   # 默认动态链接 libc
    gcc -static hello.o    # 强制静态链接
    

多文件编译

有一天,小卷写了 add.c, mul.c, hello.c
于是出现了经典问题:“我是不是得每次都手动 gcc 一遍?”

gcc -c add.c -I./include
gcc -c mul.c -I./include
gcc -c hello.c -I./include
gcc add.o mul.o hello.o -o hello

如果只改了 mul.c,理论上只需要重新编译它再链接即可。但手动操作一堆命令行,真的太“社畜”了。


Makefile 登场

于是前辈们发明了 Makefile

  • 只写一次规则,执行 make,自动找出要编译的文件
  • 修改了哪个源文件,就只编译那一个
  • 再也不用疯狂复制 gcc 命令

:point_right: 学习资料:

当然,Makefile 也有槽点:

  • 语法魔法风,难读难写
  • 不同平台规则不同,不够跨平台
  • 项目一大,维护难度翻倍

CMake:进化版工具

为了简化维护,CMake 出现了。

它的核心思想:让你写配置,不必写复杂规则

示例片段:

# 指定头文件搜索路径,比如放置公共头文件的 include 目录
include_directories(${CMAKE_SOURCE_DIR}/include)

# 把子目录 src 添加到构建系统里(src 目录里需要有自己的 CMakeLists.txt)
add_subdirectory(src)

# 生成一个可执行文件 myapp,由 main.c 构成
add_executable(myapp main.c)

# 将 myapp 与 src 子目录中编译出来的 mylib 库进行链接
target_link_libraries(myapp PRIVATE mylib)

一般流程:

mkdir build && cd build
cmake ..
make        # 或者 cmake .. -GNinja && ninja

CMake 本质上依然会生成 Makefile 或 Ninja 配置,但它跨平台、可读性更强,是现代 C/C++ 项目几乎默认的构建工具。


任务

  1. 写一份笔记,描述 从 C 源码到可执行文件的完整流程
  2. 在我们提供的 GitHub 仓库中完成指定的 Task
  3. 这一步是你理解 C/C++ 这类编译型语言 的基础哦~顺便也可以拿来和 Python 这类解释型语言 做个对比:
  • 编译型语言:需要先经过“编译 → 汇编 → 链接”等步骤,把源代码翻译成机器能直接运行的二进制程序,执行速度快,但调试起来可能稍麻烦。
  • 解释型语言:代码通常不需要提前编译,由解释器一行行读取、执行,开发效率高、调试灵活,但运行速度可能会慢一些。

:bulb: 思考一下:

  • 为什么 C 程序通常跑得比 Python 快?
  • 为什么很多团队会选择 “C++ 写核心逻辑,Python 负责调度” 的混合模式?
  • 解释型语言真的就不用编译吗?(提示:其实 Python 也会先转成字节码 .pyc 再执行哟~)

将你的回答写进笔记里哦~

注:所有的文字提交时用 Markdown 文档,并取为清晰的命名,附带截图 + 说明。

#5 机器学习

前言:这部分题目针对大一新同学,难度较适合新手入门,但仍需要你投入不少的时间理解和实操。如果你对自己的理解和代码能力足够自信,可以前往完成难度更大的焦点计划题目

人工智能(AI)是一门高度交叉且通用性极强的学科,已深度融入我们日常生活的方方面面。可以说,有摄像头的地方就有计算机视觉(CV)——从手机人脸解锁、智能安防监控,到自动驾驶的环境感知;有文字交互的地方就有自然语言处理(NLP)——比如智能客服、实时翻译,以及搜索引擎的智能推荐;而有机械装置的地方,往往也离不开智能决策与控制技术——例如工业机器人、智能家电和无人机系统。

特别值得一提的是,近年来迅速发展的生成式模型(Generative Models),进一步拓展了AI的创造与交互边界。它不仅能生成高度拟人的文本、代码和对话(如ChatGPT),还可创作图像、视频和音乐(如MidJourney、Stable Diffusion),甚至辅助设计、广告、教育等多个领域的内容生产。从感知到理解,从决策到生成,AI正以系统化、泛在化的方式,持续推动着技术与生活的融合创新。

从高中步入大学校园,如果你对人工智能(AI)充满兴趣,却不知该从何开始——别担心,接下来我们将为你指引方向,帮助你逐步建立AI领域的知识基础、掌握核心技能。你需要了解的内容大体包括:

数学基础:微积分、线性代数、概率论(不要紧张!!这只需要你对以上内容的概念、在机器学习里起到的作用大致了解即可,不用预习整门课学习计算)。重点去了解偏导数、链式求导、梯度计算、矩阵运算和线性变换。推荐书目《深度学习的数学》第二章,视频可参考深度学习的数学这个合集视频的前两章。

编程语言基础:Python。你可以通过文档、网课来学习。文档可参考Python教程 - 廖雪峰的官方网站;网课在B站找播放量较高、时长相对短的即可。这一部分不要花太多时间,浏览一遍,两天左右即可,没有编程基础的同学不要担心,以后在具体的项目代码中你会发现前面看的教程一点用都没有可以一边查阅资料一边学习。

机器学习 基础:机器学习基本概念、Pytorch框架。推荐视频吴恩达机器学习,看前几节了解基本概念即可;Pytorch入门教程,可以快速了解并上手Pytorch代码框架。

Tips:理论知识学习过程中如果遇到不明白的部分,记得善用GPT以及Google搜索等工具~你的问题基本都能在博客、论坛或GPT回答中找到解决方案。如有需要,你可以从这些地方获取算力:kagglecolabmodelscope魔搭社区AutoDL阿里云百度飞桨……

Task 0: The Very Basics

基本概念理解

请简要回答以下问题:

  • 偏导数、链式法则、梯度、矩阵等数学概念在机器学习中的作用?

  • 什么是“模型”?机器学习中的模型是如何工作的?

  • 模型没有生物的意识和记忆,它们是如何“学习”的?

  • 什么是监督学习?什么是无监督学习?请分别举一个例子。

  • AI 是什么?深度学习和传统机器学习的区别?

  • 怎么用矩阵乘法表示神经网络的全连接层前向传播过程?

编程与开发环境

  • 安装 IDE,推荐 VSCode、PyCharm

  • 安装 Anaconda 或 Miniconda

  • 创建一个新的 Python 虚拟环境(版本建议为 3.8 或 3.9)

  • 如果 PC 有 Nvidia GPU,则安装 CUDA

  • 根据自己的软硬件情况,查阅 官方网站,安装 PyTorch

  • 安装常用工具包:numpy, matplotlib, scikit-learn

  • 请简要回答以下问题:

    • Python 与 C 语言的区别?

    • 如何用命令行运行 python 程序?

    • 为什么需要 python 虚拟环境?在命令行中如何在不使用 conda 指令的情况下使用指定虚拟环境?

提交要求

  • 文件夹命名为“task0”,放在 GitHub

  • 记录你的学习过程和理解,具体内容包括但不限于上面有提及的内容。

Task 1: Neural Networks

神经网络是深度学习的基础,可以说我们现在熟知的先进深度学习模型都是普通 MLP 的升级。

概念理解

体验网站:Neural Network Playground,回答问题:

  • 什么是多层感知机(MLP)?其结构是怎样的?

  • 数据在神经网络中扮演哪些角色?(数据集的 split 和处理)

    • 噪声是什么?特征是什么?标签是什么?

    • Batch size 是什么?为什么堆叠成 Batch 可以提高运算速度?

  • 神经元是什么?

  • 什么是激活函数?常见的激活函数有哪些?什么叫“非线性表达能力”?

  • 什么是计算图?它和数据结构/离散数学中学的图有什么区别?怎么构建计算图?

  • 怎么计算MLP的参数量?什么是超参数?MLP有哪些超参数?

  • 什么是隐藏层(hidden layers)?它为什么叫这个名字?

  • 什么是损失函数?什么任务用什么损失函数?

  • 前向传播是什么?梯度是什么?学习率是什么?反向传播是什么?有哪些常见的优化器?

  • 归一化是什么?正则化是什么?

  • 什么是欠拟合?什么是过拟合?

代码实践

请实现以下功能:

  • 借助框架(PyTorch)实现一个简单的神经网络(输入层-数层隐藏层-输出层)(学会查阅文档,而不是只依靠 AI)Learn the Basics — PyTorch Tutorials 2.7.0+cu126 documentation

  • 要求:

    • 画出你神经网络的架构

    • 使用简单的数据集 dataset(如 scikit-learnmake_moonsmake_circles)进行训练(二分类问题)

      • 尝试调整 noise 的大小,对比模型的效果。

      • matplotlib 将数据集可视化,想想怎么从数学层面表达你选用的数据集?

    • 实现参数初始化、前向传播、损失计算、反向传播和参数更新

    • 可视化输出训练损失下降曲线与分类准确率

    • 模型的输出表示的应该是这个样本属于每个类别的概率值,所有类别(这里是 2 个)的概率值加起来为 1(你是通过什么手段保证这一点的?如果有更多类呢)。训练好模型后,用 matplotlib 把空间中的每个点推理结果可视化(热力图)。

    • 对比三者训练/推理速度,分析原因(为什么更快/慢,他们大致的底层原理分别是?对硬件的利用情况如何?)

加分项(选做):焦点计划 Task 1

提交要求

  • 文件夹命名为“task1”,文档和代码都放在 GitHub 上。

  • 将学习基础概念的笔记写入提交的文档,包括但不限于理论理解中的内容。

  • 代码、结果写入提交的文档,包括但不限于代码实践中的内容,体现你的学习和思考过程。

Task 2: Regression & Classification

回归和分类是机器学习中最常见和基础的两种任务,它们的根本区别在于预测的结果是什么:

  • 回归:预测的是一个具体的数值。比如预测明天的气温、估算房屋的价格,或者推断一个人的收入。它的结果是连续的数字。

  • 分类:预测的是一个类别。比如判断一张图片是猫还是狗、识别一封邮件是不是垃圾邮件,或者判断用户喜欢还是不喜欢某个产品。它的结果是有限的几个选项。

很多算法既可以做回归,也可以做分类,只是稍微调整一下就可以了。比如决策树、神经网络这些方法,都有分别处理这两种任务的版本。

有趣的是,回归和分类之间常常可以互相转换:

  • 回归的结果可以通过设定“阈值”变成分类。比如血糖值高于某个数就是“高血糖”,低于就是“正常”。

  • 分类模型(比如逻辑回归)常常先输出一个概率(属于0到1之间的数值),再根据概率大小决定最终类别——所以其实它内部也用了回归的思想。

回归

概念理解

  • 在预测房价的模型中,模型的输出是什么?它是连续的还是离散的?

  • 什么是“线性回归”?试着用一句话描述它是如何工作的。解释你在高中学习的“最小二乘法”的原理。

  • 评价一个回归模型的好坏,常用的一个指标有什么?

代码实操

本题使用 Python 和 scikit-learn 库。

  • 加载 scikit-learn 自带的加州房价数据集。查看数据的特征形状和目标值形状。

  • 使用线性回归模型训练数据,并将数据集拆分为训练集和测试集。

  • 在测试集上进行预测,并计算模型的均方误差(MSE)和决定系数(R²)。

  • 尝试绘制一个散点图,x轴是真实房价,y轴是模型预测的房价。如果预测完美,所有点会形成一条什么样的线?

分类

概念理解

  • 分类任务的输出是什么?它和回归任务的输出有什么本质不同?

  • 什么是“二分类”问题?什么是“多分类”问题?请分别举一个例子。怎么实现二分类和多分类?

  • 评价分类模型指标有哪些?

代码实操

Iris

同样使用 Python 和 scikit-learn

  • 加载 scikit-learn 自带的鸢尾花(Iris)数据集。这是一个什么类型的分类问题(二分类/多分类)?数据集里有多少个类别?

  • 使用逻辑回归(Logistic Regression)模型训练数据,并划分训练集和测试集。

  • 在测试集上进行预测,并计算模型的准确率(Accuracy)。

  • 打印模型的混淆矩阵(Confusion Matrix),并尝试说明矩阵中数字的含义。

Titanic

背景介绍

泰坦尼克号生存预测数据集是一个经典的二分类问题数据集,它包含了泰坦尼克号乘客的各种属性,如舱位等级、年龄、性别、船票价格、登船港口、是否携带亲属等,以及乘客是否在灾难中幸存。本题要求使用PyTorch框架来构建和训练一个神经网络模型,以预测乘客是否生还。

数据集:https://www.kaggle.com/c/titanic。

题目要求
  • 使用PyTorch框架构建一个神经网络模型

  • 对数据进行预处理,包括归一化、处理缺失值等。

  • 训练模型与并且进行分类预测

  • 评估模型性能

作答提示
  1. 数据预处理(推荐使用 pandas ):
  • 加载数据集。

  • 探索数据,了解各个特征的含义。

  • 对数据进行清洗,处理缺失值和异常值。

  • 对特征进行归一化处理。

  • 将部分特征值转换为模型可处理的形式,如独热编码

  1. 模型构建:
  • 设计一个适合分类问题的神经网络结构。

  • 选择合适的损失函数。

  • 选择合适的优化器,如Adam或SGD。

  1. 模型训练:
  • 转换数据集文件格式并且选择合适的训练特征

  • 从数据集中分出部分数据作为验证集。

  • 训练模型,并使用验证集进行模型调整,如:模型框架优化,超参数调优,特征选择。

  • 有满意的结果后,将验证集和训练集合并,重新训练模型。

  • 保存模型

  1. 模型评估:
  • 加载模型

  • 使用测试集评估模型的性能,如模型处理时间等。

  • 分析模型的预测结果,包括准确率,F1-Score等。

  1. 额外思考(可选):
  • 若数据集标签不平衡,会对模型产生什么影响,可采用什么方法

  • 对上述问题进行实践验证

  1. 结果分析与报告:
  • 记录模型训练过程中的关键指标,如准确率的变化。

  • 记录根据验证集评估结果对模型进行调整的过程

  • 撰写实验报告,总结模型的性能和可能的改进方向。

提交要求

  1. 代码:*.py 文件,内容为实现的上述实验模型代码,包括数据预处理、模型定义、训练和测试。

  2. 实验报告:使用 Markdown 文件记录你的实验过程和结果分析,包括模型结构、训练过程、结果评估等。

  3. GitHub 链接:将上述内容整理到一个名为 “task2” 的文件夹中,并上传至GitHub。

Task 3 CV

背景介绍

嗨嗨是一个喜欢用老人机拍照的小朋友,不过他只拍十类景物:飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车。嗨嗨有个奇怪的习惯:每次拍完照,他一定要在右下角贴个数字,像是给照片打分——“这张糊成这样,先给自己来个 3 分。”下面展示的是嗨嗨的 10 张作品:

嗨嗨拍出来的照片大部分都特别模糊,他希望你能帮忙设计一个 convolutional neural network (CNN),让模型能够识别出左上角的景物。训练集中,左上角的景物的 label 和右下角的小图数字有时会碰巧相同,这可能让模型“偷懒”去依赖右下角的数字。但在验证和测试阶段,这种巧合几乎不存在,如果模型偷懒,它的准确率会明显下降。

题目要求

根据给定的代码框架,完成以下任务:

  1. 加载数据集并进行预处理
  • 下载数据集的压缩包解压后,会得到一个包含三个子文件夹的主文件夹:trainvaltesttrainval 文件夹下各包含 10 个子文件夹,每个子文件夹存放属于同一类别的图像(例如名称为“0”的文件夹下存放的都是包含飞机的拼图),子文件夹的名称就是对应类图像的 labeltest_unlabeled 文件夹包含 10,000 张图像,用于测试你训练好的模型。

  • 请在 data.py 中完成数据加载与预处理。

  1. CNN 模型实现
  • 请在 model.py 中完成一个 5 层 CNN,使其能够处理 3 通道 RGB 图像并输出 10 类 logits。模型结构如下图所示:

  • 各卷积层参数参考下表:
Layer Kernel Size Padding In Channels Out Channels
Conv1 7 3 3 16
Conv2 3 1 16 32
Conv3 3 1 32 48
Conv4 3 1 48 64
Conv5 3 1 64 80
  1. 训练模型
  • 请在 q1_train.py 使用训练集训练 CNN,并在验证集上评估模型性能。

  • 在提交的文档中说明你的训练过程和结果分析。

  1. 测试集预测
  • 请在 q1_test.py 中使用训练好的模型对 test 文件夹下的 10,000 张图片进行预测,将预测结果写入 q1_result.txt 文件中,格式如下:
image_0001.png,3
image_0002.png,7
...
  • 其中每一行包含 文件名,预测类别编号,类别编号范围为 0–9。

进阶要求

进阶要求 1: 可视化第一层卷积核

请在 q2.py 可视化你训练好的 CNN 第一层的卷积核(滤波器)。第一层有 16 个输出通道,因此共有 16 个卷积核。请读取第一层卷积层的 weight 属性,然后使用 Matplotlib 的 imshow 函数将第一层所有卷积核可视化。在提交的 markdown 文件中,描述你的观察结果。

进阶要求 2: 分析第一层和第五层的特征图

由于卷积核输入空间可能是高维(如第四卷积层输入为 48 维),直接可视化权重不再适用。因此,我们可以利用激活强度来进行分析。请参照以下步骤完成 q3.py

  1. 特征提取
  • 遍历验证集中的每张图片及其标签。

  • 通过 CNN 前向传播获取中间特征,设置 intermediate_outputs = True 来得到各层输出。

  1. L2 范数 计算
  • 第一层最后一层卷积层输出的特征图,在通道维度上计算 L2 范数。

  • 如果特征图形状为 b × c × h × w,计算后的范数形状为 b × c

  • 通过计算每个卷积核输出特征图的 L2 范数,可以量化卷积核对输入图片的响应大小,也就是卷积核看到某类特征的强弱,后文将“每个卷积核输出特征图的 L2 范数”称为激活强度。

  1. 类别平均激活强度计算
  • 对每个卷积核,在每个类别上的输出取平均,得到 10 × c 的数据(10 个类别,c 为卷积核数量)
  1. 可视化
  • 使用 Matplotlib 的柱状图绘制每个卷积核的类别平均激活强度。

  • 第一层卷积核共 16 个,最后一层卷积核共 80 个,总共 96 张柱状图。

  • X 轴为类别名称,Y 轴为归一化后的 L2 范数。

  1. 分析与报告
  • 在报告中包含第一层和最后一层卷积核对应的一些柱状图(部分即可,不用上传96张),对第一层和最后一层的柱状图进行描述性分析,说说你观察到的这两层柱状图之间的差异。你可以用这些差异来解释你的模型学到了哪些特征。

注意:绘图代码已在代码框架中提供,进阶要求重点在于分析卷积核特征及其对不同类别的响应模式,而非学习绘图技巧。

提交要求

格式

机器学习task3/
├── code/
│   ├── data.py
│   ├── model.py
│   ├── q1.py
│   ├── q2.py
│   └── q3.py
└── results/
    ├── q1_model.pt
    ├── q1_plots.png
    ├── q1_test.txt
    └── markdown文件

说明

code 文件夹:

  • data.py

  • model.py

  • q1.py

  • (进阶)q2.py :如果你完成了进阶要求 1,请提交这个文件。

  • (进阶)q3.py :如果你完成了进阶要求 2,请提交这个文件。

results 文件夹:

  • q1_model.pt :训练好的 CNN 模型权重。

  • q1_plots.png :训练和验证的 loss 与 accuracy 曲线。

  • q1_test.txt :记录测试集每张图片的预测标签。

  • markdown文件 :记录你的代码实现思路,结果分析,遇到的困难以及你的解决方案,以 markdown 形式提交。如果文档中含有图片请写相对路径并将图片一并提交。

Task 4 NLP

背景介绍

自然语言处理(NLP)最初依赖人工编写规则(1950s–1980s),随后进入统计学习时代(1990s–2010s),通过概率模型和特征工程推动分词、翻译等任务的发展;2010年代,神经网络逐渐取代传统方法,Word2Vec、RNN、Seq2Seq 等方法兴起;2017 年 Transformer 的提出和 BERT、GPT 等预训练模型的出现,使 NLP 进入大规模深度学习时代,在机器翻译、问答、对话与文本生成等领域取得突破性进展。

概念理解

  • 从 RNN、LSTM、GRU 中选择两个,介绍其基本原理和优缺点。

  • Transformer (推荐阅读 论文论文讲解,推荐观看 3Blue1Brown李沐老师

    • 注意力机制的分类?现在有哪些最常用?

    • 什么是词向量?为什么我们需要用向量来表示词?

    • one-hot 编码是什么?为什么使用 one-hot 编码来表示词语会导致维度灾难?

    • Word2Vec 提供了哪两种训练架构?分别是如何工作的?

    • 位置编码

      • 为什么Transformer 本身没有任何位置意识?

      • 位置编码可以是 绝对的(Absolute)或 相对的(Relative),还可以是可学习的(Learnable),他们分别是什么、有什么优劣?

      • 大语言模型(LLM)中常用的位置编码有哪些?

    • 层归一化 LayerNorm

      • 什么是 Layer Normalization?为什么需要它?

      • LayerNorm 和 BatchNorm 的区别?

    • mask

      • 什么是 Causal Mask / Look-ahead Mask?作用是什么?
    • 束搜索

      • 为什么 LLM 输出序列是一个搜索问题(每次输出一个概率分布列)?
  • BERT

    • 解释 BERT 的架构和原理?

    • 为什么说 BERT 是“双向的”?

    • BERT 的预训练任务是什么?

    • BERT 的输入嵌入(Input Embedding)是由哪三部分相加而成的?为什么需要这三部分?

    • BERT 和 Transformer 有何区别?

加分项(选做):2025焦点计划

代码实操

在公开数据集上微调 BERT,完成二分类情感判别(正/负),并达到给定的验证集/测试集指标。

可选数据集(任选其一)

  • 英文:GLUE/SST-2(句子级情感,二分类)

    • 在 Hugging Face Datasets 中加载:datasets.load_dataset("glue", "sst2")

    • 预训练模型:bert-base-uncased

  • 中文:ChnSentiCorp(中文酒店评论,二分类)

    • 加载:datasets.load_dataset("chnsenticorp")

    • 预训练模型:bert-base-chinese

要求

数据处理

  • 使用 transformers 的对应 BERT tokenizer 分词与截断(如 max_length=128)。

  • 统一大小写(英文)或保持原样(中文),并处理/丢弃空样本。

模型与训练

  • 基座:BertForSequenceClassification(num_labels=2)。

  • 优化器:AdamW(学习率建议 2e-5 ~ 5e-5),训练轮数 3~5

  • 批大小:依据显存(常见 16/32)。

  • 使用 Trainer 或自写训练循环皆可;需设置随机种子保证可复现。

评估与指标

  • 指标:Accuracy 必选,F1( macro 或 binary) 至少其一。

  • 在验证集上汇报最终指标,并保存最优权重(基于验证指标早停或最佳 checkpoint)。

可复现性

  • 固定随机种子;记录关键超参(学习率、epoch、batch size、max_length)。

加分项(选做):焦点计划 Task 4

#6 后端

背景

阿卷是一名刚入学的软件工程新生。在订购教材时,他发现正版教材价格不菲,于是萌生了收购学长学姐二手教材的想法,这样省下来的钱还能多买几杯蜜雪。
然而,想要买到合适的教材却并不容易——一方面人生地不熟,另一方面相关信息分散在各个角落,难以获取。
阿卷不禁设想:如果学校能有一个专属的二手交易平台,学长学姐可以轻松处理闲置物品,新生也能便捷地购买所需教材,这将极大地方便大家的校园生活。

!!注意:萌新可跟随任务步骤逐步学习,基础薄弱者请重点记录学习过程。

总体要求

以下题目意在帮助大家入门并将Java后端知识运用到实践中,故并非所有要求都必须达到,根据自己所学的程度尽力即可

鼓励用Markdown文档详细记录你的学习、思考、踩坑和解决问题的过程。这份文档是帮助我们了解你思考轨迹和学习能力的重要依据。

不论项目完成到什么程度,请务必将最终服务部署到公网服务器上(可使用阿里云、腾讯云等云平台),并提供可访问的项目API链接。
:point_right: 详细部署流程请参考 #taskx拥有你的服务器并将项目部署上线

请将你的项目代码及相关 Markdown 学习文档上传至 GitHub 仓库。建议将 Task1 至 Task3 的内容合并为一个完整的后端项目进行开发与管理,这样有助于代码结构清晰、便于后续维护和展示。每个阶段的实现过程、遇到的问题及解决方案,都可以通过 Markdown 文档详细记录在仓库中。最终请在仓库的 README 文件中附上项目部署说明、接口文档及访问方式,方便评审和他人查阅。

大一同学:优先完成Task0至Task2的要求,加分项有余力可做,Task3可作为附加题。大二同学:请尽全力完成所有Task,并挑战各项加分项。

Task0:搭建你的Java本地开发环境,迈出Java开发的第一步

阿卷在查阅了大量学习资料后,最终选择以Java作为开发平台的核心语言。面对全新的技术领域,他充满了好奇与期待,积极投入到Java的学习之旅中。
从环境搭建到语法入门,再到后端框架的探索,阿卷一步步积累知识,不断记录自己的思考与成长。
他相信,扎实的基础和持续的学习将为后续开发打下坚实的根基,也希望通过这个过程,真正掌握Java后端开发的核心能力。

要求

  1. 编写Java程序,打印”hello world“ 到控制台,要求保存代码和运行结果截图并上传至github
  2. 用IDEA创建一个Spring Boot项目,实现一个接口,通过浏览器访问http://localhost:8080/hello,给浏览器返回一个字符串“hello world”,要求保存代码和运行结果截图并上传至github
  3. 谈谈你对Java和JavaWeb的理解,它们之间有什么联系

参考资料

Task1:实现本地商品CRUD管理系统

阿卷决定亲自为校园二手平台搭建“信息管理”系统。他选择用 Spring Boot 作为后端框架,并结合 MySQL 数据库,来实现商品信息的高效存储与管理。
阿卷将一步步开发商品的新增、删除、修改、查询等接口,让每一条数据都能被安全、便捷地操作。通过这个过程,阿卷不仅深入体验了后端开发的实际应用,还为平台后续功能扩展打下了坚实基础。
现在,就跟着阿卷一起动手实践,完善属于自己的二手交易平台吧!

要求

  1. 设计数据库表
    优先实现核心库表(user、product、product_order),可参考以下表结构或自行设计扩展。

    点击展开示例 SQL 表
    -- 用户表:存储用户信息及权限角色
    CREATE TABLE `user` (
    `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
    `username` varchar(50) NOT NULL COMMENT '用户名',
    `password` varchar(100) NOT NULL COMMENT '密码(BCrypt加密)',
    `role` varchar(20) NOT NULL COMMENT '角色:ADMIN/USER',
    `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_username` (`username`) COMMENT '用户名唯一索引'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户信息表';
    
    -- 商品表:存储二手商品/需求信息
    CREATE TABLE `product` (
    `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品ID',
    `title` varchar(100) NOT NULL COMMENT '商品标题',
    `description` text COMMENT '商品描述',
    `type` varchar(20) NOT NULL COMMENT '类型:二手物品/代取需求',
    `price` decimal(10,2) NOT NULL COMMENT '价格',
    `status` varchar(20) NOT NULL COMMENT '状态:未售出/已售出',
    `publisher_id` bigint NOT NULL COMMENT '发布者ID',
    `publish_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    KEY `idx_publisher` (`publisher_id`) COMMENT '发布者索引',
    KEY `idx_status_type` (`status`,`type`) COMMENT '状态类型联合索引',
    CONSTRAINT `fk_product_user` FOREIGN KEY (`publisher_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品信息表';
    
    -- 订单表:记录用户下单信息
    CREATE TABLE `product_order` (
    `id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID',
    `product_id` bigint NOT NULL COMMENT '商品ID',
    `buyer_id` bigint NOT NULL COMMENT '买家ID',
    `status` varchar(20) NOT NULL COMMENT '订单状态:已下单/已取消',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`),
    KEY `idx_product` (`product_id`) COMMENT '商品索引',
    KEY `idx_buyer` (`buyer_id`) COMMENT '买家索引',
    CONSTRAINT `fk_order_product` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_order_user` FOREIGN KEY (`buyer_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单信息表';
    
  2. 核心接口开发
    实现以下基础增删改查接口:

    • 新增商品信息
    • 删除商品信息
    • 更新商品信息
    • 查询商品详情
    • 查询商品列表
  3. 测试与文档

    • 使用 Postman 测试所有接口,并保留接口文档方便测试。
    • 代码需符合规范:类/方法命名见名知意,关键逻辑(如参数校验、数据库异常处理)添加注释。

可能涉及到的知识点

  • Java 核心语法
  • Web 基础协议:HTTP/HTTPS 协议
  • Json
  • Spring Boot
  • MySQL数据库基础
  • 中间件:mybatis/mybatisplus

参考资料

  • JavaWeb(推荐直接从day4的后端内容开始看,你将逐步掌握Task1所涉及的知识点)

特殊说明

由于该部分知识繁杂,遇到不懂的地方,google和百度,甚至问ai也是不错的选择哦!也可和出题人沟通交流

加分项

  • 将商品列表信息进行缓存,降低数据库压力(Spring Cache + Redis)

Task2:为你的系统添加更多功能(下单、筛选)

阿卷看着初见雏形的平台感到十分雀跃,但他知道,仅仅只有商品信息是不够的。为了让平台真正实现交易功能,还需要开发商品的接单功能。

要求

  1. 了解主流数据库的表关联逻辑:简述"一对多""多对多"数据关系的核心思想,并说明本系统中用户商品下单/商品收藏应采用哪种关系及原因。
  2. 开发拓展功能接口:在Task1基础上,新增以下功能:
    • 用户下单/取消下单
    • 信息筛选:支持按"类型(二手物品/代取需求)、价格范围、发布时间(如"24小时内新发布")"筛选列表。

参考资料

加分项

  • 了解后端如何接入支付平台(如微信,支付宝)以实现真正的交易功能,并简要说明如何实现

Task3:实现用户权限与安全鉴权

然而阿卷很快意识到,平台的安全性和规范性至关重要。如果没有用户权限的严格控制,任何人都可以随意修改、删除他人的商品信息。

要求

  1. 设计用户角色:至少划分2种角色:
    • 平台管理员:可操作所有接口。
    • 普通用户:仅可发布、查询、接单、取消接单自己的商品信息和需求,不能随意删除或修改他人信息。
  2. 开发用户与鉴权功能
    • 登录接口:接收"用户名、密码",验证通过后返回JWT Token(包含必要用户信息)。
    • 接口鉴权:为Task1、Task2的所有接口添加鉴权逻辑——请求时需在Header中携带Token,未携带/Token无效则返回"401未授权";普通成员访问越权接口时,返回"403权限不足"。

参考资料

JavaWeb(Day12登录功能)

加分项

  • 开发注册接口:支持普通成员自主注册(注册后默认角色为"普通成员",需管理员手动升级为"管理员"),并对数据库存储的密码进行加密存储(使用BCrypt算法)

TaskX:拥有你的服务器并将项目部署上线!

在互联网的世界里,一台服务器至关重要,你可以在上面存放属于你自己的所有信息,你可以将自己的网站或者资料分享给在计算机网络世界中的所有用户,在如今的互联网世界中,每一个你所登录使用的Web/App背后都有一台强大的服务器。
现在就开始去获得属于你自己的服务器,将你本地开发的项目部署到服务器上,让全世界都能访问吧!

要求

  1. 获取你的服务器

    • 优先选择阿里云免费试用(阿里云新用户ECS试用),新用户可获得3个月试用期服务器;也可选择阿里云、腾讯云、华为云等平台的学生机。
    • 服务器安全注意:设置复杂密码(建议包含大小写字母、数字、特殊符号)。
  2. 服务器基本操作

    • 在服务器上学习并使用基础Linux命令操作(参考资料:Linux常用基础命令
    • 建议优先重点学习文件操作(如ls、cd、cp、mkdir、rm)、进程管理(如ps、top、kill)等常用命令,帮助你更高效地管理和部署项目。
  3. 项目部署

    • 将完成的项目部署到服务器上运行。
    • 确保可以通过公网访问你的接口,建议使用 Postman 或浏览器进行访问验证。

加分项

  • 配置Linux服务器的防火墙,只开放必要端口(如8080端口用于后端服务访问)
  • 给出项目可访问的公网链接(如果没有能力做简单前端页面可以只给出接口链接,前端用ai速成也没问题)

#7 前端

情景引入

刚进入大学的你,发现身边的同学们热衷于分享各种各样的信息:
有人分享学习资料,有人推荐电影和音乐,有人分享本地美食和旅游攻略,还有人发兼职信息或者竞赛通知……
但这些内容分散在微信群、QQ群、朋友圈里,想要再找到它们却很困难。

于是,你萌生了一个想法:做一个属于大家的 “焦糖口袋站” —— 一个能集中收集、展示、管理信息的小站点。
你的目标是:让它从一个简单的首页,逐步成长为一个能交互的资源分享平台,最后甚至进化为一个自带 AI 助手的智能产品。

接下来,你会经历三个开发阶段,每完成一次,你的小站就会解锁新的能力。
开发过程中,你可以随时借助 AI 来帮助你,但最终的成果应该有你的创意和理解,而不是单纯的 AI 模板。


前置技能 & 学习工具


题目一:点亮小站招牌

“焦糖口袋站”刚刚诞生,你需要给它一个体面的“门面”。用户一打开,就能知道这里是一个什么样的网站,有哪些功能。首页是整个网站的第一印象,它既要清晰简洁,又要有点小惊喜。除此之外,你还需要准备一个“概览”页面,向用户展示本站资源情况。

开发目标

  1. 基础结构
    • 制作一个首页,包含三个主要区域:
      • 顶部导航栏:至少包含“首页 / 资源 / 概览”三个入口。建议在页面下滑时保持固定。
      • 介绍区块:自由发挥,简单介绍网站的功能或目标(比如“分享学习资料”“发现有趣内容”)。
      • 资源预览区块:提前展示几条“资源卡片”(标题 + 简介 + 图片/链接等内容),吸引用户点击进入资源页查看更多。
      • 页脚(可选):写上版权、联系方式、社交链接等。
    • 制作“概览”页面(或区块),用来展示网站资源信息。
      • 点击导航栏中的“概览”,跳转到该页面(或区块)。
      • 使用 ECharts 绘制可视化图表,展示网站资源情况,如资源分布情况(比如“学习资料 40%、娱乐推荐 30%、竞赛信息 20%、其他 10%”)。
  2. 页面美化
    • 使用 CSS 布局(Flex / Grid)让页面结构更整齐。
    • 给导航栏或按钮加上悬停效果(hover 时颜色或大小变化)。
    • 给页面设计一些滚动动画(如元素渐渐出现、滑动时淡入)。
    • 简单的响应式设计:在不同屏幕(电脑 / 手机)下都有较好的显示效果。

提示

  • 在写代码之前,不妨多看看一些优秀网站的配色和排版,从中汲取灵感,慢慢积累自己的审美感觉。
  • 可以先画一张简单的“页面草图”,再动手写代码。
  • 图表数据一开始不需要动态更新,可以先用静态数据模拟。

学习关键字

  • HTML 基础结构
  • 语义化标签
  • CSS Flex/Grid 布局
  • 响应式设计
  • hover/transition 动画
  • 滚动监听
  • ECharts

题目二:让资源流动起来

首页已经有了雏形,但“口袋站”不能只放静态内容。用户需要能在网站上提交自己的资源,还能快速查找。现在,你要让网站成为一个真正能互动的“资料收集器”。

开发目标

  1. 资源页结构
    • 点击导航栏中的“资源”,跳转到新的页面。
    • 页面包含一个资源列表,每一条资源建议包含以下要素:
      • 资源标题
      • 简介或描述(简要说明资源的用途或亮点)
      • 链接(点击后可跳转到资源页面,或“假链接”占位)
      • 缩略图/图标(可选,增加视觉效果)
      • 提交者/时间(可选,模拟“谁分享的”)
    • 资源列表布局可以参考以下方式:
      1. 信息流列表(类似知乎掘金):一条资源占据一行,内容以“图标 + 标题 + 简介 + 链接”形式排版。
      2. 卡片布局(类似小红书bilibili):每条资源显示为一个卡片,卡片内有标题、图片、简介等信息;卡片可采用网格/瀑布流布局,页面更活泼。
      3. 自由发挥风格:例如极简目录风、分区展示(学习/娱乐/工具),都可以。
  2. 搜索功能:在资源列表上方加一个搜索框,用户输入关键词后,列表会只显示相关资源(如标题或简介中包含关键词)。
  3. 添加功能:提供一个“提交资源”的功能,点击提交后,新资源会被添加到页面的资源列表。
  4. 数据持久化:使用本地存储保存资源内容,保证用户刷新或关闭页面后,数据不会丢失。
  5. 美化与交互细节(以下仅作参考,可自由发挥)
    • 鼠标悬停时,卡片或列表项出现放大/阴影效果。
    • 点击资源标题可跳转到资源页面。
    • 搜索结果为空时,显示“未找到结果”。
    • 添加新资源时,可以设计一些过渡动画(比如卡片淡入出现)。
    • 在添加、展示资源等环节保持UI风格的一致性。
    • 尝试让“概览”页面的图表自动读取实际的资源数据。

提示

  • 如果你有创意(比如仿照某个网页的风格),尽管大胆尝试!

学习关键字

  • JavaScript DOM 操作
  • 事件监听(click/input/submit)
  • 表单处理
  • 数组和对象操作
  • 本地存储
  • 条件渲染
  • 数据驱动思维

题目三(进阶):邀请 AI 加入小站

“焦糖口袋站”越来越受欢迎,大家每天都在提交学习资料、竞赛通知、娱乐推荐……

但问题也随之出现:有的资源简介很长,看完两眼一黑;有的资源没标注类别,想找相关的要翻半天;有人抱怨搜索太难,“输入关键词没结果,但明明有类似的资源”;好资源和水资源混在一起,大家不知道该看哪条……

于是,你决定请来一位 AI 小助手,它就像一个聪明的图书馆管理员:能帮你总结、归类、推荐、搜索,还能给资源“打分”,让“口袋站”不仅能收集信息,还能帮大家更高效地利用信息。

开发目标

下面是可供参考的开发方向,你可以从下面几个功能中选择 若干个核心功能 实现:

  1. AI 收集资源
    • 用户点击“AI 帮我找”,输入关键词等内容(如“前端学习”/“成都旅游攻略”)。
    • AI 返回若干条信息,并自动将资源内容渲染成卡片/列表供预览。
    • 可选中相应资源卡片/列表并添加到页面的资源列表。
    • 尝试实现多轮对话,在上下文语境中实现更精准的内容收集。
  2. AI 自动总结:当用户提交或选择一条资源时,AI 自动生成一句简短的摘要,帮助用户快速了解内容。
  3. AI 标签/分类自动生成:用户提交资源时,AI 自动生成合适的标签(如“学习 / 娱乐 / 工具”等等)。在资源页侧边栏展示“标签云”,点击某个标签可以筛选资源。
  4. AI 智能搜索助手:升级搜索功能,用户可输入模糊搜索词(如“想学网页设计”),AI 理解语义并返回最相关的资源,而不是仅仅依赖关键词匹配。
  5. AI 推荐与扩展:当用户浏览一条资源时,AI 自动推荐与之相关的其他资源。比如浏览“前端学习资料”,AI 推荐“JS 练习网站”或“网页设计案例”。
  6. AI 质量评估:AI 根据简介内容或关键字,给资源一个“推荐度评分”(如 1-5 星)。用户可以优先查看高分资源,提高效率。

提示

在这一阶段,你会尝试把 AI 的能力接入到网页。实现之前,建议你先了解:

  • HTTP 请求:如何发送请求并处理返回数据;
  • API 调用:如何把用户输入封装进请求,向一个 AI 接口(或模拟数据)发送;
  • Prompt 设计:如何通过文字指令控制 AI 输出;
  • JSON 数据处理:如何把返回的数据解析并渲染到网页中;
  • 前端交互优化:加载中提示、错误处理、输出过长时的处理等。

开发过程中,你可以:

  • 先用模拟 JSON 测试页面逻辑,再逐步尝试接入真实 API。
  • 在交互设计上,尝试为 AI 功能增加一些独特的界面元素(可参照市面上 AI 产品设计),让用户直观感受到 AI 驱动的结果。
  • 以上均为参考开发方向,对于实现细节并未严格限制,若你有更多新颖的ideas也欢迎实现~

学习关键字

  • JavaScript 异步编程:fetch / axios、async/await
  • JSON 数据处理
  • DOM 动态渲染与更新
  • 条件渲染、筛选与推荐逻辑
  • API 调用与封装
  • 用户体验设计(提示加载中、处理空结果等)

扩展挑战

如果你觉得上面三题可以轻松搞定,可以尝试更高层次的挑战:

  • 框架与组件化:使用 Vue.js / React 等框架,把页面拆分成组件(如导航栏、资源卡片、表单)。
  • 组件库与 UI 优化:使用 Element PlusAnt DesignTailwind CSS 等快速搭建专业化界面。
  • 个性化体验
    • 增加夜间模式、主题切换、分页显示、数据分类过滤等功能。
    • 加入过渡动画、懒加载,提升体验。
    • 兼顾配色与布局的美观性;同时保证操作合理、逻辑清晰,全面考虑不同场景下的使用体验。
  • 规范与协作
    • 使用 ESLint / Prettier 格式化代码,建立合理的目录结构。
    • 在 GitHub 建立仓库并使用 Git 进行版本控制,体验多人协作开发流程。

提交要求

  • 完成度说明
    • 题目完成度根据自己当前的学习情况,尽力即可,不强求完全一致。
    • 大一同学至少完成前两题,第三题作为附加挑战;大二同学则请尽力挑战全部题目。
    • 完成功能是基础,创意和个性化发挥是亮点——页面风格、交互体验、问题解决思路都会被重点关注。
  • 提交内容:最终需提交一份学习文档(Markdown 格式),文档中需包含:
    • 你的 GitHub 仓库链接(代码按照题号 task1task2task3 划分文件夹上传至仓库,保证结构清晰);
    • 项目的在线预览链接(推荐使用 VercelNetlify 部署);
    • 学习过程记录,包括但不限于:
      • 你是如何学习的(参考资料 / AI 辅助 / 同学交流 / 开发心得);
      • 遇到的主要问题与解决方案;
      • 你的创意和个人思考。

温馨提示

  • AI 是好帮手,但请不要把它当作“代码生成器”直接复制粘贴。
  • 我们更看重:
    • 你是否理解了代码;
    • 你是否在页面里加入了自己的想法和风格;
    • 你是否在解决问题的过程中不断学习与改进。

#8 Compiler & Architecture

前言

计算机体系结构是非常复杂的学科方向,大部分人在学习的路上都会遇到很大困难、不解。因为计算机体系结构涉及的面实在是太广了,从门电路到晶体管,到计算机部件的设计,再上升到软件层面的编译器和操作系统,你需要培养自己的软硬协同的思想,对各个方面可能都需要有一个系统的认识与了解,毕竟软件的很多设计与问题都是需要在对硬件的了解下才可以清楚的。但知识永远是可以学会的,不要对知识保有畏惧心理,请相信自己,别人可以做到的你一样可以。

Compiler是计算机体系结构学习中很重要的部分,对Compiler的学习,可以对你思维方式进行很大程度的提升,并且在对Compiler的后端架构与寄存器的考量更是对你体系结构学习的一个重要考核。

下面的所有题目只是计算机体系结构的冰山一角,如果你阅读完整个题目后觉得自己对于这个方面非常感兴趣,可以到 CS自学指南 进行更深入的学习,或者通过招新题进入工作室的方式获得学长更加细致化的指导(墙裂建议)。下面的所有题目并不要求全部做完,你的努力我们都看在眼里(看在你的md文档里),所以不论题目完成到什么程度,请务必将你的学习过程和目前进度发送给我们,Respect!

这个难度并不是依次递增的,只是按照编译的一个基本流程去出题的,所以有做不出来的题目可以试着往后面做(加油!!!)

开始

Compiler 之旅是一段漫长且艰辛的旅程,我周围有很多人选择做这个,也有很多人放弃了,对我而言,就是一点点做了做,最后发现也没有那么难,最后就做了出来,可能很多时候就是这样的,需要我们先勇敢迈出第一步去做一下…

当然,我希望自己可以做一个好的引路人,可以方便容易的让你对Compiler有一个入门…

Compiler

让我们以小谢的身份进入这场 Compiler 之旅。

在学习任何新的东西之前,如果能够先整体了解一下,那就是个不错的开始,Compiler的学习自然也是如此。对于新人小谢来说 CS 143 Compilers … 这个未免也晦涩与枯燥了吧,小谢继续寻找着,直到发现 编译体系漫游, 内心os:实在讲的太好了捏,图文并茂,墙裂推荐

TASK0

看完上述科普向视频,并借助AI工具,相信你能记下了大量的笔记,大概能对编译器是干嘛、编译的流程、现在市面上有哪些编译器(编译器框架)有一个大概的了解,请在你的提交文档中包含但不局限于以下几个问题:

  1. 什么是编译器?编译器的大致工作流程是怎样的?
  2. LLVM 编译器的架构是怎样的?
  3. 编译器中端的主要任务是什么?

TASK1

学习编译的最好方式当然是 (os:直接套用别人的项目 )自己动手写一个编译器,但是从0实现一个完整的编译器又是一个任务量巨大且十分困难的工程,更不要说实现一个优化性能超强、拓展性极好的编译器了。一般来说,大家编译器入门的第一个小项目应该是实现一个支持四则运算的编译器,这其中涉及到根据我们所给定的文法来实现特定的功能。

考虑到实现难度问题,当然是不会让你手搓编译器前端滴,那简直是效率又低,而且在工业界也是使用成熟的工具进行处理。

我们需要依托FlexBison工具来完成我们的编译器。

在开始之前,你需要了解

  1. 什么是Flex、Bison?
  2. 什么是文法,有哪些文法?

要求实现:

  • 实现支持加减乘除,逻辑运算的整数计算器,实现正确的计算优先级 (经典中的经典)
  • 正确实现优先级 例如4 * (6 - 2)
  • 根据下面的表达式拓展Flex、Bison程序
  • 注意特殊情况,例如:与 0 相关
实现下列的表达式:    
    (a ++ b) ::= a + (b + 1)
    (a &* b) ::= (a & b) * b
    (a |* b) ::= (a | b) * b

Eg:

输入:1 -- 2
输出:-1

选做内容:

  • 实现浮点数的计算
  • 实现计算器你想添加的任何功能

参考资料:

自己动手写编译器

Flex与Bison中文版电子书

Flex与Bison使用教程

Flex

Bison手册

Task2

小谢同学顺利的完成了 Task1 的任务,发现flex,bison 起到了词法分析与语法分析的作用,小谢接着了解了LLVM项目后面流程,发现LLVM 的项目会生成中间代码 IR (Intermediate Representation),这里面的学问就大了,让我们跟随小谢同学一步步往下开展:

LLVM IR

首先小谢同学思考这个IR存在的意义是什么,明明可以直接从C语言一步步映射到目标的架构例如 RISC-V指令,那为什么还需要存在一个中间 IR 来将 C语言先转化成 IR 再翻译成 RISC-V 指令呢?小谢同学又多想了其他的语言以及后端架构,假设 C,Rust,Java语言到后端的MIPS,ARM,RISC-V,那么就是 C → MIPS , C → ARM, C → RISC-V, Rust → MIPS… 共是九种,而如果有中端架构 IR 存在的话,任何的语言都需要先转化成中端架构 IR 再转换成后端的汇编指令,相乘的关系就变成了加法,所以 C,Rust,Java → IR → MIPS, ARM, RISC-V 就是 3 + 3 = 6 种的情况存在。

IR的存在可以避免转化的时候写很多重复冗余的结构,当然IR也是存在很多其他好处的,我们之后也会讲解到的。

要求:

  • 了解 LLVM IR的一些基础语法 (建议把Task 2 读完再同一做)
  • 了解一些 MLIR (选做,但强烈建议了解一下

SSA (Static-Single-Assignment Form)

SSA 是 IR 的一种属性,要求每个变量仅被赋值一次并且再被使用前定义。(其实核心思想就是确保每个变量只被赋值一次),举个例子就好理解了

1: x = 1;        
2: y = x + 1;
3: x = 2;
4: y = x + 1;
5: return y;

这个代码转化为 SSA 的形式就变成了

1: x1 = 1;
2: y1 = x1 + 1;
3: x2 = 2;
4: y2 = x2 + 1;
5: return y2;

这个 x1,x2 相当于对 x 有了版本的控制,将原本 x 的生命周期进行了重新划分,本来x的生命周期从 1 到 4 ,而进行了SSA 的转化 x1 的生命周期是 1到 2, x2 的生命周期是 3到 4。因为在 3 语句处 x 被新的值进行了重新的定义,所以此时的 x 和前面的 x 其实可以不算是同一个 x ,才进行了新的 def 。

那这样做有什么好处呢?

对优化的进行做深厚的准备。(好像等于没说

其实编译器有中端这个概念,并且发展到现在的形式,最最具有革命性的突破是1991年静态单赋值形式(SSA Form)的引入。明明只是简单的约束条件(确保每个变量只被赋值一次)却带来了十分深刻的影响。

SSA 的东西其实还有很多需要讲的,剩下的就要交给小谢自己了。

学习链接: 第一章:编译与静态代码分析概论 | SSA.to

你会在很多网上链接中找到答案,我给你的仅仅可以做一个参考

要求:
  • 上网再查询资料,谈谈自己对 SSA 的了解
  • SSA有很多其他的形式与变种,去了解一下呢
  • 到目前为止,是不是有些情况的代码, SSA 是无法转化的呢 (思考ing …)

Value, Use, User

小谢同学接着学习LLVM 项目,他听到了 “LLVM 中一切皆 Value”的这样的话,注意到了 Value,Use,User 这样的 class 类,并且对此产生了浓厚的兴趣…

这部分应该是 LLVM中很核心与关键的部分了,因为存在 这样的关系才使得很多的优化可以得以施行

​ (老图常用了属于是)

这里举一个例子来帮助大家更好的理解这样的关系。

int main()
{
	int a = 10;
	int b = 20;
	int c = a + b;
	return c;
}
define i32 @main(){
.0:
  %.7 = alloca i32
  %.4 = alloca i32
  %.1 = alloca i32
  store i32 10, i32* %.1
  store i32 20, i32* %.4
  %.8 = load i32, i32* %.1
  %.9 = load i32, i32* %.4
  %.10 = add i32 %.8, %.9
  store i32 %.10, i32* %.7
  %.12 = load i32, i32* %.7
  ret i32 %.12 
}

相信你对 LLVM IR 已经有了一定的了解,alloca 语句就是开辟内存,store 存储值到对应的内存地址,load便是从对应的地址中将值加载出来。(这个其实也是一个难点)

我们重点看一些 %.10 = add i32 %.8, %.9 这行指令,%.10 是一个 User(使用者),它使用了两个 值 %.8, %.9 ,(被使用者);在内存中如何建立这种使用与被使用的关系呢?当然是大一上所学习的数据结构。嗯,还需要注意的是 %.8 (被使用者)在 %.8 = load i32, i32* %.1 语句中,又是一个 User(使用者)了。所以一个值既可以是使用者也可以是被使用者,如果一个类中我们可以存储它的使用者,也要存储它的被使用者,那这个变量的定位就是那么那么清晰了。

当然,前面我只是笼统的在说,如果你也想要了解这个数据结构,下面任务可能会帮助到了。

深入浅出 LLVM之 Value 、User 、Use 源码解析 13

对于LLVM之类的编译器是如何实现在构造 SSA 形式的 IR 的时候,计算出 def-use 链? - 知乎

GitHub - bigSheep123/JoTang_Compiler: To recruit new members for Caramel (一个 Value,User,Use 实现的小模型)

https://github.com/llvm/llvm-project.git(llvm 源码 低版本的就好,2.7左右,不强制一定阅读)

要求:

  • 阅读上面的文章,以及找各种资料,理解Value,Use,User这一套数据结构
  • 阅读小模型的代码,谈谈小模型是如何实现Value,Use,User这一套的,你之后也会实现的(
  • 选择(不)阅读 llvm 源码,编译 llvm 源码 (选做)

BasicBlock && CFG

小谢在学习了 Value,Use,User 之后对简单的 IR 代码有了很深刻的认知,但是他发现LLVM项目中的包含链实际上很长 Value → User → Instruction → BasicBlock → Function → Module … 他想继续往后面去了解更多,当然了包含链不止这么一条,其实还有很多,很复杂(

下图是一个对 IR 的 .ll 文件的一个划分:

(opt -dot-cfg xxx.ll) 获得一张图片

​ (截自 知乎 贝壳与知了用户,因源链接已经失效 特此说明)

看上图可以很清楚的看到,函数中存在很多的基本块(BasicBlock)

通过划分基本块,就可以得到 CFG (control flow graph) 控制流图。

如果单说基本块,那通过跳转语句和一些划分算法,可以想到把函数划分为一个一个的块,每个块里面存储着很多的语句,这每个块就是基本块呗,那 CFG 是用来干什么的呢?

CFG是程序中IR的逻辑关系的载体,后续自然也是为了优化(

因为优化其实是可以按照针对的部分,分成很多的种类的,比如说 基本块内优化,函数内优化,过程间优化 … CFG 就记录着基本块的前驱以及后继的种种关系,有助于你之后进行的各种优化,有了CFG记录的关系,你也可以建立新的关系,例如支配树(哭)。

要求

  • phi函数是什么呢?对于分支形式代码如何转化为SSA形式呢?(答案竟然在题目中)
  • 支配树是什么呢? 如何确立支配关系呢?(偏难)
  • 去了解一些 Lengauer-Tarjan Dominators Algorithm 呢?借助网上各种资料

opt (优化)

小谢同学有了前面的铺垫,现在终于可以来到中端的优化环节了。

那优化到底是什么呢?

是有利可图的,逻辑不会变的同等状态的转移

优化是一个专门的学问,在编译器的学习中,不同的优化可能有不同的侧重,但也可能会达到相同的效果,并且优化的不同顺序还会导致不同的结果,下图是鲸书中给出的一个优化顺序和一些优化,但针对不同的样例结构有些优化是很重要的,而另一些优化可能就不需要去执行,这些可能都需要我们去一点点实现。

GitHub - bigSheep123/JoTang_Compiler: To recruit new members for Caramel 这个小模型里面有我实现的几个优化,一般 mem2reg 是进入中端要做的 第一个优化,但是这个优化太难了,不会要求你在如此短的时间呢去实现,但是你需要去了解这个 优化,了解mem2reg的目的与作用。

小模型里面还有 DCE 和 sccp 优化的实现(也可以简单看一下),但是你的任务是根据提示(在 README.md 里面)去动手写一下 尾递归消除(Tail Recursion Elimination)的优化,详细的介绍和要求都写在了项目文档里面,这里不多介绍了。

要求

  • 上网借助资料去了解 mem2reg,了解支配树与 mem2reg的关系
  • 了解 phi函数与 mem2reg 之间的关系
  • 调试起小模型的项目,并且完成 README.md 里面的需要完成
  • 根据提示去完成 尾递归 调用优化,也可以按自己思路进行发挥 (难)

Task3

恭喜你了解了编译器前中端的部分,到现在开始和小谢同学一起进入编译器后端的学习。

在编译器的后端,我们需要针对目标机器的架构生成对应的汇编代码。(那么多种架构,我到底要做哪种???)在这节呢,我们需要针对RISC-V架构的目标机器来生成RISC-V汇编代码(RISC-V 是开源指令集)。可能读到这里你想到完成这道题目既需要完成编译器前中端,又需要从零开始写编译器后端,想想就头大!!!嘿嘿其实要小谢在这么短时间搓出一个完整的编译器前中后端也不是很现实的。本题只需要你完成很简单的任务,以此来了解一下RISC-V汇编即可。

题目内容:

  • 配置环境:由于我们的笔记本电脑大多都是arm/x86环境,所以我们需要一个RISC-V,编译RISC-V完整工具链,并且配置qemu RISC-V环境模拟器。基于RISCV工具链和环境,你可以尝试整个从编译源文件到运行可执行文件的所有步骤,由于工具链不同,命令可能不同,在此只给出一个示范:
# 得到RISCV汇编文件
riscv-unknow-elf-gcc -S -o test.s test.c
#
riscv-unknow-elf-as -o test.o test.s
# 生成可执行文件
# “[ ]”中内容是可选项
riscv-unknow-elf-gcc -o test test.o [library.c] -lm
# 执行
qemu-riscv64 test [< test.in]
# 查看返回值
echo $?
  • 了解RISC-V汇编语言程序,你需要关注的点包括但不限于:寄存器,堆,栈,指令
  • 根据给出的参考资料以及自己从网上搜寻的资料,使用RISC-V指令集实现选择排序程序,给出必要部分即可。
  • (选做)尝试在qemu模拟器中调试你自己的riscv汇编

参考资料:

RISC-V汇编入门

riscv-gnu-toolchain

RISC-V Book

汇编代码调试

RISC-V Book 中文版

RISC-V GNU工具链的编译与安装

Task4

有了上面的对于RISC-V 程序的一个基本了解,让我们继续跟随小谢同学来开展编译器的后端,Task3 的部分是很重要的,如果你没有比较好的RISC-V 的基础,那么你肯定不能很好的想清楚之后的事情…如果觉得Task3 布置的任务完成的不好,请先完成Task3的任务,再进行下面内容的学习。

编译器的后端最简单的实现可以直接从IR 指令一条一条映射到RISC-V 指令,映射可能是一条对一条映射,也可能是一条对多条的映射,(当然这个代码量可能是庞大的),但是后端设计的难点在于你对栈帧的设计,以及寄存器的分配。如果你观察仔细,你会发现中端生成的 %.0, %.1,%.2其实你可以理解成虚拟寄存器,而且他们的个数是无限的,但是实际上寄存器是非常宝贵的资源,你在RISC-V 对应的寄存器是极其有限的(如下,这个仅仅是整数寄存器)。

如果你不分配寄存器,变量的值就存储在栈帧当中,那么你就必须使用 lw/sw 指令去在使用时加载变量/修改时存储变量到寄存器。但是如果随意使用寄存器,那么会导致寄存器中存储的值丢失,进而导致程序错误,并且有效合理的分配寄存器才能让生成的汇编代码是更加精简的。

(lw/sw 指令会使我们的指令周期大大增加,并且在RISC-V 架构下,我们无法直接使用内存中的值,必须要 load 到寄存器中才可以进行后续操作。)

在Task4 的任务下,你需要去搜集以及阅读相关文章,去了解更加详细寄存器分配的过程。

要求:

尽自己努力去了解就好,将自己了解到的和自己的思考记录下来。

小谢的编译器之旅也在这次的指导下有了进展与进步…

提交内容:

  • 所有的程序源代码(需要上传到GitHub仓库,提交时提交链接)
  • 你的Markdown文档,要把要求的内容写入Markdown中

考虑到我们的题目难度可能偏大,需要你去了解的东西很多很多,所以最终没有完全实现也是没有关系的,重要的是你这一路的学习理解过程,请务必记录在你的Markdown文档中!

如果有佬全部实现了所有的内容以及对计算机体系结构感兴趣,欢迎随时联系出题人:dh100086000 (wechat)