青岛探店计划-台东(一)
最近一直在学校里呆着,感觉也不是个事儿,总想找点出校转转的动机。于是乎一时兴起,想开一个板块,专门记录青岛本地的美食,顺便在博客里记录一下,干脆就叫青岛探店计划吧。 第一期:台东其一 来了青岛快一年了,一直没怎么去台东。一方面是离学校有点距离,另一方面也是没什么动机去逛。正好爸妈来青岛转,让我带着逛逛。青岛站附近适合晚上逛的步行街,脑子里最先想到的就是台东。作为青岛最大的步行街之一,台东步行街上的小吃还是相当丰富的。这次去没有品尝太多种类,主要还是挑了几家排了长队的小吃店。 坐地铁一号线到台东站下车,从F口出来就是台东啤酒交易所,按照屏幕上的提示付完款,从边上拿个送的塑料杯,拉下拉杆就能自动打出来一杯啤酒了。种类很多,可以按个人爱好选择,这次尝了一下葡萄味的,葡萄汁味还是挺重的,开始都不大能喝出来啤酒味,回味的时候才有股酒精的味道。 台东啤酒交易所 葡萄啤酒 第一个路口左转往里走,就进入了台东步行街。左手边街角的一家“金丝牛肉饼”马上吸引了我的注意:店门口早排起了长龙,男女老少都有。我凑近橱窗看了一眼,金色的面丝包裹着里面的馅料,看起来口味不错...
Git入门到精通:版本控制的艺术
前言 在软件开发的世界里,“我的代码昨天还能跑”是最令人崩溃的瞬间之一。你改了某个函数,加了新功能,然后一切崩溃了——而你甚至不记得改了什么。这就是版本控制系统存在的意义,而 Git,就是这个领域的王者。 本文将从零开始,系统地介绍 Git 的核心概念和实用技巧,帮你从”只会 git clone”成长为能在团队中自如协作的 Git 用户。 一、什么是版本控制 想象你在写一篇论文: 论文.doc → 论文_修改版.doc → 论文_最终版.doc → 论文_最终最终版.doc → 论文_死也不改了.doc 这就是最原始的手动版本控制。问题很明显:混乱、无法追溯、难以协作。 版本控制系统(VCS) 会记录文件在时间维度上的每一次变化。你可以: 随时回退到任意历史版本 查看每次修改的具体内容和修改者 在不影响主线的情况下并行开发新功能 将多个人的修改智能合并 VCS 经历了三代演进: 本地版本控制:只在本地维护一个简单的数据库来记录差异 集中式版本控制(如 SVN):所有版本数据存在一个中央服务器上,每个人从服务器检出一个快照...
嵌入式开发必备:深入理解I2C通信协议
深入理解I2C通信协议 在嵌入式系统开发中,通信协议是连接各种外设的桥梁。除了之前介绍的USART串行通信协议,I2C(Inter-Integrated Circuit)作为另一种广泛使用的同步串行通信协议,以其简单的硬件连接和高效的通信方式,成为单片机与传感器、存储器、显示屏等外设通信的首选方案。本文将详细介绍I2C的工作原理、特点,并给出基于STM32单片机的代码实现示例。 什么是I2C? I2C:Inter-Integrated Circuit,即集成电路互连总线。I2C最初由飞利浦半导体(现恩智浦NXP)在1982年开发,最初目的是为了简化电视机内部不同芯片之间的通信。如今,I2C已成为嵌入式领域中最常用的通信协议之一。 I2C的主要特点 特性 说明 两线制通信 只需要两根信号线:SCL(时钟线)和SDA(数据线) 多主多从 支持多个主设备和多个从设备挂在同一总线上 半双工通信 数据可以在两个方向上传输,但不能同时进行 可变位速率 标准模式100kbps,快速模式400kbps,高速模式3...
CMake 介绍与基础使用
最近做项目用到ESP32,还顺便尝试换用CLion写STM32,开始不断接触到CMake编译链,感觉挺有意思也挺好用的。所以写一篇文章来简单介绍并记录一下CMake的基础用法。 简单介绍一下吧: CMake 是个一个开源的跨平台自动化建构系统,用来管理软件建置的程序,并不依赖于某特定编译器,并可支持多层目录、多个应用程序与多个函数库。 CMake 通过使用简单的配置文件 CMakeLists.txt,自动生成不同平台的构建文件(如 Makefile、Ninja 构建文件、Visual Studio 工程文件等),简化了项目的编译和构建过程。 CMake 本身不是构建工具,而是生成构建系统的工具,它生成的构建系统可以使用不同的编译器和工具链。 CMake 的作用和优势: 跨平台支持: CMake 支持多种操作系统和编译器,使得同一份构建配置可以在不同的环境中使用。 简化配置: 通过 CMakeLists.txt 文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本。 自动化构建: CMake 能够自动检测系统上的库和工...
2025年度总结:充实的一年
回到实验室,只有一个学长在,其他人都去跨年了。打开电脑才想起来,是时候该为过去的一年写下些什么了。如果让我为过去的一年想一个词来形容,那应该就是充实。这一年里有哭有笑、有离别也有相识,想写的东西的确是很多。 今年发生了什么? 高考! 思绪回到25年上半年,那时候还是一名冲刺高考的高三学生,现在回想起来那时的我还真是挺厉害的,要是把现在的我扔到高中去指定过不下去,哈哈。总而言之,结果是还不错的,虽然最终的发挥不及一模,但是还是取得了相对满意的成绩,来到了一个我比较满意的大学。 进入实验室! 当毕业典礼结束,我也正式地告别了高中的生活,来到了青岛,一座很美丽的城市。记得是报道当天,看见电赛实验室居然直接在现场纳新,就直接进了纳新群,后续也是比较顺利地加入了实验室飞行器组。从初中了解了电赛开始,我就一直很向往这四天三夜的比拼,最后还是期待能在明年的省赛和国赛取得好的成绩! 搭建博客! 不得不承认,我是一个喜欢折腾的人。很久之前就有搭建博客的想法,但是鉴于财力不足以及鲜有时间去维护博客,一直没能搭起来。高考之后总算是有了机会,把博客搭建起来了,一开始是使用WordPress...
嵌入式开发必备:深入理解USART通信协议
深入理解USART通信协议 在嵌入式系统开发中,通信是至关重要的一部分。在电赛中,我们往往会用到STM32开发板、CanMV开发板、树莓派等板载计算机,他们之间要进行数据的交换就必须进行通信。而USART(通用同步 / 异步收发传输器)作为一种常见的串行通信接口,广泛应用于各种设备之间的数据传输。本文将详细介绍USART的工作原理、特点,并给出基于STM32单片机的代码实现示例。 什么是USART? USART:Universal Synchronous Asynchronous Receiver Transmitter,即通用同步异步收发器。USART最初是由Motorola在1970年代设计的,用于解决早期微处理器与外部设备之间的串行通信问题。随着技术发展,USART逐渐成为嵌入式系统中不可或缺的标准接口。 与UART的区别 特性 UART USART 全称 通用异步收发器 通用同步异步收发器 通信模式 仅支持异步 支持同步和异步 时钟信号 无CLK引脚 有CLK引脚(可选) 硬件...
Huffman算法求最优二元树
什么是 Huffman树? 哈夫曼树(Huffman Tree),又叫“最优二元树”,它的核心思想非常简单,可以用一句话概括:“大权值靠近根,小权值远离根”。这样做也是为了让总的“代价”最小。 做这类题,甚至不需要死记硬背复杂的代码逻辑,只要掌握“排、取、加、放”这四个字的口诀即可。 下面我通过一个具体的例子一步步做。 一、 核心步骤 排:把所有还没有处理的数字(权值)从小到大排列。 取:取出最小的两个数字。 加:把这两个数字相加,得到一个新的数字(父节点)。 放:把这个新的数字放回刚才的队伍里,并把之前那两个取出来的数字删掉。 循环:重复上面的步骤,直到队伍里只剩下一个数字(这个数字就是树的根)。 二、 手把手演示 题目:有一组权值 W = {2, 3, 6, 8, 9},请构建哈夫曼树,并计算带权路径长度 (WPL)。 第一轮: 排:目前池子里是 {2, 3, 6, 8, 9} (已经有序)。 取:最小的俩是 2 和 3。 加:2 + 3 = 5。 放:把 5 放回去。此时池子变成了 {5, 6, 8, 9}(注意:2和3已...
Kruskal算法和Prim算法求最短路径
Kruskal算法: 在离散数学中,Kruskal 算法是一种用于求解带权无向连通图的最小生成树(MST)的经典算法。 它的核心思想非常直观:贪心策略。也就是说,我们总是试图从图中挑选出当前权重最小的那条边,只要这条边不与已经挑选出的边形成回路(环),就把它加入到生成树中。 下面,我将通过一个示例直接演示Kruskal算法的操作方法。 1.算法核心步骤 在开始实例之前,先记住 Kruskal 算法的三个核心步骤: 排序:将图中所有的边按照权重从小到大进行排序。 选边:从权重最小的边开始考察。 判环: 如果这条边连接的两个顶点目前不在同一个连通分量里(即加入这条边不会形成回路),就选中这条边,加入生成树。 如果这条边加入后会形成回路,就丢弃这条边。 结束:重复步骤 2 和 3,直到选够了n − 1条边(n是顶点数),或所有边都考察完了 2.实例设定 假设我们有一个带权无向图,包含 5 个顶点:A,B,C,D,E。 (A,B) : 权重 4 (A,C) : 权重 1 (A,D) : 权重 3 (B,C) : 权重 2 (B...
Dijkstra算法求最短路径
1.什么是 Dijkstra 算法(标号法)? Dijkstra 算法用于在一个带权有向图(通常权值非负)中,从指定的起点出发,求出该起点到图中所有其他顶点的最短路径。 “标号法”这个名字来源于它的操作方式:算法过程中,每个顶点都会被赋予一个标号。 2.实例设定 T 标号(Temporary Label,临时标号):表示从起点到该点的暂时的最短路径长度估计值。随着算法进行,T 标号会不断变小(被修正)。 P 标号(Permanent Label,永久标号):表示从起点到该点的真正的最短路径长度已经找到了,不再改变。一旦一个顶点获得 P 标号,它就相当于被“确定”了。 假设我们有如下所示的带权有向图,设起点为V1,我们需要求V1到其他所有点的最短路径: (注意:如果两点之间没有直接连线,可以理解为权重无穷大 ∞) 图的边及权重(邻接关系): V1 → V2 (权重1) V1 → V3 (权重4) V2 → V3 (权重2) V2 → V4 (权重5) V2 → V5 (权重10) V3 → V4 (权重1) V4...
Warshall算法求传递闭包矩阵
1.什么是传递闭包? 在深入了解Warshall算法之前,我们先要明白目标是什么。 传递闭包:对于一个有向图 G,它的传递闭包是另一个图 G,G 和 G 拥有相同的顶点。如果在原图 G 中,从顶点 i 到顶点 j 存在一条路径(路径长度可以大于1),那么在 G* 中就存在一条从 i 直接指向 j 的边。 简单来说,传递闭包就是回答这样一个问题:“从任意一个点出发,我能到达哪些其他的点?” 如果能到达,就连一条直接的边。 举个例子: 如果 A → B,且 B → C,那么在传递闭包中,除了原有的 A→B 和 B→C,我们还会新增一条 A→C 的边。 Warshall算法就是用来高效计算这个传递闭包的利器。 2.Warshall算法的核心思想 Warshall算法的精髓在于“逐步引入中间点”。 想象一下,我们想知道从城市 i 能否到城市 j。一开始,我们只看有没有直达的航班。后来,我们允许在城市1中转,看看会不会增加新的可达路线。接着,我们再允许在城市2中转,看看会不会又增加新的路线……直到我们把所有城市都当作过中转站考虑了一遍,最终得到的就是完整...
