Git
git submodule
- git submodule 命令用于管理包含其他 Git 仓库的项目。 git submodule可以将外部库作为你的项目的一部分来管理,而不必将其直接合并到主仓库中。 •
- Git submodule init初始化配置文件中的所有子模块:根据.gitmodules文件中内容设置子模块的URL和路径到本地.git/config中,不下载子模块的内容 •
- Git submodule uodate从远程仓库中拉取子模块的内容,并将其更新到.gitmodules文件中指定的提交 (--recursive递归更新所有子模块 --remote从子模块的远程仓库中拉取最新更改) •
- git submodule add <repo-url> [<path>] :<repo-url> 是子模块的仓库地址,<path> 是子模块在主仓库中的路径(可选,如果不指定,默认使用子模块仓库的名称作为路径)。 •
- git submodule deinit [<path>]: 将子模块从 .git/config 文件中移除,并删除子模块目录中的文件。 •
- git rm [<path>]:将子模块的引用从主仓库中删除,并提交更改 •
- git submodule 列出所有子模块 •
- git submodule status 查看模块当前状态(提交hash、路径、是否有未提交)
2. git config查看和设置配置信息
3. git diff <branch1> <branch2>比较分支差异**
4. git stash
作用 :临时存储未提交的代码改动(包括工作目录和暂存区的修改),便于切换分支或处理紧急任务后恢复工作。
适用场景:
• 代码改到一半需切换分支修复 Bug(未完成代码不想提交)
• 拉取远程代码(git pull)前,避免未提交改动引发冲突
• 多任务中断时保存当前进度
# 存储当前改动(默认名称为stash@{0}) git stash
# 存储并添加备注 git stash save "备注内容"
# 查看所有存储记录 git stash list
# 恢复最近一次存储的改动(保留存储记录) git stash apply
# 恢复最近一次存储的改动(并删除该记录) git stash pop
# 丢弃指定存储(如stash@{1}) git stash drop stash@{1}
# 清空所有存储 git stash clear
5. git revert
作用 :安全撤销某次提交 ,通过生成一个新的"反向提交"抵消原提交的改动,保留完整历史记录。 适用场景:
• 撤销已推送到远程仓库的提交(避免重写历史)13
• 协作开发中回退错误代码(不影响他人分支)
核心特点:
• 🔄 不破坏提交历史,适合公共分支
• ⚙️ 可能需手动解决冲突(新旧代码冲突时)
• ❌ 与 git reset 的区别:reset 直接删除提交(危险操作),revert 是安全撤销1
• # 撤销某次提交(生成新提交抵消改动) • git revert <commit-hash> •
# 撤销最近一次提交 • git revert HEAD
Linux命令
1. 查看信息
查看当前登录用户whoami /who / id 查看所有用户:cat /etc/passwd | cut -d: -f1
2. 系统服务
以dns为例:(具体命令还和系统和版本有关,这里是ubuntu18.04) sudo systemctl restart systemd-resolved.service sudo service systemd-resolved restart sudo /etc/init.d/ systemd-resolved restart 查找dns服务进程:ps -ef | grep system-resolved 查看状态用status
3. Linux中通过域名查找ip
Nslookup <域名> Dig/host/ping/fping/tracert Ping/ nslookup /tracert windows也可用 **网络通信
4. Linux网络通信------字节序转换----htonl()、htons()、ntohl()、ntohs()
** 头文件:#include <arpa/inet.h>
原型:uint32_t htonl(uint32_t hostlong)
uint16_t htons(uint16_t hostlong)
uint16_t ntohs(uint16_t hostlong)
uint32_t ntohs(uint32_t hostlong)
注意缩写的扩展名就知道函数意义了: h表示host------主机 n表示net------网络 l表示long------unsigned long s表示unsigned short 几个函数功能都是网络和主机字节顺序的转换 (主机字节顺序可能是大端顺序或者小端顺序(这个要看编译器的设置,还有自己是用的C还是Java还是其他的语言,其各自都是不尽相同),但是网络字节顺序一定是大端顺序。)
5. ipv4/mac地址字符串转换------inet_aton inet_ntoa
// 点分十进制转网络字节序(eg:192.168.0.1)
int inet_aton(const char *cp, struct in_addr *inp); (返回值为0失败,in_addr *inp为出参)
in_addr_t inet_addr(const char *cp); (直接返回一个地址) // 网络字节序转点分十进制(返回一个地址字符串)
char *inet_ntoa(struct in_addr in); // mac地址字符串和字节之间的转换
头文件:#include <netinet/ether.h>
Ether_aton ether_ntoa ether_aton_r ether_ntoa_r
6. Linux------套接字
头文件:#include <sys.types.h> #include <sys/socket.h>
这里相关的套接字直接看原型就比较明白:
// 创建套接字 int socket(int domain, int type, int protocol);
// 绑定地址到套接字 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 监听连接 int listen(int sockfd, int backlog);
// 接受连接 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 发起连接 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 关闭连接 int close(int fd);
数据流
// TCP 数据流 ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t recv(int sockfd, void *buf, size_t len, int flags);
// UDP 数据包 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
7. 网络信息查询
头文件:#include <netdb.h> 这类函数的原型很明显的表明了使用方法
// 获取主机信息 struct hostent *gethostbyname(const char *name); struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
// 获取服务信息 struct servent *getservbyname(const char *name, const char *proto); struct servent *getservbyport(int port, const char *proto);
// 地址和服务名解析 int getaddrinfo(const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result);
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
8. linux---route/ip route命令 Route:
Route [选项] [操作] [目标] [参数]
Route -h 可查看使用手册
常用:
route -n 查看路由表
常用选项
-n # 以数字形式显示地址(不解析主机名)
-v # 显示详细操作信息
-e # 使用 netstat 格式显示路由表
-A family # 指定地址族(如 inet 或 inet6)
IP Route: 新工具功能更强大: ip route help 打印出使用手册
使用格式: ip route {list| flush}
SELECTOR 常用:ip (-6) route -n 查看路由 ip r ip route ip route show ip route list 均可查看路由
8**. brctl命令**
Brctl管理以太网桥 启动:
modprobe bridge ## 加载 bridge 模块
echo "1">/proc/sys/net/ipv4/ip_forward ## 开启转发,多个网卡之间进行数据交互
Brctl --help输出使用手册(这个手册非常清晰)
常用:brctl show 展示当前的网桥配置
Linux函数
1. memcmp/memcpy函数
头文件:#include <string.h>
直接比较两个内存块之间的字节内容
声明:int memcmp(const void *str1, const void *str2, size_t n)
• 如果返回值 < 0,则表示 str1 小于 str2。
• 如果返回值 > 0,则表示 str1 大于 str2。
• 如果返回值 = 0,则表示 str1 等于 str2。
常用于字节内容的比较,参数n指明了需要比较的字节长度
类似的C 库函数 **void *memcpy(void str1, const void str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1
2. strdup函数
头文件:#include <string.h> char *strdup(const char *s);
复制一个内存空间完全独立的字符串副本,返回指针,使用后最后一定得手动释放指针
下面是规范用法:
cpp
#include <syslib.h>
#include<string.h>
int main(void) {
char *src ="This is the jibo";
char *dest;
dest = strdup(s);
printf("the dest %s\n",dest);
free(dest); // 切记释放空间
return 0;
}
3. strtok/strtok_r函数分割遍历
头文件: #include <string.h>
常用于分割约定俗称的字符串并处理:
声明:char *strtok(char *str, const char *delim)
第一次使用str传需要分割的delim指针(传字符串是多个分割符比如",;"是分割逗号或分号),
后面传NULL;
strtok_r(): **char *strtok_r(char *str, const char delim, char saveptr);
strtok_r() 是 strtok() 的可重入版本,它允许你在多线程环境中安全地使用 使用规范:(saveptr是一个char的指针,保存分割状态)
4. realloc函数
realloc的安全使用方式
(realloc行为) :
如果原有地址后有足够空间,直接追加,指针地址不变 :
如果没有足够空间,新申请一份,copy原来内容,释放原来指针空间,然后返回新的指针地址 由此安全的做法为:
cpp
#include <stdio.h>
int main()
{
int*ptr = malloc(100);
if(ptr != NULL)
{
//业务处理
}
else
{
exit(EXIT_FAILURE);
}
//扩展容量
//代码1
ptr = realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)
//代码2
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}
//业务处理
free(ptr);
return 0;
}
Uboot
switch init setenv ipaddr <ipv4> setenv serverip <ipv4> tftpboot ER8411v1_un_1.3.0_20250114-rel36677_nandflash_noecc.bin nand erase.chip nand write {loadaddr} 0 {filesize} reset 史上最全的Uboot常用命令汇总(超全面!超详细!)收藏这一篇就够了_uboat控制台指令大全-CSDN博客
VPP
www.meemx.com vpp使用详解
MakeFile
-
三要素:目标、依赖、命令
-
命令以tab开头
-
默认执行规则为第一条,其他顺序无关性
-
make使用文件的创建和修改时间来判断是否应该更新一个目标文件;makefile支持增量编译
-
伪目标:clean、install......
-
一条规则可以有多条命令
-
/ 分割长命令到不同行 ; 分割不同命令 (;分割后会当成不同的命令,make的每条命令有一个独立的shell空间)
-
一种执行多条命令的语法是用&&,它的好处是当某条命令失败时,后续命令不会继续执行
-
@ 可以指定某一条命令不回显到输出
-
有些时候,我们想忽略错误,继续执行后续命令,可以在需要忽略错误的命令前加上-
代码优化和性能提升
-
常见的代码优化思路 18 极致优化(上):如何实现高性能的 C 程序? - 极客时间文档 :高速缓存(局部性原理)、内联函数(预处理逻辑)、restrict关键字(编译成汇编时由于确定数据不会被其他指针更改,可以减少访存次数)、减少不必要的内存引用(比如累乘运算使用register定义一个寄存器局部变量不用多次访问内存) 19 极致优化(下):如何实现高性能的 C 程序? - 极客时间文档 :循环展开(本质上是利用提高CPU指令流水线占用率)、条件传送指令优化(三元运算符代替ifelse)、利用编译器的优化等级、迭代代替递归 Debug
-
为什么同时编译两个大型项目会导致虚拟机崩溃,最终导致编译任务失败? 场景:有一个buildroot框架的项目,复制一份到另一个目录,其中两份代码进行不同的配置,命令行同时启动编译,最终导致崩溃 原因推测: • CPU资源耗尽 Buildroot项目编译会尝试在系统上启动N个并行任务,2个项目同时编译导致系统上同时运行2N高负载gcc进程;超越了虚拟机CPU核心处理和能力,调度器不断切换上下文尝试分配时间片------系统几乎100%时间用于切换进程,而不真正编译任务,导致系统完全卡顿失去响应,这被称为"Trashing"(系统颠簸) • 内存RAM耗尽 2N个gcc进程的内存需求可能超过虚拟机分配的上限;物理内存耗尽时,操作系统会开始使用交换分区;Swap是硬盘上的一块空间,用来存放不常用的内存页;硬盘读写速度比内存慢几个量级,频繁使用swap系统性能断崖式下跌------系统完全卡死,CPU不再进行编译任务,而是等待缓慢的硬盘读写,如果swap空间被填满,操作系统内核的OOM(Out of Memory)Killer触发强制随机终止进程释放内存,可能导致编译失败 • 磁盘I/O瓶颈 若CPU和内存都满足了上述的资源要求,磁盘io也是瓶颈,两个buildroot项目都快速读写万级文件,磁头需要来回移动,SSD的并发通道也会占满------所有进程都等待磁盘操作,编译速度很慢,系统卡顿 • 潜在的依赖冲突 若所有的性能和资源都满足,两个buildroot编译时可能下载相同软件包到同一临时目录,导致覆盖或损坏;同时编译和安装同一个基础依赖库zlib或openssl等导致文件锁冲突或安装文件错乱------各种不可预知的错误 解决方案:
-
串行编译
-
限制并行度:eg:8核虚拟机------两个项目每个项目 make -j4
-
使用不同的机器
-
硬件升级
-
segmentation fault (SIGSEGV) 问题 该问题就是内存泄漏/溢出:当一个进程执行一个无效的内存引用或发生断错误时,触发sigsegv信号------内核默认动作终止该进程 常见情形------使用非法指针 解决:gdb查看core文件,Linux默认会为sigsegv故障生成一个core文件,该文件记录了出错时的堆栈信息,通过gdb可以快速追踪 Gdb查看命令bt和where Core文件一般会在程序执行的当前目录生成,若无法生成:
-
linux内核限制,ulimit -c <number>设置解除限制(ulimit -a查看限制
-
当前程序没有当前目录的写权限------chown chgrp等命令赋权即可
Snap
Snap 是 Canonical 开发的跨发行版 Linux 包管理系统,核心特点包括:
- 沙盒化运行:每个应用及依赖封装在独立容器中,避免系统污染1
- 自动更新:默认后台静默更新(可配置关闭)
- 版本管理:支持多版本共存与回滚(通过 snap revert)1
- 跨平台兼容:适用于 Ubuntu/Debian/Fedora 等主流发行版 数学表示沙盒隔离原理: Appsnap =(Binaries+Dependencies+Config)⊗Ssandbox
其中 Ssandbox 为安全隔离层。
删除:sudo snap remove <package_name>(会保留~/snap/<package_name>位置的用户数据文件)
彻底卸载:sudo snap remove --purge <package_name>
多版本清理: snap list --all | grep <package_name>
查看所有版本[^1] sudo snap remove --revision=<rev_num> <package_name>
删除指定版本
操作命令示例作用
查看已安装包snap list
显示基础信息查看所有版本snap list --all显示包括非活跃版本
回滚旧版sudo snap revert <package>
清理磁盘空间sudo rm -rf /var/lib/snapd/cache/*
删除更新缓存(需手动执行)
安装snap install <package_name> (--classic)
默认开启自动更新机制:snap get system refresh.timer # 查看自动刷新频率