From 93cecd754418c79be0e522d58a4d9c006a1104a9 Mon Sep 17 00:00:00 2001 From: RongersLY <2281@qq.com> Date: Fri, 4 Apr 2025 17:35:35 +0800 Subject: [PATCH] BIG MERGE!!! BIG ADD: - docker - archlinux FIX: - vim - c_cpp - string hash - linux /dev/random - thread - STL - linux - command - last OTHERS: - add antenna.md - mirrors - makefile.md --- electronic/parameter.md | 10 + miscellaneous/README.md | 0 os/linux/arch/command.md | 19 + os/linux/arch/install.md | 125 ++ os/linux/command.md | 1321 ++++++++++++----- os/linux/config/.bashrc | 117 -- os/linux/config/.profile | 27 - program/c_cpp/STL/algorithms.md | 252 ++++ program/c_cpp/STL/containers.md | 240 +++ program/c_cpp/{universal => }/STL/function.md | 0 program/c_cpp/{universal => }/STL/string.md | 2 +- program/c_cpp/library/offsetof.h | 2 + program/c_cpp/library/string_hash.c | 10 + program/c_cpp/library/thread-pool.cpp | 73 + program/c_cpp/linux/ncurses.c | 24 + program/c_cpp/linux/random.md | 25 + program/c_cpp/universal/class.md | 142 +- program/c_cpp/universal/compile.md | 42 + program/c_cpp/universal/func.md | 47 + program/c_cpp/universal/io.md | 1 + program/c_cpp/universal/ptr.md | 156 ++ .../c_cpp/universal/specifier_qualifier.md | 32 +- program/c_cpp/universal/template.md | 54 +- program/c_cpp/universal/thread.cpp | 35 - program/c_cpp/universal/thread.md | 130 ++ program/c_cpp/universal/常用函数.txt | 34 - program/python/basics/demo.py | 51 +- program/python/basics/string.py | 23 - program/python/basics/summary.md | 97 ++ program/tool/docker.md | 213 ++- program/tool/g++.txt | 29 - program/tool/gcc_g++.md | 43 + program/tool/gdb.md | 63 + program/tool/gdb.txt | 35 - program/tool/makefile.md | 506 ++++++- radio/antenna.md | 37 + tool/git/github | 15 - tool/git/github.md | 40 + tool/konsole.md | 31 + tool/vim/.vimrc | 55 +- tool/vim/ShortcutKeys.md | 52 - tool/vim/cpp.dict | 157 ++ tool/vim/shortcutKeys.md | 89 ++ 43 files changed, 3585 insertions(+), 871 deletions(-) create mode 100644 electronic/parameter.md create mode 100644 miscellaneous/README.md create mode 100644 os/linux/arch/command.md create mode 100644 os/linux/arch/install.md delete mode 100644 os/linux/config/.bashrc delete mode 100644 os/linux/config/.profile create mode 100644 program/c_cpp/STL/algorithms.md create mode 100644 program/c_cpp/STL/containers.md rename program/c_cpp/{universal => }/STL/function.md (100%) rename program/c_cpp/{universal => }/STL/string.md (97%) create mode 100644 program/c_cpp/library/offsetof.h create mode 100644 program/c_cpp/library/string_hash.c create mode 100644 program/c_cpp/library/thread-pool.cpp create mode 100644 program/c_cpp/linux/ncurses.c create mode 100644 program/c_cpp/linux/random.md create mode 100644 program/c_cpp/universal/compile.md create mode 100644 program/c_cpp/universal/func.md create mode 100644 program/c_cpp/universal/ptr.md delete mode 100644 program/c_cpp/universal/thread.cpp create mode 100644 program/c_cpp/universal/thread.md delete mode 100644 program/c_cpp/universal/常用函数.txt delete mode 100644 program/python/basics/string.py create mode 100644 program/python/basics/summary.md delete mode 100644 program/tool/g++.txt create mode 100644 program/tool/gcc_g++.md create mode 100644 program/tool/gdb.md delete mode 100644 program/tool/gdb.txt create mode 100644 radio/antenna.md delete mode 100644 tool/git/github create mode 100644 tool/git/github.md create mode 100644 tool/konsole.md delete mode 100644 tool/vim/ShortcutKeys.md create mode 100644 tool/vim/cpp.dict create mode 100644 tool/vim/shortcutKeys.md diff --git a/electronic/parameter.md b/electronic/parameter.md new file mode 100644 index 0000000..4f6d3b6 --- /dev/null +++ b/electronic/parameter.md @@ -0,0 +1,10 @@ +# 电子硬件参数 + +## 目录 +- [电阻](#电阻) +- [电容](#电容) +- [电感](#电感) +- [微控制器](#微控制器) +- [逻辑器件](#逻辑器件) +- [晶体管](#晶体管) + diff --git a/miscellaneous/README.md b/miscellaneous/README.md new file mode 100644 index 0000000..e69de29 diff --git a/os/linux/arch/command.md b/os/linux/arch/command.md new file mode 100644 index 0000000..e2208da --- /dev/null +++ b/os/linux/arch/command.md @@ -0,0 +1,19 @@ +# arch常用命令 + + - [pacman](#pacman) + + +## pacman + + + `-S` 同步 + + `-y` 更新软件包数据库 + + `-u` 升级已有安装包 + + `-R` 卸载 + + `-Q` 查看已安装 +> 示例 + + `pacman -Sy` 同步数据库 + + `pacman -S ` 安装软件包 + + `pacman -Syu` 更新系统 + + `pacman -Rs ` 卸载同时删除无用的依赖 + + `pacman -Ss ` 搜索软件包 + + `sudo pacman -Sc` 清除缓存 diff --git a/os/linux/arch/install.md b/os/linux/arch/install.md new file mode 100644 index 0000000..16e2494 --- /dev/null +++ b/os/linux/arch/install.md @@ -0,0 +1,125 @@ +# archlinux安装 + +## 目录 +- [基础安装](#基础安装) + - [修改控制台字体](#修改控制台字体) + - [验证引导](#验证引导) + - [验证网络和更改系统时间](#验证网络和更改系统时间) + - [硬盘分区](#硬盘分区) + - [安装基础软件包](#安装基础软件包) + - [生成fstab](#生成fstab) + - [chroot配置](#chroot) +- [新系统](#新系统) + - [换源](#换源) + - [普通用户](#普通用户) + - [KDE](#kde) + +## 基础安装 + +### 修改控制台字体 + +`/usr/share/kbd/consolefonts/` 存放字体的位置 +`# setfont ter-132b` + +### 验证引导 + +`# cat /sys/firmware/efi/fw_platform_size` + +### 验证网络和更改系统时间 + +`ip addr` +`timedatectl` + +### 硬盘分区 + +```bash +parted /dev/sdX # 进入parted交互界面 +> mklabel gpt # 创建分区表格式 + +gdisk /dev/sdX # 分区 +ef00 -> 1G +ef02 -> 2M +8300 -> / + +**先用最小系统启动** + +mkfs.fat -F 32 /dev/sdX1 # 分区格式化 +mkfs.ext4 /dev/sdX3 + +mount /dev/sdX3 /mnt +mount --mkdir /dev/sdX1 /mnt/boot +``` + +### 安装基础软件包 + +`pacstrap -K /mnt xxx` ++ base linux linux-firmware ++ vim base-devel networkmanager archlinuxcn-keyring +--- +以下是可以等系统启动后安装的 ++ sof-firmware ++ yay +`pacman -S git base-devel && git clone https://aur.archlinux.org/yay.git && cd yay && makepkg -si` ++ man ++ fcitx5-im fcitx5-rime # 输入法 ++ alsa-utils # 声卡驱动 ++ 其他固件 + +### 生成fstab + +`genfstab -U /mnt > /mnt/etc/fstab` + +### chroot + +```bash +ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 配置时间 +hwclock --systohc + +vim /etc/locale.gen +> 去掉 en_GB.UTF-8 以及 zh_CN. +locale-gen +vim /etc/locale.conf +> LANG=en_US.UTF-8 + +vim /etc/hostname +> [hostname] + +passwd + +**安装引导** +pacman -S grub +grub-install --target=i386-pc /dev/sdX +grub-mkconfig -o /boot/grub/grub.cfg + +umount -R /mnt + +reboot +``` + +## 新系统 + +### 换源 +- `/etc/pacman.d/mirrorlist` +``` +Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch +Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch +Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch +``` + +### 普通用户 + +`useradd -m -G wheel username` +`vim /etc/sudoers` + +### kde + +``` +pacman -S noto-fonts noto-fonts-cjk noto-fonts-emoji # 安装字体 +pacman -S plasma +systemctl enable sddm + +cd ~/.local/share/fcitx5/rime # 配置输入法 +git clone https://github.com/iDvel/rime-ice.git +cp -r ./rime-ice/* . + +sudo usermod -a -G uucp $USER # 允许用户使用串口 diff --git a/os/linux/command.md b/os/linux/command.md index 0727a77..a509a94 100644 --- a/os/linux/command.md +++ b/os/linux/command.md @@ -1,455 +1,992 @@ -# 基础命令 -> sudo -> > 配置文件/etc/sudoers 使用visudo进行编辑 - + -u # 指定用户 +# linux基础命令 -> pwd - -> cd - -> ls -> > 列出目录下所有内容 - + -F # 在文件名后加提示符 '/' '*' '@' - + -a # 显示隐藏文件 - + -l # 列出文件信息 - + -d # 目录 - + -h # 将文件大小输出为易读的格式 - + -s # 在行首显示(大小)? - + -i # inode +## 目录 +- [文件操作](#) + - [cd](#) + - [ls](#) + - [cat](#) + - [less](#) + - [od](#):查看二进制文件 + - [grep](#) + - [wc](#) + - [mkdir](#) + - [touch](#) + - [mv](#) + - [cp](#) + - [rm](#) + - [chown](#) + - [chmod](#) + - [file](#) + - [umark](#) + - [ln](#) + - [diff](#) + - [patch](#) + - [rsync](#):同步命令 + - [find](#) + - [locate](#):高效文件查找 + - [whereis](#) + - [which](#):查找命令 + - [whoami](#) + - [uname](#):系统内核版本等信息 +- [文件压缩](#) + - [gzip](#) + - [bzip2](#) + - [xz](#) + - [tar](#) + - [dd](#) +- [磁盘](#) + - [iostat](#iostat) : 监测磁盘活动 + - [mount](#) + - [umount](#) + - [df](#) + - [sync](#) + - [smartctl](#):查看smart参数 + - [parted](#) +- [用户](#) + - [sudo](#) + - [useradd](#) + - [groupadd](#) + - [passwd](#) + - [userdel](#) + - [usermod](#) + - [id](#) + - [newgrp](#):切换有效用户组 + - [last](# last) : 查看用户登陆记录 +- [进程](#) + - [ps](#) + - [uptime](#uptime) + - [vmstat](#vmstat) + - [top](#) + - [btop](#) + - [lsop](#):查看占用文件的进程 + - [kill](#) + - [bg](#) : 暂停的jobs 放到后台运行 + - [fg](#) : 后台拉回前台 + - [jobs](#) + - [ulimit](#) +- [网络](#) + - [ip](#) : many net tool + - [ss](#) : 端口 + - [ping](#) + - [curl](#) + - [wget](#) +- [系统](#) + - [systemctl](#) + - [dmidecode](#) + - [dpkg](#) + - [apt](#) + - [编解码工具](#) +- [其他](#) + - [](#) -# 文件目录操作管理 -> cat -> > - + -n # 显示行号 +## 文件操作 +### pwd -> less +### cd -> od -> > 查看非纯文本 - + -t # 类型 a, d, f, o, x +### ls + + -F # 在文件名后加提示符 '/' '*' '@' + + -a # 显示隐藏文件 + + -l # 列出文件信息 + + -d # 目录 + + -h # 将文件大小输出为易读的格式 + + -s # 在行首显示(大小)? + + -i # inode -> grep -> > 文件字符串匹配 - + -A # 后续n行 - + -B # 前n行 - + -n # 显示行号 - + -v # 反向选择 - + -E 'o1|o2|o3' # 多匹配 +### cat + + -n # 显示行号 -> wc -> > 统计 - + -l 行数 - + -m 字符 - + -w +### less -> mkdir +### od + + -t # 类型 a, d, f, o, x -> touch +### grep + + -A # 后续n行 + + -B # 前n行 + + -n # 显示行号 + + -v # 反向选择 + + -E 'o1|o2|o3' # 多匹配 + + -r "指定字符串" /目标文件夹路径 # 结合递归选项来查找文件夹下包含指定字符串的文件 -> mv -> > - + -i # 覆盖时警告 - + -b # 重合加~ +### wc + + -l 行数 + + -m 字符 + + -w word -> cp -> > copy - + -i # 覆盖时警告 - + -b # 重合加~ - + -u # 仅复制更新 - + -v # 详细显示 - + -r # 目录 +### mkdir -> rm -> > - + -i # 覆盖时警告 - + -r # 目录 - + -f # 强制 +### touch -> chown -> > 所有权 - + -R # 同时更改所有子目录 +### mv + + -i # 覆盖时警告 + + -b # 重合加~ -> chmod -> > 权限修改 - + -R # 同时更改所有子目录 +### cp + + -i # 覆盖时警告 + + -b # 重合加~ + + -u # 仅复制更新 + + -v # 详细显示 + + -r # 目录 + +### rm + + -i # 覆盖时警告 + + -r # 目录 + + -f # 强制 + + + + -R # 同时更改所有子目录 + +### chmod + + -R # 同时更改所有子目录 ```bash - SUID 4 - 执行二进制文件时,权限提升为文件所有者 - - SGID 2 - 在此权限下的目录进入后,有效用户组变为所有组 + SUID 4 + 执行二进制文件时,权限提升为文件所有者 + + SGID 2 + 在此权限下的目录进入后,有效用户组变为所有组 - SBIT 1 - 在此权限下的文件夹里创建文件,仅有root与属主有权操作 + SBIT 1 + 在此权限下的文件夹里创建文件,仅有root与属主有权操作 ``` -> file -> > 观察文件类型 - + -i 查看编码格式 - + -z 查看压缩格式 - + -b 查看文件的系统架构 - + -p 详细信息 +### file + + -i 查看编码格式 + + -z 查看压缩格式 + + -b 查看文件的系统架构 + + -p 详细信息 -> umark -> > 设置默认权限,默认是拿掉权限 +### umark -> ln -> > 链接(硬) - + -s # 符号链接(软) +### ln + + -s # 符号链接(软) -> diff -> > 比较文件 - + -b # 忽略空格 - + -i # 忽略大小写 - + -B # 忽略空白行 +### diff + + -r # 递归比较两个目录 + + -b # 忽略空格 + + -i # 忽略大小写 + + -B # 忽略空白行 + + -w # 忽略空白字符 + + -u # 使用"统一格式”显示,易于生成补丁文件 -> patch -> > 补丁制作 -> > example +### patch ```bash - diff -Naur > # -p[n] 拿掉路径中的/ - patch -p < # 制作 - patch -p-R < # 还原 + diff -Naur > < -R < rsync -> > 文件同步工具,它通过比较源和目标文件的大小、时间戳等信息,只同步发生变化的部分,提高了效率 -> > rsync [选项] 源文件/目录 目标文件/目录 - + -a(archive):归档模式,用于完整同步 - + -v(verbose):详细模式,显示同步过程中的详细信息。 - + -u(update):仅在目标文件不存在或源文件更新时才同步。 - + -z(compress):在传输过程中压缩文件数据。 - + --delete:删除目标目录中多余的文件,使目标目录与源目录保持一致 - + -e(rsh):指定远程连接时使用的工具(如 ssh)。 - + --exclude:指定排除的文件或目录模式。 - + --include:指定包含的文件或目录模式。 - + -P --progress:显示同步进度。 - + --bwlimit : 限速,用于单个大文件,避免占用过多带宽 - + --dry-run:模拟同步操作,不实际执行,用于测试同步命令的效果。 -> > example - 1. 本地同步 - rsync -avP /path/to/source/ /path/to/destination/ - 2. 从本地同步到远程 - rsync -avzP /path/to/source/ user@remote_host:/path/to/destination/ - 3. 同步时删除多余文件 - rsync -av --delete /path/to/source/ /path/to/destination/ - 4. 排除某些文件或目录 - rsync -av --exclude 'temp/*' --exclude '*.log' /path/to/source/ /path/to/destination/ - --exclude 'temp/*':排除 temp 目录下的所有文件。 - --exclude '*.log':排除所有 .log 文件。 - 5. 包含某些文件或目录 - rsync -av --include 'data/*' --exclude '*' /path/to/source/ /path/to/destination/ - --include 'data/*':仅包含 data 目录下的文件。 - --exclude '*':排除其他所有文件。 - 6. 模拟同步操作 - rsync -av --dry-run /path/to/source/ /path/to/destination/ +### rsync + + -a(archive):归档模式,用于完整同步 + + -v(verbose):详细模式,显示同步过程中的详细信息。 + + -u(update):仅在目标文件不存在或源文件更新时才同步。 + + -z(compress):在传输过程中压缩文件数据。 + + --delete:删除目标目录中多余的文件,使目标目录与源目录保持一致 + + -e(rsh):指定远程连接时使用的工具(如 ssh)。 + + --exclude:指定排除的文件或目录模式。 + + --include:指定包含的文件或目录模式。 + + -P --progress:显示同步进度。 + + --bwlimit : 限速,用于单个大文件,避免占用过多带宽 + + --dry-run:模拟同步操作,不实际执行,用于测试同步命令的效果。 + 1. 本地同步 + `rsync -avP /path/to/source/ /path/to/destination/` + 2. 从本地同步到远程 + `rsync -avzP /path/to/source/ user@remote_host:/path/to/destination/` + 3. 同步时删除多余文件 + `rsync -av --delete /path/to/source/ /path/to/destination/` + 4. 排除某些文件或目录 + `rsync -av --exclude 'temp/*' --exclude '*.log' /path/to/source/ /path/to/destination/` + --exclude 'temp/*':排除 temp 目录下的所有文件。 + --exclude '*.log':排除所有 .log 文件。 + 5. 包含某些文件或目录 + `rsync -av --include 'data/*' --exclude '*' /path/to/source/ /path/to/destination/` + --include 'data/*':仅包含 data 目录下的文件。 + --exclude '*':排除其他所有文件。 + 6. 模拟同步操作 + `rsync -av --dry-run /path/to/source/ /path/to/destination/` + +### find + + -name [filename] # 指定文件名 + + -print # 打印结果在终端 + + -type [type] # 指定类型 + + -atime <+-n### # n天前使用的文件 + + -mtime <+-n### # n天前修改的文件 + + find /usr/bin -name zip -print + +### locate + +### whereis + +### which + + -a # 全部列出 +### whoami + +### uname + + -a 全部信息 -# 文件查找 -> find -> > find [OPTION] [path] [expression] - + -name [filename] # 指定文件名 - + -print # 打印结果在终端 - + -type [type] # 指定类型 - + -atime <+-n> # n天前使用的文件 - + -mtime <+-n> # n天前修改的文件 -> > example - + find /usr/bin -name zip -print +## 文件压缩 +### gzip + + -d # 解压 + + -l # 查看压缩效果 -> locate +### bzip2 + + -d # 解压 + + -l # 查看压缩效果 -> whereis -> > 找命令文件 +### xz + + -z # 压缩 + + -d # 解压 + + -l # 查看压缩效果 + + -k # 保留压缩原文件 + + - # 压缩等级 + + -T # 使用多个线程 + + -v # 显示详细过程 -> which -> > 找PATH - + -a # 全部列出 -> whoami +### tar + + -c # 创建 + + -x # 解开 + + -v # 显示详细过程 + + -f # 指定文件名 + + -z # 调用gzip + + -j # 调用bzip2 + + -J # 调用xz + + tar -cvjf shell.tar.bz2 shell/ -> uname -> > 查看系统版本信息 - + -a 全部信息 +### dd + + if # input file/device + + of # output file/device + + bs # one black size + + count # count + + `oflag=sync` sync + +## 磁盘 +### mount + + -r # 只读 + + -o # 特殊设备 + + auto # 开机自动挂载 + + noauto # 不自动挂载 + + ro # read only + + rw # read and write + + user # 任意用户可挂载 -# 文件压缩 -> gzip -> > - + -d # 解压 - + -l # 查看压缩效果 +__/etc/fstab__ +[设备/UUID] [挂载点] [文件系统] [参数] 0 0 -> bzip2 -> > - + -d # 解压 - + -l # 查看压缩效果 +### umount -> xz -> > - + -z # 压缩 - + -d # 解压 - + -l # 查看压缩效果 - + -k # 保留压缩原文件 - + - # 压缩等级 - + -T # 使用多个线程 - + -v # 显示详细过程 +### df + + df -hT -> tar -> > 文件打包 - + -c # 创建 - + -x # 解开 - + -v # 显示详细过程 - + -f # 指定文件名 - + -z # 调用gzip - + -j # 调用bzip2 - + -J # 调用xz -> > example - + tar -cvjf shell.tar.bz2 shell/ +### sync -> dd -> > - + if # input file/device - + of # output file/device - + bs # one black size - + count # *bs - +### smartctl + -a 全部参数 + -H 是否正常 - - - -# 磁盘 -> mount -> > 挂载文件系统 - + -r # 只读 - + -o # 特殊设备 -> > /etc/fstab 配置文件 - + auto # 开机自动挂载 - + noauto # 不自动挂载 - + ro # read only - + rw # read and write - + user # 任意用户可挂载 -> > example - + [设备/UUID] [挂载点] [文件系统] [参数] 0 0 - -> umount -> > 卸载文件系统 - -> df -> > 观察磁盘使用情况 -> > example - + df -hT - -> sync - -> smartctl -> > 查看硬盘状态参数 - -a 全部参数 - -H 是否正常 - -> parted -> > 磁盘分区管理工具 -> > parted [OPTIONS] [DEVICES] [COMMAND] - + -i 列出所有设备的分区信息 - + -s 非交互模式 -> > 交互模式常用命令 - + print 显示当前设备的分区表 - + mklabel [gpt/msdos] 创建分区表 - + mkpart [part-type] [fs-type] [start] [end] 创建一个分区 -`例: mkpart primary ext4 1MiB 1000MiB` - + rm [number] 删除指定编号的分区 - + resizepart [number] [size] 重调大小 - + set [number] [mode] 设置分区标志 - + quit -> > 非交互 +### parted + + -i 列出所有设备的分区信息 + + -s 非交互模式 + + print 显示当前设备的分区表 + + mklabel [gpt/msdos] 创建分区表 + + mkpart [part-type] [fs-type] [start] [end] 创建一个分区 +`例: mkpart primary ext4 1MiB 1000MiB` + + rm [number] 删除指定编号的分区 + + resizepart [number] [size] 重调大小 + + set [number] [mode] 设置分区标志 + + quit `sudo parted -s /dev/sdb mklabel gpt mkpart primary ext4 0% 100%` `sudo parted -s /dev/sdb rm 2` -# 用户 -> useradd -> > - + -m # 同时建立主目录 - + -g # 指定用户组 - + -s # 指定shell +## 用户 +### sudo + + -u # 指定用户 -> groupadd +### useradd + + -m # 同时建立主目录 + + -g # 指定用户组 + + -s # 指定shell -> passwd +### groupadd -> userdel -> > - + -r # 删除主目录 +### passwd -> usermod -> > - + -d # 修改主目录 - + -e # 修改账号有效期 - + -s # 修改shell +### userdel + + -r # 删除主目录 -> id -> > 查看用户信息 +### usermod + + -d # 修改主目录 + + -e # 修改账号有效期 + + -s # 修改shell -> /etc/passwd -> > example - + 登录名:口令:UID:GID:x信息:主目录:shell +### id -> /etc/group -> > example - + 组名:组口令(一般无):GID:user1,user2,user3 +`/etc/passwd` +登录名:口令:UID:GID:x信息:主目录:shell -### 用户所有组是passwd和groups的并集 +`/etc/group` + + 组名:组口令(一般无):GID:user1,user2,user3 -> newgrp -> > 切换有效用户组 +__用户所有组是passwd和groups的并集__ + +### newgrp + +### last +- **-n <数字>** 表示查看最近n条 +- **-i** 显示IP而不是主机名 + +## 进程 +### ps + + aux + +### uptime +`load average` 为过去 1, 5, 15 分钟内等待资源的进程数量 +若持续高于cpu核心数,表明进程可能在争抢资源 + +### vmstat +检测系统状态 ++ **`r`** cpu队列 ++ **`b`** io等待 ++ **`si/so`** swap队列 + +- `-f` 自启动fork次数 +- `-d` 磁盘统计信息 +- `-s` 统计 + +### top + +### btop + +### lsop + +### kill + + -l # 列出所有信号 + +### bg + +### fg + +### jobs + +### nohup 命令挂机(退出登陆后依然执行) +nohup [command] & +`screen` 主要用于用户开启多个独立的会话(称为"窗口")在这些会话之间可以自由切换而不会中断已经运行的程序 +1. **启动一个新的 screen 会话**: + screen +2. **列出当前的 screen 会话**: + screen -ls +3. **重新连接到一个已存在的会话**: + screen -r [会话ID或名称] +4. **分离当前会话**: + 在 screen 会话中按 `Ctrl-a` 然后按 `d`。 +9. **退出 screen 会话**: + - 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。 + - 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。 +10. **锁定当前会话**: + 在 screen 会话中按 `Ctrl-a` 然后按 `x`。 + +### ulimit + 查看和修改进程运行资源限制 + -H/S # 设置/显示 软/硬 限制 + -a # 显示所有 + -t # cpu time + -f # file size + -s # stack size + -c # core file size + -m # memory size + -l # lock memory size + -p # user processes + -n # open file + + #ulimit -Ht 3600 +## 网络 +### ip + + ip neigh [OPTIONS] [COMMAND] + + ip neigh add [IP] lladdr [MAC] dev [eth0] 添加表项 + + ip neigh del [IP] dev [eth0] 删除表项 + + ip neigh flush all 清空 + _________________________________ + REACHABLE:表示邻居设备可达。 + STALE:表示邻居设备的条目已过期,但之前是可达的。 + DELAY:表示正在等待确认邻居设备是否可达。 + PROBE:表示正在积极探测邻居设备是否可达 + _________________________________ -# 进程 -> ps -> > - + aux +### ss + + -t # tcp + + -u # udp + + -n # 以端口号显示 + + -l # 列出正在监听的服务 + + -p # + pid + +` -r # 路由表 + + ss -tlunp -> top +### ping -> lsop -> > 查看占用文件的进程 +### curl -> kill -> > 发送信号 - + -l # 列出所有信号 +### wget -> nice renice -> > 调整谦让度 +## 系统 +### systemctl + + start + + stop + + restart + + reload + + enable + + disable + + status + + mask # 强制注销 + + unmask + + list-units + + get-default # 获取目前target + + set-default # 设置默认target + + isolate # 切换target + + poweroff + + reboot + + suspend # 挂起 + + hibernate # 休眠 + + rescue # 修复 -> bg -> > 让后台中的进程继续运行 +### dmidecode + + -q # 简洁 + + -t # 指定查看类型 -> fg -> > 把后台进程拉回前台 +### dpkg + + -i # 安装 + + -l # 查看版本 + + -r # 卸载 -> jobs -> > 列出后台进程 +### apt + + updata # 更新软件包缓存 + + upgrade # 更新已有软件包的最新版本 + + install # 下载并安装 + + remove # 卸载 + + source # 下载源码 + + search # 搜索 + + depends # 列出依赖 + + /etc/apt/sources.list +### 编解码工具 + + md5sum md5编码 + + sha1sum sha1 + + cksum crc + + base64 + + basenc 各种base64变种 + + `--base64url` + + `--base32` + + `--base16` + + `--base2msbf` 二进制 + + `echo -n 你好|iconv -t ucs-2be|xxd-ps|sed 's/..../\\u&/g` unicode码 - -# 网络 -> ip -> > 查看网络的各种信息 -> > address 地址等连接信息 -> > neigh arp相关 - + ip neigh [OPTIONS] [COMMAND] - + ip neigh add [IP] lladdr [MAC] dev [eth0] 添加表项 - + ip neigh del [IP] dev [eth0] 删除表项 - + ip neigh flush all 清空 - _________________________________ - REACHABLE:表示邻居设备可达。 - STALE:表示邻居设备的条目已过期,但之前是可达的。 - DELAY:表示正在等待确认邻居设备是否可达。 - PROBE:表示正在积极探测邻居设备是否可达 - _________________________________ - -> ss -> > 查看端口开放情况 - + -t # tcp - + -u # udp - + -n # 以端口号显示 - + -l # 列出正在监听的服务 - + -p # + pid - +` -r # 路由表 -> > example - + ss -tlunp - -> ping - - -# 系统 -> systemctl -> > systemctl [command] [unit] - + start - + stop - + restart - + reload - + enable - + disable - + status - + mask # 强制注销 - + unmask -> > - + list-units -> > - + get-default # 获取目前target - + set-default # 设置默认target - + isolate # 切换target -> > > - + poweroff - + reboot - + suspend # 挂起 - + hibernate # 休眠 - + rescue # 修复 - - -# 硬件 -> dmidecode -> > 获取硬件信息 - + -q # 简洁 - + -t # 指定查看类型 - - - -# 软件包管理 -> dpkg -> > .deb - + -i # 安装 - + -l # 查看版本 - + -r # 卸载 - -> apt -> > apt-get -> > > - + updata # 更新软件包缓存 - + upgrade # 更新已有软件包的最新版本 - + install # 下载并安装 - + remove # 卸载 - + source # 下载源码 -> > apt-cache -> > > - + search # 搜索 - + depends # 列出依赖 -> > 配置源 - + /etc/apt/sources.list - - -# 其他命令 - # nohup 命令挂机(退出登陆后依然执行) - nohup [command] & - `screen` 主要用于用户开启多个独立的会话(称为"窗口")在这些会话之间可以自由切换而不会中断已经运行的程序 - ### 基本使用方法: - 1. **启动一个新的 screen 会话**: - screen - 2. **列出当前的 screen 会话**: - screen -ls - 3. **重新连接到一个已存在的会话**: - screen -r [会话ID或名称] - 4. **分离当前会话**: - 在 screen 会话中按 `Ctrl-a` 然后按 `d`。 - 9. **退出 screen 会话**: - - 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。 - - 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。 - 10. **锁定当前会话**: - 在 screen 会话中按 `Ctrl-a` 然后按 `x`。 - - - - # ulimit - 查看和修改进程运行资源限制 - -H/S # 设置/显示 软/硬 限制 - -a # 显示所有 - -t # cpu time - -f # file size - -s # stack size - -c # core file size - -m # memory size - -l # lock memory size - -p # user processes - -n # open file - - #ulimit -Ht 3600 +## 其他 +======= +# linux基础命令 + +## 目录 +- [linux基础命令](#linux基础命令) + - [目录](#目录) + - [文件操作](#文件操作) + - [pwd](#pwd) + - [cd](#cd) + - [ls](#ls) + - [cat](#cat) + - [less](#less) + - [od](#od) + - [grep](#grep) + - [wc](#wc) + - [mkdir](#mkdir) + - [touch](#touch) + - [mv](#mv) + - [cp](#cp) + - [rm](#rm) + - [chmod](#chmod) + - [file](#file) + - [umark](#umark) + - [ln](#ln) + - [diff](#diff) + - [patch](#patch) + - [rsync](#rsync) + - [find](#find) + - [locate](#locate) + - [whereis](#whereis) + - [which](#which) + - [whoami](#whoami) + - [uname](#uname) + - [文件压缩](#文件压缩) + - [gzip](#gzip) + - [bzip2](#bzip2) + - [xz](#xz) + - [tar](#tar) + - [dd](#dd) + - [磁盘](#磁盘) + - [mount](#mount) + - [umount](#umount) + - [df](#df) + - [sync](#sync) + - [smartctl](#smartctl) + - [parted](#parted) + - [用户](#用户) + - [sudo](#sudo) + - [useradd](#useradd) + - [groupadd](#groupadd) + - [passwd](#passwd) + - [userdel](#userdel) + - [usermod](#usermod) + - [id](#id) + - [newgrp](#newgrp) + - [进程](#进程) + - [ps](#ps) + - [top](#top) + - [btop](#btop) + - [lsop](#lsop) + - [kill](#kill) + - [bg](#bg) + - [fg](#fg) + - [jobs](#jobs) + - [nohup](#nohup) + - [ulimit](#ulimit) + - [网络](#网络) + - [ip](#ip) + - [ss](#ss) + - [ping](#ping) + - [curl](#curl) + - [wget](#wget) + - [系统](#系统) + - [systemctl](#systemctl) + - [dmidecode](#dmidecode) + - [dpkg](#dpkg) + - [apt](#apt) + - [编解码工具](#编解码工具) + - [其他](#其他) + + +## 文件操作 +### pwd + +### cd + +### ls + + -F # 在文件名后加提示符 '/' '*' '@' + + -a # 显示隐藏文件 + + -l # 列出文件信息 + + -d # 目录 + + -h # 将文件大小输出为易读的格式 + + -s # 在行首显示(大小)? + + -i # inode + +### cat + + -n # 显示行号 + +### less + +### od + + -t # 类型 a, d, f, o, x + +### grep + + -A # 后续n行 + + -B # 前n行 + + -n # 显示行号 + + -v # 反向选择 + + -E 'o1|o2|o3' # 多匹配 + + -r "指定字符串" /目标文件夹路径 # 结合递归选项来查找文件夹下包含指定字符串的文件 + +### wc + + -l 行数 + + -m 字符 + + -w word + +### mkdir + +### touch + +### mv + + -i # 覆盖时警告 + + -b # 重合加~ + +### cp + + -i # 覆盖时警告 + + -b # 重合加~ + + -u # 仅复制更新 + + -v # 详细显示 + + -r # 目录 + +### rm + + -i # 覆盖时警告 + + -r # 目录 + + -f # 强制 + + + + -R # 同时更改所有子目录 + +### chmod + + -R # 同时更改所有子目录 +```bash + SUID 4 + 执行二进制文件时,权限提升为文件所有者 + + SGID 2 + 在此权限下的目录进入后,有效用户组变为所有组 + + SBIT 1 + 在此权限下的文件夹里创建文件,仅有root与属主有权操作 +``` + +### file + + -i 查看编码格式 + + -z 查看压缩格式 + + -b 查看文件的系统架构 + + -p 详细信息 + +### umark + +### ln + + -s # 符号链接(软) + +### diff + + -r # 递归比较两个目录 + + -b # 忽略空格 + + -i # 忽略大小写 + + -B # 忽略空白行 + + -w # 忽略空白字符 + + -u # 使用"统一格式”显示,易于生成补丁文件 + +### patch +```bash + diff -Naur > < -R < # 压缩等级 + + -T # 使用多个线程 + + -v # 显示详细过程 + +### tar + + -c # 创建 + + -x # 解开 + + -v # 显示详细过程 + + -f # 指定文件名 + + -z # 调用gzip + + -j # 调用bzip2 + + -J # 调用xz + + tar -cvjf shell.tar.bz2 shell/ + +### dd + + if # input file/device + + of # output file/device + + bs # one black size + + count # count + + `oflag=sync` sync + + +## 磁盘 +### mount + + -r # 只读 + + -o # 特殊设备 + + auto # 开机自动挂载 + + noauto # 不自动挂载 + + ro # read only + + rw # read and write + + user # 任意用户可挂载 + +__/etc/fstab__ +[设备/UUID] [挂载点] [文件系统] [参数] 0 0 + +### umount + +### df + + df -hT + +### sync + +### smartctl + -a 全部参数 + -H 是否正常 + +### parted + + -i 列出所有设备的分区信息 + + -s 非交互模式 + + print 显示当前设备的分区表 + + mklabel [gpt/msdos] 创建分区表 + + mkpart [part-type] [fs-type] [start] [end] 创建一个分区 +`例: mkpart primary ext4 1MiB 1000MiB` + + rm [number] 删除指定编号的分区 + + resizepart [number] [size] 重调大小 + + set [number] [mode] 设置分区标志 + + quit +`sudo parted -s /dev/sdb mklabel gpt mkpart primary ext4 0% 100%` +`sudo parted -s /dev/sdb rm 2` + + +## 用户 +### sudo + + -u # 指定用户 + +### useradd + + -m # 同时建立主目录 + + -g # 指定用户组 + + -s # 指定shell + +### groupadd + +### passwd + +### userdel + + -r # 删除主目录 + +### usermod + + -d # 修改主目录 + + -e # 修改账号有效期 + + -s # 修改shell + +### id + +`/etc/passwd` +登录名:口令:UID:GID:x信息:主目录:shell + +`/etc/group` + + 组名:组口令(一般无):GID:user1,user2,user3 + +__用户所有组是passwd和groups的并集__ + +### newgrp + + +## 进程 +### ps + + aux + +### top + +### btop + +### lsop + +### kill + + -l # 列出所有信号 + +### bg + +### fg + +### jobs + +### nohup +nohup [command] & +`screen` 主要用于用户开启多个独立的会话(称为"窗口")在这些会话之间可以自由切换而不会中断已经运行的程序 +1. **启动一个新的 screen 会话**: + screen +2. **列出当前的 screen 会话**: + screen -ls +3. **重新连接到一个已存在的会话**: + screen -r [会话ID或名称] +4. **分离当前会话**: + 在 screen 会话中按 `Ctrl-a` 然后按 `d`。 +9. **退出 screen 会话**: + - 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。 + - 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。 +10. **锁定当前会话**: + 在 screen 会话中按 `Ctrl-a` 然后按 `x`。 + +### ulimit + 查看和修改进程运行资源限制 + -H/S # 设置/显示 软/硬 限制 + -a # 显示所有 + -t # cpu time + -f # file size + -s # stack size + -c # core file size + -m # memory size + -l # lock memory size + -p # user processes + -n # open file + + #ulimit -Ht 3600 + + +## 网络 +### ip + + ip neigh [OPTIONS] [COMMAND] + + ip neigh add [IP] lladdr [MAC] dev [eth0] 添加表项 + + ip neigh del [IP] dev [eth0] 删除表项 + + ip neigh flush all 清空 + _________________________________ + REACHABLE:表示邻居设备可达。 + STALE:表示邻居设备的条目已过期,但之前是可达的。 + DELAY:表示正在等待确认邻居设备是否可达。 + PROBE:表示正在积极探测邻居设备是否可达 + _________________________________ + +### ss + + -t # tcp + + -u # udp + + -n # 以端口号显示 + + -l # 列出正在监听的服务 + + -p # + pid + +` -r # 路由表 + + ss -tlunp + +### ping + +### curl +用于从服务器传输数据或向服务器传输数据,支持多种协议,包括 HTTP、HTTPS、FTP、FTPS、SMTP、POP3 等 + +1. 基本用法 ++ `curl http://example.com` 访问网页或API ++ `curl -o output.html http://example.com` 保存响应到文件 ++ `curl -v http://example.com` 显示详细信息 ++ `curl -s http://example.com` 静默模式 ++ `curl -X POST -d "param1=value1¶m2=value2" http://example.com/api` 发送POST请求 ++ `curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://example.com/api` 发送JSON数据 ++ `curl -X POST -F "file=@/path/to/file" http://example.com/upload` 上传文件 + +### wget +`wget [参数] [URL]`一个下载文件的工具,可以使用HTTP代理,所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行。这意味这你可以登录系统,启动一个wget下载任务,然后退出系统,wget将在后台执行直到任务完成 + +1.特点 ++ 支持断点下传功能 ++ 同时支持FTP和HTTP下载方式 ++ 支持代理服务器 ++ 设置方便简单 ++ 程序小,完全免费 + +2. 参数 +> `-V` +> `-b` 启动后转后台 +> `-O [FILE]` 写入文件 +> `-d` debug信息 +> `-c` continue继续下 +> `-T` 设定响应超时的秒数 +> `-r` 递归下载 + +__example__ ++ `wget http://www.minjieren.com/wordpress-3.1-zh_CN.zip` 下载单个文件 ++ `wget -O wordpress.zip http://www.minjieren.com/download.aspx?id=1080` 以不同的文件名保存 ++ `wget -c http://www.minjieren.com/wordpress-3.1-zh_CN.zip` 使用wget -c断点续传 ++ `wget --mirror -p --convert-links -P ./LOCAL URL` 镜像整个网站到本地 ++ `wget -r -A.pdf url` 使用wget -r -A下载指定格式文件 + + +## 系统 +### systemctl + + start + + stop + + restart + + reload + + enable + + disable + + status + + mask # 强制注销 + + unmask + + list-units + + get-default # 获取目前target + + set-default # 设置默认target + + isolate # 切换target + + poweroff + + reboot + + suspend # 挂起 + + hibernate # 休眠 + + rescue # 修复 + +### dmidecode + + -q # 简洁 + + -t # 指定查看类型 + +### dpkg + + -i # 安装 + + -l # 查看版本 + + -r # 卸载 + +### apt + + updata # 更新软件包缓存 + + upgrade # 更新已有软件包的最新版本 + + install # 下载并安装 + + remove # 卸载 + + source # 下载源码 + + search # 搜索 + + depends # 列出依赖 + + /etc/apt/sources.list + +### 编解码工具 + + md5sum md5编码 + + sha1sum sha1 + + cksum crc + + base64 + + basenc 各种base64变种 + + `--base64url` + + `--base32` + + `--base16` + + `--base2msbf` 二进制 + + `echo -n 你好|iconv -t ucs-2be|xxd-ps|sed 's/..../\\u&/g` unicode码 + +## 其他 +>>>>>>> Stashed changes diff --git a/os/linux/config/.bashrc b/os/linux/config/.bashrc deleted file mode 100644 index 2a03a10..0000000 --- a/os/linux/config/.bashrc +++ /dev/null @@ -1,117 +0,0 @@ -# ~/.bashrc: executed by bash(1) for non-login shells. -# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) -# for examples - -# If not running interactively, don't do anything -case $- in - *i*) ;; - *) return;; -esac - -# don't put duplicate lines or lines starting with space in the history. -# See bash(1) for more options -HISTCONTROL=ignoreboth - -# append to the history file, don't overwrite it -shopt -s histappend - -# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) -HISTSIZE=500 -HISTFILESIZE=500 - -# check the window size after each command and, if necessary, -# update the values of LINES and COLUMNS. -shopt -s checkwinsize - -# If set, the pattern "**" used in a pathname expansion context will -# match all files and zero or more directories and subdirectories. -#shopt -s globstar - -# make less more friendly for non-text input files, see lesspipe(1) -[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" - -# set variable identifying the chroot you work in (used in the prompt below) -if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then - debian_chroot=$(cat /etc/debian_chroot) -fi - -# set a fancy prompt (non-color, unless we know we "want" color) -case "$TERM" in - xterm-color|*-256color) color_prompt=yes;; -esac - -# uncomment for a colored prompt, if the terminal has the capability; turned -# off by default to not distract the user: the focus in a terminal window -# should be on the output of commands, not on the prompt -#force_color_prompt=yes - -if [ -n "$force_color_prompt" ]; then - if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then - # We have color support; assume it's compliant with Ecma-48 - # (ISO/IEC-6429). (Lack of such support is extremely rare, and such - # a case would tend to support setf rather than setaf.) - color_prompt=yes - else - color_prompt= - fi -fi - -if [ "$color_prompt" = yes ]; then - PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h@\t\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' -else - PS1='${debian_chroot:+($debian_chroot)}\u@\h@\t:\w\$ ' -fi -unset color_prompt force_color_prompt - -# If this is an xterm set the title to user@host:dir -case "$TERM" in -xterm*|rxvt*) - PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h@\t: \w\a\]$PS1" - ;; -*) - ;; -esac - -# enable color support of ls and also add handy aliases -if [ -x /usr/bin/dircolors ]; then - test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" - alias ls='ls --color=auto' - #alias dir='dir --color=auto' - #alias vdir='vdir --color=auto' - - alias grep='grep --color=auto' - alias fgrep='fgrep --color=auto' - alias egrep='egrep --color=auto' -fi - -# colored GCC warnings and errors -#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' - -# some more ls aliases -alias ll='ls -ahlF' -alias l='ls -lF' -# Add an "alert" alias for long running commands. Use like so: -# sleep 10; alert -alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' - -# Alias definitions. -# You may want to put all your additions into a separate file like -# ~/.bash_aliases, instead of adding them here directly. -# See /usr/share/doc/bash-doc/examples in the bash-doc package. - -if [ -f ~/.bash_aliases ]; then - . ~/.bash_aliases -fi - -# enable programmable completion features (you don't need to enable -# this, if it's already enabled in /etc/bash.bashrc and /etc/profile -# sources /etc/bash.bashrc). -if ! shopt -oq posix; then - if [ -f /usr/share/bash-completion/bash_completion ]; then - . /usr/share/bash-completion/bash_completion - elif [ -f /etc/bash_completion ]; then - . /etc/bash_completion - fi -fi -alias powerele="upower -i /org/freedesktop/UPower/devices/battery_BAT0" -export LANG=en_US.UTF-8 diff --git a/os/linux/config/.profile b/os/linux/config/.profile deleted file mode 100644 index d89ea5a..0000000 --- a/os/linux/config/.profile +++ /dev/null @@ -1,27 +0,0 @@ -# ~/.profile: executed by the command interpreter for login shells. -# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login -# exists. -# see /usr/share/doc/bash/examples/startup-files for examples. -# the files are located in the bash-doc package. - -# the default umask is set in /etc/profile; for setting the umask -# for ssh logins, install and configure the libpam-umask package. -#umask 022 - -# if running bash -if [ -n "$BASH_VERSION" ]; then - # include .bashrc if it exists - if [ -f "$HOME/.bashrc" ]; then - . "$HOME/.bashrc" - fi -fi - -# set PATH so it includes user's private bin if it exists -if [ -d "$HOME/bin" ] ; then - PATH="$HOME/bin:$PATH" -fi - -# set PATH so it includes user's private bin if it exists -if [ -d "$HOME/.local/bin" ] ; then - PATH="$HOME/.local/bin:$PATH" -fi diff --git a/program/c_cpp/STL/algorithms.md b/program/c_cpp/STL/algorithms.md new file mode 100644 index 0000000..996d4f4 --- /dev/null +++ b/program/c_cpp/STL/algorithms.md @@ -0,0 +1,252 @@ +# STL算法 + +## 目录 +- [非修改性算法](#) + - [find](#) + - [conut](#) + - [二分查找](#binary-search) +- [修改性算法](#) + - [copy](#) + - [replace](#):将指定范围内等于给定值的元素替换为新值 + - [reverse](#):翻转序列 +- [排序算法](#) + - [sort](#) + - [稳定排序](#stable-sort) + - [第n大数](#nth-element) +- [数值算法](#) + - [accumulate](#):计算指定范围内元素的累积和 + - [计算两个序列的内积](#inner-product) +- [集合算法](#) + - [两个有序序列的差集](#set-difference) + - [将两个有序序列合并为一个有序序列](#merge) +- [其他算法](#) + - [去除相邻重复元素](#unique) + - [随机打乱序列](#shuffle) + +## 非修改性算法 +### find +``` +template +InputIterator find(InputIterator first, InputIterator last, const T& value); +``` ++ InputIterator:输入迭代器类型,表示要搜索的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含)。 ++ value:要查找的目标值。 ++ 返回值:如果找到目标值,返回指向该元素的迭代器;如果没有找到,则返回 last + +__注意事项__ +1. 返回值的判断 +如果未找到目标值,返回值是 last,通常需要通过比较返回值是否等于 last 来判断是否找到目标 + +2. 自定义对象的比较 +如果要在自定义对象中使用 `std::find`,需要重载 `operator==`,以便算法能够比较对象是否相等 + +3. 性能 +是线性查找算法,时间复杂度为 O(n),其中 n 是范围内的元素数量 + +4. 范围的正确性 +确保 first 和 last 指向的范围是有效的,并且 first 不大于 last + +### conut +``` +template +typename iterator_traits::difference_type count( + InputIterator first, + InputIterator last, + const T& value +); +``` ++ InputIterator:输入迭代器类型,表示要搜索的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含)。 ++ value:要统计的目标值。 ++ 返回值:返回等于目标值的元素个数,类型为 `iterator_traits::difference_type` + +__注意事项__ +1. 返回值的判断 +返回值类型是 `iterator_traits::difference_type`,通常是与容器相关的整数类型 `int` `size_t` + +2. 自定义对象的比较 +需要重载 `operator==`,以便算法能够比较对象是否相等 + +3. 性能 +是线性查找算法,时间复杂度为 O(n),其中 n 是范围内的元素数量 + +4. 范围的正确性 +确保 first 和 last 指向的范围是有效的,并且 first 不大于 last + +### binary-search +用于在*有序序列*中查找是否存在某个值,基于二分查找的思想,时间复杂度为 O(log n) + +只返回布尔值,表示是否找到目标值,如果需要找到目标值的位置,可以结合 `std::lower_bound` 或 `std::upper_bound` 使用 +``` +template +bool binary_search(ForwardIterator first, ForwardIterator last, const T& value); +``` ++ ForwardIterator:正向迭代器类型,表示要搜索的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含)。 ++ value:要查找的目标值。 ++ 返回值:如果找到目标值,返回 true;否则返回 false。 + +__还支持自定义比较函数__ +``` +template +bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); +``` ++ Compare:比较函数,用于定义元素之间的大小关系。如果未提供,会使用默认的 < 比较运算符 + +## 修改性算法 +### copy +用于将一个范围内的元素复制到另一个范围中,是一个线性算法,时间复杂度为 O(n) + +``` +template +OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); +``` ++ InputIterator:输入迭代器类型,表示要复制的源范围的起始和结束位置。 ++ first:指向源范围的起始位置的迭代器。 ++ last:指向源范围的结束位置的迭代器(不包含)。 ++ OutputIterator:输出迭代器类型,表示目标范围的起始位置。 ++ result:指向目标范围的起始位置的迭代器。 ++ 返回值:返回指向目标范围结束位置的迭代器(即 result + (last - first)) + +### replace +用于在指定范围内将所有等于某个特定值的元素替换为另一个值 + +``` +template +void replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); +``` ++ ForwardIterator:正向迭代器类型,表示要操作的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含)。 ++ `old_value`:要被替换的旧值。 ++ `new_value`:用于替换的新值。 + +如果需要更复杂的替换逻辑(例如基于条件的替换),可以结合 `std::replace_if` 使用,后者允许传入一个谓词函数来定义替换条件。 + +### reverse +反转指定范围内的元素顺序,要求输入范围的迭代器是双向迭代器,即支持双向遍历 + +``` +template +void reverse(BidirectionalIterator first, BidirectionalIterator last); +``` ++ BidirectionalIterator:双向迭代器类型,表示要反转的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含) + +## 排序算法 +### sort +指定范围内的元素进行排序,要求输入范围的迭代器是随机访问迭代器,是不稳定的排序算法,平均时间复杂度为 O(n log n) + +``` +template +void sort(RandomAccessIterator first, RandomAccessIterator last); +``` ++ RandomAccessIterator:随机访问迭代器类型,表示要排序的范围的起始和结束位置 ++ first:指向范围的起始位置的迭代器 ++ last:指向范围的结束位置的迭代器(不包含) + +此外,std::sort 还支持自定义比较函数 +``` +template +void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); +``` + +### stable-sort +是一个稳定排序算法,对指定范围内的元素进行排序,同时保证相等元素的相对顺序不变 + +``` +template +void stable_sort(RandomAccessIterator first, RandomAccessIterator last); + +template +void stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); +``` ++ first 和 last:随机访问迭代器,分别指向要排序范围的起始位置和结束位置(不包含) ++ Compare:可选的比较函数,用于定义排序规则。如果未提供,默认使用 < 运算符 + +如果有足够的额外内存,`std::stable_sort` 的时间复杂度为 O(n log n),内存不足,时间复杂度可能退化为 O(n log² n) + + +### nth-element +用于部分排序序列,使得第 k 小的元素被放置到正确的位置,同时保证所有在它之前的元素都不大于它,所有在它之后的元素都不小于它,平均时间复杂度:O(n),最坏时间复杂度:O(n²) + +``` +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last); + +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last, Compare comp); +``` ++ first:指向序列起始位置的随机访问迭代器。 ++ nth:指向序列中第 k 个位置的迭代器(0-based index)。 ++ last:指向序列结束位置的迭代器。 ++ comp(可选):自定义比较函数,默认使用 std::less + +> 不会完全排序整个序列,它只保证第 k 小的元素在正确的位置上 +> 该算法的性能优于完全排序 + +## 数值算法 +### accumulate +用于计算指定范围内元素的累积和,时间复杂度为 O(n) + +`std::accumulate` 从 first 开始,逐个处理范围内的元素,将每个元素与累积结果进行操作(默认为加法),并将最终结果返回 + +``` +template +T accumulate(InputIterator first, InputIterator last, T init); + +template +T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation op); +``` ++ InputIterator:输入迭代器类型,表示要操作的范围的起始和结束位置。 ++ first:指向范围的起始位置的迭代器。 ++ last:指向范围的结束位置的迭代器(不包含)。 ++ T:累积结果的类型。 ++ init:初始值,用于开始累积操作。 ++ BinaryOperation(可选):二元操作函数,用于定义累积操作。如果未提供,默认使用加法操作 `std::plus` [预定义函数符](./containers.md#) + +### inner-product + +## 集合算法 +### set-difference +### merge + +## 其他算法 +### unique +用于移除序列中相邻的重复元素,并返回一个指向“新序列”结束位置的迭代器。它不会改变原序列的长度,而是将重复元素移动到序列末尾,并返回一个指向“有效部分”结束位置的迭代器。因此,通常需要结合容器的 erase 方法来真正移除重复元素,O(n) + +``` +template +ForwardIterator unique(ForwardIterator first, ForwardIterator last); + +template +ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); +``` ++ ForwardIterator:正向迭代器类型,表示要操作的序列的起始和结束位置。 ++ first:指向序列起始位置的迭代器。 ++ last:指向序列结束位置的迭代器(不包含)。 ++ BinaryPredicate(可选):二元谓词函数,用于定义两个元素是否相等。如果未提供,默认使用 operator== + +### shuffle +随机打乱指定范围内元素的顺序 + +``` +template +void shuffle(RandomAccessIterator first, RandomAccessIterator last, URNG&& g); +``` ++ first 和 last:随机访问迭代器,分别指向要打乱范围的起始位置和结束位置(不包含) ++ URNG:均匀随机数生成器,例如 `std::mt19937` 或 `std::default_random_enginei` + +``` +// 使用随机数生成器 + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::mt19937 rng(seed); + + // 打乱顺序 + std::shuffle(vec.begin(), vec.end(), rng); +``` diff --git a/program/c_cpp/STL/containers.md b/program/c_cpp/STL/containers.md new file mode 100644 index 0000000..9b6571a --- /dev/null +++ b/program/c_cpp/STL/containers.md @@ -0,0 +1,240 @@ +# STL 容器 + +## 目录 + +- [概念](#) +- [通性](#) +- [序列容器](#) + - [vector](#) + - [deque](#) + - [list](#) +- [关联容器](#) + - [set](#) + - [multiset](#) + - [map](#) + - [multimap](#) +- [无序容器](#) + - [`unordered_set`](#unordered_set) + - [`unordered_multiset`](#unordered_multiset) + - [`unordered_map`](#unordered_map) + - [`unordered_multimap`](#unordered_multimap) +- [预定义函数符](#) + +## 概念 + +**函数符**概念 + +其实就是重载了()的伪函数 + +- 生成器:无参数 +- 一元函数:一个参数 +- 二元函数:两个参数 +- 谓词:返回bool的一元函数 +- 二元谓词:返回bool的二元函数 + +## 通性 + ++ `begin()` 和 `end()` 用于获取容器的迭代器,指向容器的第一个元素和最后一个元素的“后继” ++ `rbegin()` 和 `rend()` 用于获取容器的反向迭代器,指向容器的最后一个元素和第一个元素的“前驱”位置 ++ `size()` 返回容器中元素的数量 ++ `empty()` 如果容器为空,返回true;否则返回false ++ `max_size()` 返回容器可能存储的最大元素数量 ++ `clear()` 清空容器中的所有元素,但不释放内存 ++ `swap()` 交换两个容器的内容 ++ `data()` **仅适用于序列容器** 返回指向容器底层存储的指针 + + 提供对容器底层数据的直接访问 + + 适用于需要与C语言风格的API交互的场景 ++ `front()` 和 `back()` **仅适用于序列容器** 返回容器的第一个元素和最后一个元素的引用 ++ `operator[]` 和 `at()` **仅适用于序列容器** 访问容器中的特定元素 + + at() 进行边界检查,如果索引超出范围,会抛出`std::out_of_range`异常 + +## 序列容器 + +存储元素的顺序与插入顺序一致 + +### vector + +1. 定义和初始化 + +`std::vector vec1; // 定义一个空的 vector` +`std::vector vec2 = {1, 2, 3, 4, 5}; // 使用初始化列表初始化` +`std::vector vec3(10, 0); // 10个元素,初始值为0` +`std::vector vec4(vec2); // 拷贝构造` +`std::vector vec5(std::move(vec2)); // 移动构造` + +2. 元素访问 + +支持序列容器的大部分访问方法 + +3. 修改容器 + +`push_back()` 在容器末尾添加一个元素 +`pop_back()` 删除容器末尾的元素 +`insert()` 在指定位置插入一个或多个元素 +`erase()` 删除指定位置的元素 + +4. 容量和大小 + +`capacity()` 返回容器当前分配的内存容量(以元素数量计) +`reserve()` 预分配内存,减少动态扩展的次数 +`shrink_to_fit()` 收缩内存,释放多余空间 + +__使用技巧__ + +1. 预分配内存 + +如果知道容器将存储大量元素,可以使用 reserve() 预分配内存,以减少动态扩展的次数 + +2. 使用 `std::move()` + +`vec2.push_back(std::move(vec1[0])); // 将vec1的第一个元素移动到vec2` + +3. 使用vector的bool值特性 + +`std::vector` 是一个特化版本,它使用位存储来优化空间占用,但可能会牺牲某些操作的性能 + +4. 使用 `std::vector` 的指针特性 + +如果需要存储动态分配的对象,可以使用 `std::vector>` 或 `std::vector>` + + +__vector 的 capacity 和 size 属性区别__ + +size 是当前 vector 容器真实占用的大小,也就是容器当前拥有多少个容器。 + +capacity 是指在发生 realloc 前能允许的最大元素数,即预分配的内存空间。 + +使用 resize() 容器内的对象内存空间是真正存在的。 + +使用 reserve() 仅仅只是修改了 capacity 的值,容器内的对象并没有真实的内存空间(空间是"野"的)。 + +### deque +1. 插入和删除 + + `push_back()` 和 `pop_back()`:尾部操作 + + `push_front()` 和 `pop_front()`:头部操作 + + `insert()` 和 `erase()`:在任意位置插入或删除 + +2. 大小操作 + + `resize()`:调整容器大小 + +__使用技巧__ +> 高效头部操作:`deque` 是处理头部和尾部频繁插入删除的理想选择 +> 随机访问优化:虽然 `deque` 的内存不连续,但通过下标访问效率较高 +> 排序:由于支持随机访问,可以使用 `std::sort` 对 `deque` 进行排序 +> 迭代器失效:在添加或删除元素后,迭代器可能失效,需要重新获取 + +__注意事项__ +> 内存不连续:`deque` 的元素可能分散在多个内存块中,但通过下标或迭代器访问不会受到影响 +> 迭代器失效:在容器大小发生变化时(如插入或删除元素),迭代器可能会失效 +> 性能权衡:虽然 `deque` 在头部和尾部操作高效,但在中间插入或删除元素的性能不如 `list` + +__相比vector的优势__ +> 头部操作高效:deque 在头部插入和删除操作的时间复杂度为 O(1),而 vector 为 O(n)。 +> 动态变化灵活:deque 的*分块内存*分配使其更灵活,性能损耗更小,且内存不足时不用搬运所有元素 +> 随机访问性能接近:虽然 deque 的随机访问效率略低于 vector,但差距不大 + +### list +1. 特点 + + 双向链表结构:每个元素包含指向前后元素的指针,支持双向遍历 + + 高效插入和删除:在任意位置插入或删除元素的时间复杂度为 O(1),前提是已知位置 + + 不支持随机访问:无法通过索引直接访问元素,只能通过迭代器遍历 + + 稳定的迭代器:插入和删除操作不会使迭代器失效,除非删除了迭代器所指向的元素 + +1. 插入和删除 + + `push_back()` 和 `pop_back()`:尾部操作 + + `push_front()` 和 `pop_front()`:头部操作 + + `insert()` 和 `erase()`:在任意位置插入或删除 + +2. 其他 + + resize():调整容器大小 + + swap():交换两个 list 的内容 + + splice():将一个 list 的元素插入到另一个 list 的指定位置 + + sort()、merge()、reverse():排序、合并和反转 + +__注意事项__ +> 不支持随机访问:无法通过索引访问元素,只能通过迭代器 +> 内存开销:每个元素存储额外的指针,内存开销较大 +> 缓存局部性差:元素不连续存储,遍历性能不如 std::vector +> 适用场景有限:只有在需要频繁中间插入和删除时才适合使用 + + +## 关联容器 + +存储元素时会自动排序,通常基于键值对 + +### set +基于红黑树实现 适用于需要去重、排序和*高效查找*的场景 + +1. 特点 + + 元素唯一性:容器中不允许存储重复元素 + + 自动排序:元素会根据指定的比较规则自动排序,默认为升序 + + 高效查找:插入、删除和查找操作的时间复杂度均为 O(log n) + +2. 构造与初始化 + + 默认构造 + + 初始化列表 + + 拷贝构造 + + 自定义比较规则 +``` +struct Compare { + bool operator()(int a, int b) const { + return a > b; // 降序排序 + } +}; +``` + +3. 常用操作 + + 插入元素 `s1.insert(5);` + + 删除元素 `s1.erase(3); // 删除值为 3 的元素` + + 查找元素 `s1.find(4); // 返回指向元素的迭代器,未找到时返回 s1.end()` + + 统计元素 `int count = s1.count(4);` + + 范围查询 +``` +auto lower = s1.lower_bound(3); // 返回第一个 >= 3 的元素的迭代器 +auto upper = s1.upper_bound(5); // 返回第一个 > 5 的元素的迭代器 +``` + +4. 高级用法 + + 自定义排序规则:使用仿函数或 `std::greater` 可以改变排序规则 + + 存储复杂数据类型:可以存储 `std::pair` 或自定义结构体,通过自定义比较函数排序 + + 范围删除 `s1.erase(s1.lower_bound(10), s1.upper_bound(50)); // 删除值在 [10, 50) 范围内的所有元素` + +__注意事项__ +> 修改元素:无法直接修改容器中的元素值,需要先删除再插入 +> 性能开销:由于自动排序的特性,插入和删除操作比无序容器慢 +> 迭代器失效:插入操作不会使迭代器失效,但删除操作会使指向被删除元素的迭代器失效 + +### map +用于存储键值对(key-value pairs),并根据键自动排序 + +1. 特点 + + 键的唯一性:每个键在 map 中是唯一的,不允许重复 + + 自动排序:容器会根据键的默认比较规则(通常是 < 运算符)自动排序 + + 高效操作:插入、删除和查找操作的时间复杂度均为 O(log n),其中 n 是容器中元素的数量 + +2. 常用操作 + + 插入元素:`map1.insert({4, "four"});`或`map1[5] = "five"; // 如果键不存在,则插入新键值对;如果键存在,则更新值` + + 查找元素:`map1.find(3);` 或者使用 `operator[]` 直接访问键对应的值 + + 删除元素:`map1.erase(3); // 删除键为 3 的元素。` + +## 无序容器 + +存储元素时不排序,基于哈希表实现 + +## 预定义函数符 + ++ `+` plus ++ `-` minus ++ `*` multiplies ++ `/` divides ++ `%` modulus + ++ `==` `equal_to` ++ `!=` `not_equal_to` ++ `>` `greater` ++ `<` `less` ++ `>=` `greater_equal` ++ `<=` `less_equal` ++ `&&` `logical_and` ++ `||` `logical_or` ++ `!` `logical_not` diff --git a/program/c_cpp/universal/STL/function.md b/program/c_cpp/STL/function.md similarity index 100% rename from program/c_cpp/universal/STL/function.md rename to program/c_cpp/STL/function.md diff --git a/program/c_cpp/universal/STL/string.md b/program/c_cpp/STL/string.md similarity index 97% rename from program/c_cpp/universal/STL/string.md rename to program/c_cpp/STL/string.md index 6eb98b9..944a1f3 100644 --- a/program/c_cpp/universal/STL/string.md +++ b/program/c_cpp/STL/string.md @@ -87,5 +87,5 @@ ## 神奇转换函数 ```cpp - string to_ strinf(任何类型); //将好多类型转换成string + string to_strinf(任何类型); //将好多类型转换成string ``` diff --git a/program/c_cpp/library/offsetof.h b/program/c_cpp/library/offsetof.h new file mode 100644 index 0000000..e509be0 --- /dev/null +++ b/program/c_cpp/library/offsetof.h @@ -0,0 +1,2 @@ +#define offsetof(type, struct_name) (size_t)&(((struct type*)0)->struct_name) +// 计算结构体成员相对结构体首地址的偏移度 diff --git a/program/c_cpp/library/string_hash.c b/program/c_cpp/library/string_hash.c new file mode 100644 index 0000000..a0caa81 --- /dev/null +++ b/program/c_cpp/library/string_hash.c @@ -0,0 +1,10 @@ +// 非加密型hash,速度极快,支持种子 +uint32_t murmur3_32(const char *key, size_t len, uint32_t seed) { + for(uint32_t i=0; i> 15; + } + return seed; +} diff --git a/program/c_cpp/library/thread-pool.cpp b/program/c_cpp/library/thread-pool.cpp new file mode 100644 index 0000000..bd0ec5d --- /dev/null +++ b/program/c_cpp/library/thread-pool.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include + +class ThreadPool { +public: + ThreadPool(size_t num_threads); + ~ThreadPool(); + void enqueue(std::function task); + +private: + std::vector workers; + std::queue> tasks; + std::mutex queue_mutex; + std::condition_variable condition; + bool stop; +}; + +ThreadPool::ThreadPool(size_t num_threads) : stop(false) { + for (size_t i = 0; i < num_threads; ++i) { + workers.emplace_back([this] { + while (true) { + std::function task; + { + std::unique_lock lock(this->queue_mutex); + this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); + if (this->stop && this->tasks.empty()) { + return; + } + task = std::move(this->tasks.front()); + this->tasks.pop(); + } + task(); + } + }); + } +} + +ThreadPool::~ThreadPool() { + { + std::unique_lock lock(queue_mutex); + stop = true; + } + condition.notify_all(); + for (std::thread& worker : workers) { + worker.join(); + } +} + +void ThreadPool::enqueue(std::function task) { + { + std::unique_lock lock(queue_mutex); + if (stop) { + throw std::runtime_error("enqueue on stopped ThreadPool"); + } + tasks.emplace(task); + } + condition.notify_one(); +} + +int main() { + ThreadPool pool(4); + for (int i = 0; i < 8; ++i) { + pool.enqueue([i] { + std::cout << "Task " << i << " is running on thread " << std::this_thread::get_id() << '\n'; + }); + } + return 0; +} diff --git a/program/c_cpp/linux/ncurses.c b/program/c_cpp/linux/ncurses.c new file mode 100644 index 0000000..53f078b --- /dev/null +++ b/program/c_cpp/linux/ncurses.c @@ -0,0 +1,24 @@ +#include +#include + +char fastRead(); + +int main() { + char ch; + printf("Please down any key\n"); + ch = fastRead(); + printf("down : %c --- %d\n", ch, (int)ch); + return 0; +} +char fastRead() { + char ch; + filter(); // 阻止initscr 清空屏幕 + initscr(); // 初始化 + cbreak(); // 禁用缓冲区 + noecho(); // 禁用回显 + keypad(stdscr, TRUE); + ch = getchar(); + refresh(); // 刷新 + endwin(); // 关闭 + return ch; +} diff --git a/program/c_cpp/linux/random.md b/program/c_cpp/linux/random.md new file mode 100644 index 0000000..e8a97d5 --- /dev/null +++ b/program/c_cpp/linux/random.md @@ -0,0 +1,25 @@ +# linux随机数设备 +从系统熵池进行获取 + +## index +- [random-urandom](# random-urandom) +- [note](# note) + +## random-urandom +/dev/random 和 /dev/urandom 的区别 ++ /dev/random: + - 阻塞型设备,当熵池耗尽时会阻塞,直到收集到足够的熵 + - 适合生成高价值的密钥、证书等 + - 可能会影响性能,因为可能需要等待 + ++ /dev/urandom: + - 非阻塞型设备,即使熵池耗尽也会继续提供数据 + - 使用加密算法从初始熵生成伪随机数 + - 对于大多数应用来说已经足够安全 + - 推荐在大多数情况下使用 + +## note +- 对于大多数应用,使用 /dev/urandom 就足够了,它不会阻塞且性能更好 +- 只在生成长期加密密钥等极高安全需求时使用 /dev/random +- 不要频繁打开和关闭设备文件,可以保持打开状态或重用文件描述符 +- 检查所有系统调用的返回值,确保操作成功 diff --git a/program/c_cpp/universal/class.md b/program/c_cpp/universal/class.md index a0bd92c..72a0123 100644 --- a/program/c_cpp/universal/class.md +++ b/program/c_cpp/universal/class.md @@ -1,19 +1,45 @@ # 对象和类 -## 访问控制 -```cpp +## 目录 +- [访问控制](#访问控制) +- [作用域运算符](#作用域运算符) +- [类的六大特殊成员函数](#类的六大特殊成员函数) + - [RAII](#RAII) + - [move语义](#move) + - [右值引用](#右值引用) + - [初始化列表](#初始化列表) +- [const 成员函数](#const成员函数) +- [this指针](#this指针) +- [作用域为类的常量](#作用域为类的常量) +- [作用域内枚举](#作用域内枚举) +- [友元](#友元) +- [类的自动转换和强制类型转换](#类的自动转换和强制类型转换) + - [转换函数](#转换函数) +- [继承](#继承) + - [继承方式](#继承方式) + - [虚函数](#virtual) +- [设计理念](#) + - [is a](#) + - [AbstactBaseClass](#ABC) + +## 访问控制 + +```cpp class demo { -public: // 公有接口 +public : // 公有接口 private: // 私有成员 -protected: // 保护 +protected: // 保护,对外部是私有 }; ``` + ## 作用域运算符(::) + 可用于在类体外指出函数所属的类(命名空间) -## 成员函数的参数名不可与类成员相同 +**成员函数的参数名不可与类成员相同** ## 类的六大特殊成员函数(未定义时编译器提供默认版本) + ```cpp demo::demo(); // 默认构造函数 demo::~demo(); // 默认析构函数 @@ -23,7 +49,57 @@ demo::demo(demo&&); // 移动复制构造函数 demo& demo::operator = (demo&&); // 移动赋值构造函数 ``` -## const 成员函数 适合的成员函数要尽可能用,以帮助规避错误 +`demo::demo() = default;`显式声明为默认 +`demo::demo() = delete;`显式声明为禁用 + + +### RAII + +在类的构造函数中申请堆内存,在析构函数中释放,这样可以保证类失效时内存被释放 + +### move + +移动语义的核心思想是转移而非复制。当一个对象被移动时,其资源(如动态分配的内存、文件句柄等)被转移到目标对象,而源对象被置于一种有效但未定义的状态。这种状态通常是清空的,以确保源对象的资源在其生命周期内不会被重复释放 + +```cpp +MyString(MyString&& other) noexcept : data(other.data) { // 移动构造函数 + other.data = nullptr; +} +MyString& operator=(MyString&& other) noexcept { // 移动赋值运算符 + if (this != &other) { + delete[] data; // 释放当前对象的资源 + data = other.data; + other.data = nullptr; + } + return *this; +} +``` + +`std::move` 是一个函数模板,用于将左值强制转换为右值。它本身并不执行移动操作,而是通过返回一个右值引用,触发移动构造函数或移动赋值运算符 + +`MyString str2 = std::move(str1); // 触发移动构造函数` + +#### 右值引用 +分为两类 +> 普通右值引用:直接声明的T&&,用于移动语义 +> 转发引用:模板函数中声明的T&&,用于完美转发 + +- [函数引用重载](./func#重载) + +### 初始化列表 + +初始化列表是一种在构造函数中初始化类成员变量的机制 + +1. 初始化常量成员变量:常量成员变量必须在构造函数的初始化列表中初始化,不能在构造函数体内赋值。 +2. 初始化引用成员变量:引用成员变量必须在构造函数的初始化列表中初始化,不能在构造函数体内赋值。 +3. 调用基类的构造函数:如果类继承自基类,需要在初始化列表中显式调用基类的构造函数。 +4. 优化性能:对于一些复杂的成员变量(如类对象),使用初始化列表可以避免默认构造后再赋值,从而提高效率。 + +> example +`MyClass(int a, int b, int c) : Base(a), myConst(b), myRef(c), myValue(10) {}` + +## const成员函数 适合的成员函数要尽可能用,以帮助规避错误 + `void show() const;` 声明 `void demo::show() const;` 定义 表明函数不会修改调用对象 @@ -70,3 +146,57 @@ operator typeName(); + 必须是类成员 + 不能有参数 + 不能指定返回类型 + +## 继承 + +基类对象需要在进入派生类的构造函数之前被创建,通常使用初始化列表解决 +`demo::demo() : base();` +### 继承方式 +1. public + + 基类的公有成员在派生类中仍然是公有的。 + + 基类的保护成员在派生类中仍然是保护的。 + + 基类的私有成员在派生类中不可访问。 + + 派生类*对象*可以访问基类的公有成员。 + + 派生类*对象*不能直接访问基类的*私有成员* + +2. protected + + 基类的公有成员和保护成员在派生类中都变成保护的。 + + 基类的私有成员在派生类中仍然不可访问。 + + 派生类*对象*不能直接访问基类的*所有成员* + +3. private + + 基类所有成员变成私有 + + 派生类*对象*不能直接访问基类的*所有成员* + +__保护成员在派生类中的访问性__ +无论继承方式,派生类都可以访问基类的 `protected` 这是因为保护成员的设计初衷就是允许派生类访问,但不允许*派生类的对象*访问 + +### virtual +虚函数是通过在基类中使用关键字 virtual 声明的成员函数 + +虚函数的主要作用是实现动态绑定或运行时多态.当通过基类指针或引用调用虚函数时,程序会根据对象的实际类型(运行时类型)来调用相应的函数版本 + +为了实现动态绑定,C++ 编译器会在每个具有虚函数的类的对象中隐式添加一个指针,指向一个虚函数表(V-Table)。V-Table 是一个函数指针数组,存储了类中所有虚函数的地址。当通过指针或引用调用虚函数时,程序会通过 V-Table 查找并调用正确的函数版本 + +**虚函数的特点** ++ 必须是成员函数 ++ 派生类继承基类的虚函数,但可以重写它 ++ 覆盖:派生类中的虚函数与基类中的虚函数具有相同的签名 ++ 多态:通过基类指针或引用调用虚函数时,会根据对象的实际类型调用相应的函数版本 + +**纯虚函数与抽象类** +如果一个虚函数在基类中没有实现,而是通过在函数声明后加上 = 0 来表示,那么这个函数称为纯虚函数。包含纯虚函数的类称为抽象类 + +`virtual void display() = 0; // 纯虚函数` + +## 设计理念 + +### is-a +### ABC +即使用[纯虚函数](#virtual)构造的抽象类 + +无法构建对象,只能用于构造其他派生类 + +用于提取一系列对象的共性以共用 + +即抽象类设计理念,把一系列对象的共性提取出来,创建一个*抽象*的类 diff --git a/program/c_cpp/universal/compile.md b/program/c_cpp/universal/compile.md new file mode 100644 index 0000000..6438bc1 --- /dev/null +++ b/program/c_cpp/universal/compile.md @@ -0,0 +1,42 @@ +# 预编译指令 + +## 目录 +- [define](#define) + - [预定义宏](#预定义宏) +- [ifdef](#ifdef) +- [ifndef](#ifndef) +- [endif](#endif) +- [pragma](#pragma) +- [error](#error) +- [warning](#warning) + +## define +### 预定义宏 +1. 平台相关 + + `__STDC__` 如果编译器遵循ANSI C标准,则定义为1 + + `__cplusplus` 如果编译器支持C++,则定义为一个版本号 如199711L表示C++98,201103L表示C++11等 + + `_WIN32` 在Windows平台下定义,表示目标系统是32位或64位 + + `_WIN64` + + `__unix__` + + `__linux__` + + `__APPLE__` + +2. 编译器相关 + + `__GNUC__` 如果编译器是GCC,则定义为GCC的主版本号 + + `__clang__` 如果编译器是Clang + + `_MSC_VER` 如果编译器是Microsoft Visual C++,则定义为一个版本号 + + `__ICC` 如果编译器是Intel C/C++ Compiler,则定义 + +3. 文件和行号相关的预定义宏 + + `__FILE__` 当前文件的名称 + + `__LINE__` 当前文件的行号 + + `__DATE__` 编译日期 + + `__TIME__` 编译时间 + +4. 其他 + + `__func__` `__FUNCTION__` 当前函数的名称 + + `__PRETTY_FUNCTION__` 在C++中,包含当前函数的完整声明 + +## pragma + +`#pragma once` 确保头文件只被包含一次 diff --git a/program/c_cpp/universal/func.md b/program/c_cpp/universal/func.md new file mode 100644 index 0000000..cb6f9c7 --- /dev/null +++ b/program/c_cpp/universal/func.md @@ -0,0 +1,47 @@ +# c-cpp function + +## 目录 +- [extern](#extern) +- [noexcept](#noexcept) +- [重载](#) +- [often](#often) + +## extern + +`exterm` 表明函数在外部定义,在链接期才去查找 +`extern "C"` 表明以C的方式查找外部函数 + +## noexcept + +```cpp +void myFunction() noexcept { + // 这个函数不会抛出异常 +} +``` +noexcept 的一个重要用途是优化性能,特别是在移动语义中。当一个函数被标记为 noexcept 时,编译器可以更积极地优化代码 + +## 重载 +只要特征标不同就可以重载 +**特征标**:原型除去返回值都是 + ++ 左值:优先选择T&,如果不可用则选择const T&。 ++ const左值:选择const T&。 ++ 右值:优先选择T&&, else const T& ++ 字面量或临时对象:选择T&&。 + +## often + +``` +abs(x); //求x的绝对值 e.g.abs(-5)=5 +fabs() //实数绝对值 +exp(x); //求x的自然指数e^x e.g.exp(1)=2.718282 +floor(x); //向下取整 +ceil(x); //向上取整 +log(x); //求实数x的自然数对数 e.g.log(1)=0 +pow(x,y); //计算x^y,输出为双精度实数 e.g.pow(2,3)=8 +sqrt(x); //求x的平方根 e.g.sqrt(25)=5 +strlen(str);获取字符数组长度(只能用在字符数组)。 +max(a,b) //两数中最大 +min(a,b) //两数中最小 +swap(a,b) //交换两个类型相同的变量 +``` diff --git a/program/c_cpp/universal/io.md b/program/c_cpp/universal/io.md index 19c4d3a..a2da2ed 100644 --- a/program/c_cpp/universal/io.md +++ b/program/c_cpp/universal/io.md @@ -6,6 +6,7 @@ - [c fio](# c fio) - [cpp stdio](# cpp stdio) - [cpp fio](# cpp fio) + - [关闭缓冲区读取](# ../linux/ncurses.c) ## c stdio diff --git a/program/c_cpp/universal/ptr.md b/program/c_cpp/universal/ptr.md new file mode 100644 index 0000000..8251ce9 --- /dev/null +++ b/program/c_cpp/universal/ptr.md @@ -0,0 +1,156 @@ +# c-cpp的指针问题 + +## 目录 + +- [NULL and nullptr](#NULL-nullptr) +- [cpp智能指针](#cpp智能指针) + - [注意事项](#注意事项) + - [some example](#some-example) + +## NULL-nullptr + +在C和CPP中,NULL并不相同 + +``` +#ifndef NULL + #ifdef __cplusplus + #define NULL 0 + #else + #define NULL ((void *)0) + #endif +#endif +``` + +由源码可知, C中 `NULL` 为 `(void *)0`, 而cpp中视为整形常量 + +因此cpp中应使用nullptr,否则函数重载中会出现选择错误问题 + +## cpp智能指针 + +1. `std::unique_ptr` + +表示独占所有权的指针,即同一时刻只能有一个`unique_ptr`指向某个对象。 + + * 不可复制(没有拷贝构造函数和拷贝赋值运算符)。 + * 可以移动(支持移动语义)。 + * 自动释放资源。 + +**由于不可复制,不能将unique_ptr存储在标准容器中(如std::vector)** + +``` +std::unique_ptr ptr1 = std::make_unique(42); // 创建unique_ptr +std::unique_ptr ptr2 = std::move(ptr1); // 移动所有权 +ptr1 = nullptr; // ptr1不再指向对象,对象由ptr2管理 +``` + +2. `std::shared_ptr` + +表示共享所有权的指针,多个`shared_ptr`可以指向同一个对象 + + * 使用引用计数来管理对象的生命周期。 + * 当最后一个`shared_ptr`被销毁时,对象才会被释放。 + * 可以复制 + * 引用计数可能会引入性能开销,尤其是在多线程环境中。 + * 如果存在循环引用(如双向链表),可能导致内存泄漏。需要使用`std::weak_ptr`来解决。 + +``` +std::shared_ptr ptr1 = std::make_shared(42); +std::shared_ptr ptr2 = ptr1; // 复制,引用计数加1 +std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl; // 输出2 +``` + +3. `std::weak_ptr` + +解决`shared_ptr`的循环引用问题 + + * 不增加引用计数。 + * 可以通过lock()方法获取一个`shared_ptr`,但需要检查对象是否仍然存在 + * `weak_ptr`不能直接访问对象,需要通过lock()方法转换为`shared_ptr`。 + * 如果对象已经被销毁,lock()会返回一个空的`shared_ptr` + +### 注意事项 + +***循环引用问题*** + +`std::shared_ptr`通过引用计数来管理对象的生命周期。当最后一个`shared_ptr`被销毁时,引用计数归零,对象才会被释放。然而,如果两个或多个`shared_ptr`相互引用,引用计数将永远不会归零,因为它们相互持有对方的引用。 + +> example:双向链表中的循环引用 +``` +struct Node { + std::shared_ptr next; // 指向下一个节点 + std::shared_ptr prev; // 指向前一个节点 +}; + auto node1 = std::make_shared(); + auto node2 = std::make_shared(); + node1->next = node2; // node1 持有 node2 的共享所有权 + node2->prev = node1; // node2 持有 node1 的共享所有权 +``` + +为了解决循环引用问题,C++标准库提供了`std::weak_ptr`。`std::weak_ptr`是一种弱引用,它不会增加引用计数,但可以指向一个由`std::shared_ptr`管理的对象 + +``` +struct Node { + std::shared_ptr next; // 指向下一个节点 + std::weak_ptr prev; // 使用 weak_ptr 指向前一个节点 +}; + auto node1 = std::make_shared(); + auto node2 = std::make_shared(); + node1->next = node2; // node1 持有 node2 的共享所有权 + node2->prev = node1; // node2 使用 weak_ptr 指向 node1 +``` + +如果对象仍然存在,lock()返回一个指向对象的`std::shared_ptr` 如果对象已经被销毁,lock()返回一个空的`std::shared_ptr` + + +__正确选择智能指针类型__ + +> 如果对象的所有权是唯一的,使用`std::unique_ptr` +> 如果对象的所有权需要共享,使用`std::shared_ptr` +> 如果需要解决循环引用问题,使用`std::weak_ptr` + +### some-example + +``` +#include +#include +#include // 用于 std::fill +int main() { + // 使用 std::unique_ptr 管理1000个 int 的内存空间 + std::unique_ptr data = std::make_unique(1000); + + // 初始化数据 + std::fill(data.get(), data.get() + 1000, 42); // 将所有元素初始化为42 + // data.get()返回底层指针,可以用于标准库算法(如std::fill) + + // 访问并打印部分数据 + for (int i = 0; i < 10; ++i) { + std::cout << data[i] << " "; + } + std::cout << std::endl; + + // 当 unique_ptr 超出作用域时,内存会自动释放 + return 0; +} +``` +``` +#include +#include +#include // 用于 std::fill +int main() { + // 使用 std::shared_ptr 管理1000个 int 的内存空间 + std::shared_ptr data(new int[1000]); // 使用 new[] 分配内存 + // ***std::shared_ptr需要显式使用new[]分配内存*** + + // 初始化数据 + std::fill(data.get(), data.get() + 1000, 42); // 将所有元素初始化为42 + + // 访问并打印部分数据 + for (int i = 0; i < 10; ++i) { + std::cout << data[i] << " "; + } + std::cout << std::endl; + + // 当最后一个 shared_ptr 超出作用域时,内存会自动释放 + return 0; +} +``` diff --git a/program/c_cpp/universal/specifier_qualifier.md b/program/c_cpp/universal/specifier_qualifier.md index fd1d390..7f33229 100644 --- a/program/c_cpp/universal/specifier_qualifier.md +++ b/program/c_cpp/universal/specifier_qualifier.md @@ -1,12 +1,13 @@ -# 存储说明符 -+ static -+ extern -+ mutable -+ thread_local +# 说明符 -# cv 说明符 -+ const -+ volatile +## 目录 +- [static](#static) +- [extern](#extern):引用声明 +- [mutable](#mutable) +- [thread local](#`thread_local`) +- [const](#const) +- [volatile](#volatile):强制读内存 +- [restrict](#restrict) : 指示编译器优化指针(C99) ## static @@ -18,7 +19,7 @@ ## extern 引用声明 - 声明引用在其他地方定义的变量 + 声明引用在其他地方定义的变量或者函数 ## mutable 即使结构(类)被声明为const,也可以被修改的成员函数 @@ -36,4 +37,15 @@ 就像使用了static 如果希望连接性为外部,则可以用extern覆盖 -## volatile 强制读内存 +## restrict +- 在没有 restrict 的情况下,编译器需要考虑指针之间可能存在的别名关系。编译器会频繁地从内存中读取数据,以确保每次使用指针时数据是最新的。这会导致不必要的内存访问 +- 使用 restrict 后,编译器可以假设带有 restrict 的指针是唯一的,不会与其他指针指向同一块内存。因此,编译器可以减少不必要的内存访问 + +```c +void copy(int *restrict dest, int *restrict src, int n) { + for (int i = 0; i < n; i++) { + dest[i] = src[i]; + } +} +``` +__如果违反了 restrict 的约束(即多个 restrict 指针指向同一块内存),程序的行为是未定义的__ diff --git a/program/c_cpp/universal/template.md b/program/c_cpp/universal/template.md index 27cdb59..184c5a8 100644 --- a/program/c_cpp/universal/template.md +++ b/program/c_cpp/universal/template.md @@ -1,35 +1,33 @@ # 模板 +## 目录 +- [函数模板](#) + - [生成](#) +- [类模板](#) +- [完美转发](#) +- [可变参数](#可变参数) + ## 函数模板 - -### 基本格式 - ```cpp template -void swap(T &a, T &b) { - T temp; - temp = b; - b = a; - a = temp; -} +void swap(T &a, T &b); ``` -__函数模板必须放在头文件里,因为它不是函数实体,只能算编译指令__ +__函数模板必须放在编译器可见的地方里,因为不是函数实体,只能算编译指令__ -### 模板的几个术语 -+ **隐式实例化** +### 生成 +**隐式实例化** ```cpp int a=0, b=3; swap(a, b); ``` -+ **显式实例化** +**显式实例化** ```cpp template void swap(int&, int&); // 使用模板生成int类型的函数定义 ``` -+ **显式具体化** +**显式具体化** 这个可以放到其他文件里,因为是有实体的 ```cpp template <> void swap(int&, int&); ``` -__这个可以放到其他文件里,因为是有实体的__ ### 类型推导 + decltype() @@ -39,5 +37,29 @@ decltype(a) var; ``` ## 类模板 +同样没有实体,包括类成员方法等都要写成模板的格式 -+ 同样没有实体,包括类成员方法等都要写成模板的格式 +## 完美转发 +- [右值引用](./class.md#):有关完美转发的基础 +完美转发允许模板函数将参数原封不动地转发给另一个函数,保留其左值或右值的性质。这在编写通用代码时非常有用,例如模板库或函数包装器 + +完美转发的核心是std::forward,它根据模板参数T的类型(左值引用或右值引用)来决定如何转发参数 + +``` +template +void wrapper(T&& arg) { + // 转发 arg 到另一个函数,保留其左值或右值性质 + targetFunction(std::forward(arg)); +} +``` + +## 可变参数 + +``` +void print() {} // 终止递归 +template -#include - -using namespace std; -void func(int a) { - cout << a << endl; -} - -mutex mtx; // 互斥量 - -int main() { - -// 同一个进程的多个线程共享该进程的全部系统资源 -// 但各个线程有自己的调用栈,寄存器,本地存储 - -// thread类 -// 1. -// thread() noexcept;默认构造函数,不执行任何任务 -// 2. -// template -// explicit thread(Function&& fx,Args&&... args); - - thread t1(func, 1); //用2方法创建线程 - -// mtx.lock(); -// mtx.unlock(); - - - if(t1.joinable()) // 判断能否调用join - t1.join(); //回收线程t1 -// t1.detach(); //分离线程 - return 0; -} - -// 注:g++编译器要加 -pthread -std=c++11选项编译 diff --git a/program/c_cpp/universal/thread.md b/program/c_cpp/universal/thread.md new file mode 100644 index 0000000..1c821e7 --- /dev/null +++ b/program/c_cpp/universal/thread.md @@ -0,0 +1,130 @@ +# cpp多线程 +C++11引入了标准的线程库 ``,使得多线程编程更加方便和标准化 + +## 目录 +- [创建线程](#) +- [线程的分离和结合](#) +- [传递参数给线程函数](#) +- [线程的同步](#) + - [互斥锁](#mutex) + - [lock-guard](#) +- [条件变量](#) +- [原子操作](#atomic) +- [高级接口](#高级接口) +- [线程池](#) + +## 创建线程 +通过 `std::thread` 类来创建和管理线程 +``` + std::thread t(thread_function); // 创建线程并执行 thread_function + t.join(); // 等待线程结束 +``` + +## 线程的分离和结合 ++ `join()`:主线程等待子线程执行完毕。 ++ `detach()`:将子线程与主线程分离,子线程在后台独立运行。 + +## 传递参数给线程函数 +可以通过 `std::thread` 的构造函数传递参数给线程函数 + +`std::thread t(thread_function, 10, "Hello");` + +## 线程的同步 +多个线程访问共享资源时,可能会出现竞争条件(Race Condition)。为了避免这种情况,可以使用互斥锁(Mutex)来同步线程 + +### 互斥锁 +`std::mutex` 用于保护共享资源,确保同一时间只有一个线程可以访问,`` + +``` +std::mutex mtx; // 互斥量 +void print_block() { + mtx.lock(); // 锁定互斥锁 + // ... + mtx.unlock(); // 解锁互斥锁 +} +// in main -> + std::thread t1(print_block, 50, '*'); + std::thread t2(print_block, 50, '$'); + t1.join(); + t2.join(); +``` + +### lock-guard +`std::lock_guard` 是一个 RAII 风格的互斥锁管理类,它在构造时锁定互斥锁,在析构时自动解锁0 + +``` +std::mutex mtx; +std::lock_guard lock(mtx); +``` + +## 条件变量 +条件变量用于线程间的同步,允许线程在某些条件不满足时等待,直到其他线程通知条件满足 + +`` +```cpp +std::mutex mtx; +std::condition_variable cv; +bool ready = false; +void print_id(int id) { + std::unique_lock lock(mtx); + while (!ready) { + cv.wait(lock); // 线程等待条件变量 + } + std::cout << "thread " << id << '\n'; +} +void go() { + std::unique_lock lock(mtx); + ready = true; + cv.notify_all(); // 通知所有等待的线程 +} +// main + std::thread threads[10]; + for (int i = 0; i < 10; ++i) { + threads[i] = std::thread(print_id, i); + } + go(); + for (auto& th : threads) { + th.join(); + } +``` + +## atomic +`std::atomic` 提供了原子操作,确保对共享变量的操作是不可分割的 + +## 高级接口 + +```cpp +void wait_s(time_t sec) { // 延时函数 + std::cout << "BEGIN" << std::endl; + time_t begin = time(0); + while((time(0) - begin) < sec); +} +int main() { + std::future r1(std::async(wait_s, 10)); + // async let `a piece of functionality` run in alone thread + + wait_s(10); + r1.get(); // 获得返回值,确保必将被调用 + + std::cout << "END" << std::endl; + return 0; +} +``` + +## 线程池 +通过 `std::thread` 和任务队列来实现一个简单的[线程池](../library/thread-pool.cpp) + +// thread类 +// 1. +// thread() noexcept;默认构造函数,不执行任何任务 +// 2. +// template +// explicit thread(Function&& fx,Args&&... args); + + if(t1.joinable()) // 判断能否调用join + t1.join(); //回收线程t1 +// t1.detach(); //分离线程 + return 0; +} + +__注:g++编译器要加 -pthread -std=c++11选项编译__ diff --git a/program/c_cpp/universal/常用函数.txt b/program/c_cpp/universal/常用函数.txt deleted file mode 100644 index fd14404..0000000 --- a/program/c_cpp/universal/常用函数.txt +++ /dev/null @@ -1,34 +0,0 @@ -abs(x); //求x的绝对值 e.g.abs(-5)=5 -fabs() //实数绝对值 -a=clock();测量从程序开始到目前的时间,并把值给a。(单位毫秒级) -exp(x); //求x的自然指数e^x e.g.exp(1)=2.718282 -floor(x); //向下取整 -ceil(x); //向上取整 -log(x); //求实数x的自然数对数 e.g.log(1)=0 -pow(x,y); //计算x^y,输出为双精度实数 e.g.pow(2,3)=8 -sqrt(x); //求x的平方根 e.g.sqrt(25)=5 -str.length();获取字符串长度(只能用在字符串)string b="123456789";//字符串定义 初始化。 -str.size(); -strlen(str);获取字符数组长度(只能用在字符数组)。 -abort() //终止程序运行 不能结束工作 -exit() //终止程序运行 做结束工作 -max(a,b) //两数中最大 -min(a,b) //两数中最小 -swap(a,b) //交换两个类型相同的变量 - -sort(数组名+起始单元,数组名+结束单元,排序方法cmp倒); - sort(a,a+n);//sort默认为升序 - int cmp(int a,int b) - { - return a>b; - } - -Sleep(s时间);//程序运行到此处时暂停s毫秒,注意大小写,需调用头文件#include - -void color(const unsigned short textColor) //颜色字函数 -{ - if(textColor>=0&&textColor<=15) - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),textColor); - else - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7); -} diff --git a/program/python/basics/demo.py b/program/python/basics/demo.py index 3aa1df1..c2bdadc 100644 --- a/program/python/basics/demo.py +++ b/program/python/basics/demo.py @@ -1,6 +1,7 @@ -a1 = int(input("input:")) # input -print('%8d'%a1, '\n') # print -# print(objects, sep=' ', wnd='\n') +a1 = int(input("input:")) # input +a, b = map(int, input().split()) # 读取输入分割并转化 +print('%8d'%a1, '\n') # print +# print(objects, sep=' ', end='\n') # 数据类型 @@ -18,38 +19,38 @@ print() # 运算符 """ - 1. ** - 2. * / % // - 3. + - - 4. <= < > >= - 5. <> == != - 6. = %= /= //= -= += *= **= - 7. not or and + 1. ** + 2. * / % // + 3. + - + 4. <= < > >= + 5. <> == != + 6. = %= /= //= -= += *= **= + 7. not or and """ # 条件判断 if (x1==a1) and (x3==True): - print("OK!!!") + print("OK!!!") elif x3==False: - print("x3==False") + print("x3==False") else: - print("x1:", x1) - print("a1:", a1) + print("x1:", x1) + print("a1:", a1) print() # 循环控制 -for i in range(10): # 逐一访问序列中的元素 - while i>=9 and i<13: # 通过条件控制 - print(i) - i+=1 - continue - break +for i in range(10): # 逐一访问序列中的元素 + while i>=9 and i<13: # 通过条件控制 + print(i) + i+=1 + continue + break -# range() 函数 创建一个整数列表 +# range() 函数 创建一个整数列表 """ - # 基本格式 - range(start, stop,[step]) - # 开始 结束 步长 - range(5, 1, -1) # 可做到倒序输出 + # 基本格式 + range(start, stop,[step]) + # 开始 结束 步长 + range(5, 1, -1) # 可做到倒序输出 """ diff --git a/program/python/basics/string.py b/program/python/basics/string.py deleted file mode 100644 index 0f59c46..0000000 --- a/program/python/basics/string.py +++ /dev/null @@ -1,23 +0,0 @@ -# 字符串 -s = str("Hello world") - -print(s[3]) -print(s[-3]) -print(s[0:3]) # 字符串切片 -print(s[3:]) -print(s[:5]) -print(s[:-5]) -print(s[::-1]) # 倒序 -len(s) # 计算长度 - -# 字符串查询 -s.find('w') -s.count('l') - -s.replace('H','h') # H变成h -s.casefold() # 大写转小写 -s.upper() # 小写转大写 -s.swapcase() # 转换大小写 -eval('12+3') # 计算值 返回15 - - diff --git a/program/python/basics/summary.md b/program/python/basics/summary.md new file mode 100644 index 0000000..5bb06b6 --- /dev/null +++ b/program/python/basics/summary.md @@ -0,0 +1,97 @@ +# python基础合集 + +## 目录 + +- [程序之始](#run) +- [IO](#IO) + - [格式化输出](#) +- [字符串](#string) +- [DEBUG](#Debug) +- [变量](#) + - [数值类型](#) + +## run + +`if __name__ == '__main__'` 判断程序是否在主函数内(区别与模块等) + +## IO + +`print(values, sep, end)` 值, 分割符, 结尾符 +> `print("hello", sep=',', end='_')` +> `print('%8d'%a1, '\n')` + +a1 = int(input("input:")) # input +a, b = map(int, input().split()) # 读取输入分割并转化 + +### 格式化输出 +1. 占位符 ++ `%` ++ `format()` ++ `格式化f` + +> example +`print("%4d" % a)` + + +## string + +字符串可以用单引号或者双引号 + +三引号可以跨行 + +> example +```python +print('''Hello +world''') +``` + +``` +s = str("Hello world") +print(s[3]) +print(s[-3]) +print(s[0:3]) # 字符串切片 +print(s[3:]) +print(s[:5]) +print(s[:-5]) +print(s[::-1]) # 倒序 +len(s) # 计算长度 + +s.find('w') +s.count('l') + +s.replace('H','h') # H变成h +s.casefold() # 大写转小写 +s.upper() # 小写转大写 +s.swapcase() # 转换大小写 +eval('12+3') # 计算值 返回15 +``` + +## Debug + +1. pdb +`import pdb; pdb.set_trace()` 程序运行到这行代码时会进入调试模式 + + n(next):执行下一行代码。 + + c(continue):继续运行直到遇到下一个断点。 + + q(quit):退出调试。 + + p <变量>:打印变量的值。 + + l(list):显示当前代码上下文。 + + b <行号>:设置断点。 + + cl(clear):清除断点。 +``` +def add(a, b): + import pdb; pdb.set_trace() # 从这里进入断点调试 + return a + b +print(add(3,5)) +``` + +## 变量 +name = value + +### 数值类型 ++ int ++ float ++ bool True = 1 False = 0 ++ complex ++ [str](#string) + +type() diff --git a/program/tool/docker.md b/program/tool/docker.md index 9a23a4a..0f7f0b4 100644 --- a/program/tool/docker.md +++ b/program/tool/docker.md @@ -1,8 +1,39 @@ -安装docker - sudo apt-get install docker-compose +# docker +是一个开源的应用容器引擎 -配置/etc/docker/daemon.json - +## 目录 +- [核心组件](#) +- [install](#) +- [基本命令](#) + - [样例](#example-command) +- [数据管理](#) +- [高级用法](#) +- [daemon.json](#) + +## 核心组件 ++ 镜像(Image):只读模板,包含运行应用所需的所有内容,如代码、运行时、库等 ++ 容器(Container):镜像的运行实例,隔离运行应用的环境 ++ 仓库(Repository):存储和分发镜像的地方,Docker Hub 是最常用的公共仓库 + + +## install ++ 更新系统并安装依赖包 ++ 添加 Docker 官方 GPG 密钥并设置存储库 ++ 安装 Docker 引擎并启动服务 ++ 设置 Docker 开机自启 + +```bash +sudo apt-get update +curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - +echo "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list +sudo apt-get update +sudo apt-get install docker-ce docker-ce-cli containerd.io +# 验证安装 +sudo docker --version +``` + +__配置/etc/docker/daemon.json__ +``` { "registry-mirrors": [ @@ -11,23 +42,173 @@ "https://docker.nju.edu.cn" ] } +``` -docker ps #查看所有运行容器 -docker ps -a #全部 +## 基本命令 +1. 镜像操作 + + `docker pull <镜像名>` : 从仓库拉取镜像 + + `docker image ls` : 列出本地镜像 + + `docker rmi <镜像ID>` : 删除镜像 -docker stop [ID / NAME] #停止某容器 +2. 容器操作 + + `docker run -d <镜像名>` : 创建并后台运行容器 + + `docker ps` : 列出所有运行中容器 + + `docker stop [ID / NAME]` : 停止某容器 + + `docker start [ID / NAME]` : 启动已经停止的容器 + + `docker rm [ID / NAME]` : 删除容器 + + `docker commit <容器ID或名称> <新镜像名称>:<标签>` 将运行中的容器保存为镜像 + + `docker save -o my-new-image.tar my-new-image:latest` 导出为tar文件 + + `docker load -i my-new-image.tar` 导入镜像到目标环境 -docker start [ID / NAME] #启动和删除容器 -docker rm [ID / NAME] +3. 其他 + + `docker search <镜像名>` 搜索镜像 + + `docker logs <容器ID>` : 查看容器日志 + + `docker exec -it [ID / NAME] /bin/bash` : 进入容器 + + `c-P c-Q` : 退出容器 + + `sudo systemctl daemon-reload && sudo systemctl restart docker` 重启 + + `docker load < xxx.tar` #导入tar为镜像 + + `docker commit [ID] [镜像名]` #容器保存为镜像 -docker pull 仓库名/镜像名 +### example-command +> `docker pull ubuntu` 拉取 Ubuntu 镜像 +> `docker run -it ubuntu /bin/bash` 运行 Ubuntu 容器并进入交互式 shell +> `docker ps -a` 列出所有容器(包括停止的) +> `docker run -it --name mc-ser ubuntu -v /opt/mc:/opt/mc -p 25565:25565 /bin/bash` -docker save [ID] > xxx.tar #导出为tar文件 -docker load < xxx.tar #导入tar为镜像 +## 数据管理 +为了持久化数据,Docker 提供了多种数据管理方式,主要包括 数据卷(Volumes)、绑定挂载(Bind Mounts) 和 临时文件系统(tmpfs) -docker commit [ID] [镜像名] #容器保存为镜像 +1. Docker 数据卷(Volumes) +数据卷是 Docker 推荐的数据持久化方式。数据卷存储在 Docker 管理的文件系统中(通常是 /var/lib/docker/volumes/),与容器的生命周期分离,即使容器被删除,数据卷仍然存在 -docker image ls #查看本地所有镜像 -docker rmi [ID / NAME] #删除镜像 ++ 持久化:数据卷独立于容器,容器删除后数据仍然保留。 ++ 高性能:数据卷通常比绑定挂载性能更好。 ++ 易于备份和迁移:数据卷可以通过 Docker 命令轻松备份和恢复。 -docker exec -it [ID / NAME] bash #操作容器 +> `docker volume create my_volume` 创建数据卷 +> `docker volume ls` 查看数据卷 +> `docker volume inspect my_volume` 查看数据卷详细信息 +> `docker run -d --name my_container -v my_volume:/path/in/container ` 挂载数据卷到容器 +> `docker volume rm my_volume` 删除数据卷 +> `docker volume prune` 清理未使用的数据卷 + +2. 绑定挂载(Bind Mounts) +绑定挂载是将主机上的文件或目录直接挂载到容器中 + ++ 灵活性:可以直接挂载主机上的任意文件或目录。 ++ 实时同步:主机和容器之间的文件修改会实时同步。 ++ 依赖主机文件系统:绑定挂载的路径必须存在于主机上。 + +- `docker run -d --name my_container -v /host/path:/container/path ` 挂载主机目录到容器 + +3. 临时文件系统(tmpfs) +tmpfs 是一种基于内存的文件系统,适用于需要临时存储数据的场景。数据仅存储在内存中,容器停止后数据会丢失 + ++ 高性能:数据存储在内存中,读写速度快。 ++ 临时性:数据不会持久化,容器停止后数据丢失。 + +`docker run -d --name my_container --tmpfs /container/path ` 挂载 tmpfs 到容器 + +4. 数据卷的高级用法 +多个容器可以共享同一个数据卷,实现数据共享 +``` +docker run -d --name container1 -v my_volume:/data +docker run -d --name container2 -v my_volume:/data +``` + +可以将数据卷或绑定挂载设置为只读,防止容器修改数据 +`docker run -d --name my_container -v my_volume:/data:ro ` + +## 高级用法 +1. Dockerfile +Dockerfile 是用于构建镜像的脚本文件,包含一系列指令,用于定义镜像的构建过程 +``` +# 使用基础镜像 +FROM ubuntu:latest + +# 维护者信息 +MAINTAINER Your Name + +# 更新包索引并安装软件 +RUN apt-get update && apt-get install -y \ + software-properties-common \ + python3 + +# 设置工作目录 +WORKDIR /app + +# 复制当前目录下的文件到容器中的 /app 目录 +COPY . /app + +# 暴露端口 +EXPOSE 80 + +# 设置环境变量 +ENV NAME World + +# 运行命令 +CMD ["python3", "app.py"] +``` +`docker build -t .` 构建镜像 + +2. Docker 网络 +`docker network create ` 创建网络 + +`docker network ls` 查看网络 + +`docker network connect ` 连接容器到网络 + +3. Docker 数据管理 +`docker volume create ` 创建数据卷 + +`docker volume ls` 查看数据卷 + +`docker run -v :/path/in/container ` 挂载数据卷到容器 + +4. Docker 资源限制 +`docker run -m 512m ` 限制内存 + +`docker run --cpus="1.5" ` 限制 CPU + +5. Docker 安全 +> 使用非 root 用户运行容器 +```dockerfile +FROM ubuntu +RUN useradd -m myuser +USER myuser +``` +> 限制容器权限 +`docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE ` + +## daemon.json +``` +{ + "registry-mirrors": [ + "https://docker.1ms.run", + "https://docker.xuanyuan.me", + "https://docker.zhai.cm", + "https://a.ussh.net", + "https://hub.littlediary.cn", + "https://hub.rat.dev", + "https://atomhub.openatom.cn", + "https://docker.m.daocloud.io", + "https://dytt.online", + "https://func.ink", + "https://lispy.org", + "https://docker.xiaogenban1993.com", + "https://docker.mybacc.com", + "https://docker.yomansunter.com", + "https://dockerhub.websoft9.com", + "https://docker-0.unsee.tech", + "https://docker-cf.registry.cyou", + "https://docker.1panel.live", + "https://docker.imgdb.de", + "https://docker.hlmirror.com", + "https://dockerpull.org", + "https://dockerhub.icu", + "https://proxy.1panel.live", + "https://docker.1panel.top", + "https://docker.ketches.cn" + ] +} +``` diff --git a/program/tool/g++.txt b/program/tool/g++.txt deleted file mode 100644 index 0929ac4..0000000 --- a/program/tool/g++.txt +++ /dev/null @@ -1,29 +0,0 @@ -g++ -S test.s test.cpp #编译成汇编文件 -g++ -c test.o test.s #目标文件 -g++ -o test test.o #链接 - -g++ -O1/-O2/-O3 // 优化选项 - -g++ -S -o - -fverbose-asm xxx.cpp > xxx.s // 输出带注释的汇编 - - -#静态库制作: - g++ -c -o libtest.a {test.cpp 源代码文件清单} -// g++ -c test.cpp -// ar -crv libtest.a test.o - - -#动态库制作 - g++ -fPIC -shared -o libtest.so {test.cpp 源代码文件清单} -// g++ -fPIC -c test.cpp -// g++ -shared -o libtest.so tset.o - 两种方法 - 1 + .so 放到 /usr/lib 或 /lib - 2 + 路径放到/etc/ld.so.conf 运行ldconfd 重建/etc/ld.so.cache - -# 库使用 - g++ -o main -l库名 -L库路径 -I头文件路径 - // g++ -o main -ltest -L/home/e0x1a/test - - 如果是动态库,需要指定 LD_LIBRARY_PATH 环境变量 //待查 - 用 echo $LD_LIBRARY_PATH 查看 diff --git a/program/tool/gcc_g++.md b/program/tool/gcc_g++.md new file mode 100644 index 0000000..52a5567 --- /dev/null +++ b/program/tool/gcc_g++.md @@ -0,0 +1,43 @@ +# gcc-g++ 编译器 + +## 目录 +- [编译选项](#编译选项) +- [制作库文件](#制作库文件) + +## 编译选项 +`g++ -S test.s test.cpp` 编译成汇编文件 +`g++ -c test.o test.s` 目标文件 +`g++ -o test test.o` 链接 + +`g++ -O1/-O2/-O3` // 优化选项 + +`g++ -S -o - -fverbose-asm xxx.cpp > xxx.s` // 输出带注释的汇编 + +`gcc -s` 选项用于剥除可执行文件中的符号表和重定位信息,减小可执行文件的大小 +- **正常功能保持** +- **性能无显著差异** +- **调试困难**:符号表中包含了函数名、变量名等调试信息。使用 `-s` 选项后,这些信息会被移除,使得调试变得非常困难 +- **反汇编和分析不便**:没有符号表,反汇编工具(如 `objdump`)无法显示函数名和变量名等信息,只能显示汇编指令和地址。这会增加对程序进行反汇编分析的难度。 + + +## 制作库文件 +> 静态库制作: + g++ -c -o libtest.a {test.cpp 源代码文件清单} +// g++ -c test.cpp +// ar -crv libtest.a test.o + + +> 动态库制作 + g++ -fPIC -shared -o libtest.so {test.cpp 源代码文件清单} +// g++ -fPIC -c test.cpp +// g++ -shared -o libtest.so tset.o + 两种方法 + 1 + .so 放到 /usr/lib 或 /lib + 2 + 路径放到/etc/ld.so.conf 运行ldconfd 重建/etc/ld.so.cache + +> 库使用 + g++ -o main -l库名 -L库路径 -I头文件路径 + // g++ -o main -ltest -L/home/e0x1a/test + + 如果是动态库,需要指定 LD_LIBRARY_PATH 环境变量 //待查 + 用 echo $LD_LIBRARY_PATH 查看 diff --git a/program/tool/gdb.md b/program/tool/gdb.md new file mode 100644 index 0000000..1d5b03b --- /dev/null +++ b/program/tool/gdb.md @@ -0,0 +1,63 @@ +# gdb c/c++ 代码调试工具 +使用 -g 生成调试文件,不可以加 -O 选项 + +## 目录 +- [基础使用](#基础使用) + - [run](#run) + - [set](#set) + - [mem](#mem) + - [disassemble](#disassemble) + - [info](#info) +- [core](#core) + +## 基础使用 +`l n` 列出源码 +`b n` 在第n行打断点 +`break main if var_name > 10` 满足条件时打断点 +`d n` 删除断点 +`lay next` 切换窗口布局TUI +`Ctrl-x a` 退出TUI +`Ctrl-x 1` 恢复单窗口布局 +`Ctrl-x o` 切换窗口焦点 +`ref``Ctrl-L` 刷新布局 + +### run +`r` 开始运行到第一个断点 +`c` 继续运行到下一个断点 +`s` 步入 +`si` 单步汇编 +`n` 步过 +`ni` +`q` 退出 + +### set +`set [argc]` 传入参数 +`set var []` # 修改变量的值 +`set $rsp = 0x7ccc` # 修改寄存器的值 + +### mem +`p` # 查看特定变量或表达式的值 +`bt` # 查看函数调用栈 +`bt full` # 详细信息 +`x/10gx $rsp` # 查看内存中由$rsp开始的10个八字节数据 g:八字节 x:16进制 + +### disassemble +`disassemble` # 查看当前函数的汇编,可在后面加函数名看指定汇编 +`x/i $pc` # 检查pc处的汇编 + +### info +`info locals` # 查看局部变量 +`info registers` # 查看寄存器状态 +`info program` # 查看程序运行信息 +`info break` # 查看断点信息 +`info threads` # 查看所有线程 + +## core +1. `ulimit -c unlimited` 使挂掉的程序产生core文件 + +2. 修改 `/proc/sys/kernel/core_pattern` 使其在当前目录下生成core文件 +> `sudo echo "./core" > /proc/sys/kernel/core_pattern + +3. gdb ./a.out core + +gdb demo -p [pid] # 调试运行中的程序 diff --git a/program/tool/gdb.txt b/program/tool/gdb.txt deleted file mode 100644 index a8cf2fb..0000000 --- a/program/tool/gdb.txt +++ /dev/null @@ -1,35 +0,0 @@ -gdb c/c++ 代码调试工具 - 使用 g++ -g 生成调试文件,不可以加 -O 选项 - - set [argc] # 传入参数 - l n # 列出源码 - r # 开始运行到第一个断点 - b n # 在第n行打断点 - break main if var_name > 10 # 满足条件时打断点 - d n # 删除断点 - c # 继续运行到下一个断点 - s # 单步执行 - si # 单步汇编 - n # 单步执行,不进入函数 - q # 退出 - - set var [] # 修改变量的值 - set $rsp = 0x7ccccccc # 修改寄存器的值 - - p # 查看特定变量或表达式的值 - bt # 查看函数调用栈 - bt full # 详细信息 - disassemble # 查看当前函数的汇编,可在后面加函数名看指定汇编 - x/10gx $rsp # 查看内存中由$rsp开始的10个八字节数据 g:八字节 x:16进制 - - info locals # 查看局部变量 - info registers # 查看寄存器状态 - info program # 查看程序运行信息 - info break # 查看断点信息 - info threads # 查看所有线程 - -使用gdb调试core文件 - 使用ulimit -c unlimited 使挂掉的程序产生core文件 - gdb ./a.out core - -gdb demo -p [pid] # 调试运行中的程序 diff --git a/program/tool/makefile.md b/program/tool/makefile.md index a801430..e398e43 100644 --- a/program/tool/makefile.md +++ b/program/tool/makefile.md @@ -1,46 +1,486 @@ -# makefile +# make -makefile 是一个通用的项目代码构建器 -由规则 依赖 命令构成 +## 目录 +- [参数](#参数) +- [makefile](#makefile) + +## 参数 +`-n` 参数可以打印出make会执行的命令,但不真正执行 +`-f ` 指定makefile +`-i` 忽略错误 +`-k` 在某个目标失败时,尽量构建其他 +`-s` 静默 +`-j4` 4线程 +`-C /dir` 进入指定目录再运行 +`-d` debug +`-w` 打印工作目录 +`-B` 强制重新构建 + +## makefile +Makefile 是一种用于自动化构建和管理项目的工具,尤其在 C/C++ 项目中广泛使用。除了基本的规则和依赖关系,Makefile 还支持一些高级语法和功能,可以帮助你编写更灵活和高效的构建脚本 规则:依赖 命令 +__注意: 命令前面必须要用Tab__ -+ -n 参数可以打印出make会执行的命令,但不真正执行 - -# 注意: 命令前面必须要用Tab - -# 伪目标 -.PHONY:clean - -# 自动变量 - $@ 目标文件 - $< 第一个依赖文件 - $^ 全部的依赖文件 - -# 普通变量定义 +## 普通变量定义 OPTION = -O3 -Wall -# 变量使用 +## 变量使用 g++ $(OPTION) xxx -# 使用通配符 -%.o: %.c - g++ $(OPTION) -c $< -o $@ +### 1. 变量和赋值 +Makefile 支持多种变量赋值方式: +- **`=`**:递归展开变量,变量值在使用时展开。 +- **`:=`**:简单展开变量,变量值在定义时展开。 +- **`?=`**:条件赋值,只有当变量未定义时才赋值。 +- **`+=`**:追加赋值,将值追加到变量末尾。 ```makefile -.PHONY:clean -INCLUDE = -I/home/e0x2d/include -main: file1.o file2.o - g++ -o $@ file1.o file2.o - -file1.o: file1.cpp - g++ -c file1.o file1.cpp - -file2.o: file2.cpp - g++ -c file2.o file2.cpp ${INCLUDE} - -clean: - rm *.o demo +CC = gcc +CFLAGS := -Wall -O2 +CFLAGS += -g +``` + +### 2. 自动变量 +Makefile 提供了一些自动变量,用于简化规则的编写: + +- **`$@`**:目标文件名。 +- **`$<`**:第一个依赖文件名。 +- **`$^`**:所有依赖文件列表。 +- **`$?`**:所有比目标新的依赖文件列表。 +- **`$*`**:目标文件的主干名(不包含扩展名)。 + +```makefile +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### 3. 模式规则 +模式规则允许你使用通配符来定义规则,适用于多个文件。 + +```makefile +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### 4. 函数 +Makefile 提供了一些内置函数,用于处理字符串、文件名等。 + +- **`$(wildcard pattern)`**:匹配文件名模式。 +- **`$(patsubst pattern,replacement,text)`**:模式替换。 +- **`$(shell command)`**:执行 shell 命令并返回结果。 +- **`$(foreach var,list,text)`**:循环遍历列表。 + +```makefile +SRCS = $(wildcard *.c) +OBJS = $(patsubst %.c,%.o,$(SRCS)) +``` + +### 5. 条件判断 +Makefile 支持条件判断,可以根据条件执行不同的操作。 + +```makefile +ifeq ($(DEBUG),1) + CFLAGS += -DDEBUG +else + CFLAGS += -DNDEBUG +endif +``` + +### 6. 包含其他 Makefile +你可以使用 `include` 指令将其他 Makefile 包含到当前 Makefile 中。 + +```makefile +include config.mk +``` + +### 7. 多目标规则 +你可以为一个规则定义多个目标,这样它们可以共享相同的命令。 + +```makefile +all: target1 target2 + +target1 target2: + @echo Building $@ +``` + +### 8. 伪目标 +伪目标是指那些不对应实际文件的目标,通常用于执行一些操作,如清理、安装等。 + +```makefile +.PHONY: clean + +clean: + rm -f *.o +``` + +### 9. 嵌套 Makefile +你可以在 Makefile 中调用另一个 Makefile,通常用于构建子目录中的项目。 + +```makefile +SUBDIRS = dir1 dir2 + +$(SUBDIRS): + $(MAKE) -C $@ + +all: $(SUBDIRS) +``` + +### 10. 自定义函数 +你可以通过 `define` 和 `endef` 定义自定义函数。 + +```makefile +define greet + @echo "Hello, $(1)!" +endef + +all: + $(call greet,World) +``` + +### 11. 错误处理 +你可以使用 `$(error text)` 和 `$(warning text)` 来生成错误或警告信息。 + +```makefile +ifeq ($(CC),) + $(error CC is not set) +endif +``` + +### 13. 隐式规则 +Makefile 有一些内置的隐式规则,可以自动推导如何从源文件生成目标文件。你可以通过定义自己的隐式规则来覆盖默认行为。 + +```makefile +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### 14. 动态依赖 +你可以使用 `-include` 来包含动态生成的依赖文件,通常用于自动生成头文件依赖。 + +```makefile +-include $(OBJS:.o=.d) + +%.d: %.c + @$(CC) -MM $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ +``` + +### 16. 环境变量 +Makefile 可以访问环境变量,并且可以通过 `export` 将变量传递给子 Makefile。 + +```makefile +export PATH := $(PATH):/usr/local/bin +``` + +### 17. 多行命令 +你可以使用反斜杠 `\` 将长命令分成多行。 + +```makefile +all: + @echo "This is a long command that spans \ + multiple lines." +``` + +### 18. 命令前缀 +命令前缀可以控制命令的执行方式: + +- **`@`**:不显示命令本身,只显示输出。 +- **`-`**:忽略命令的错误,继续执行。 + +```makefile +all: + @echo "This command will not be displayed" + -rm -f non_existent_file +``` + +### 19. 文件搜索路径 +你可以使用 `VPATH` 或 `vpath` 来指定源文件的搜索路径。 + +```makefile +VPATH = src:include + +vpath %.c src +vpath %.h include +``` + +### 20. 递归扩展变量 +递归扩展变量在使用时才会展开,可以用于动态生成内容。 + +```makefile +FOO = $(BAR) +BAR = $(BAZ) +BAZ = Hello + +all: + @echo $(FOO) # 输出 Hello +``` + +### 21. 静态模式规则 +静态模式规则允许你为特定目标定义规则。 + +```makefile +objects = foo.o bar.o + +$(objects): %.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ +``` + +### 22. 多架构支持 +你可以通过条件判断来支持多架构编译。 + +```makefile +ifeq ($(ARCH),x86) + CFLAGS += -m32 +else ifeq ($(ARCH),x64) + CFLAGS += -m64 +endif +``` + +### 23. 自定义后缀规则 +你可以定义自定义的后缀规则来处理特定类型的文件。 + +```makefile +.SUFFIXES: .cpp .o + +.cpp.o: + $(CXX) $(CXXFLAGS) -c $< -o $@ +``` + +### 24. 使用 `eval` 动态生成规则 +`eval` 函数可以动态生成 Makefile 规则。 + +```makefile +define MAKE_RULE +$(1): $(2) + $(CC) $(CFLAGS) -c $$< -o $$@ +endef + +$(eval $(call MAKE_RULE,foo.o,foo.c)) +``` + +### 25. 使用 `foreach` 循环 +`foreach` 函数可以用于循环处理列表中的每个元素。 + +```makefile +DIRS = dir1 dir2 dir3 + +all: + $(foreach dir,$(DIRS),$(MAKE) -C $(dir);) +``` + +### 26. 使用 `call` 调用自定义函数 +`call` 函数可以调用自定义函数,并传递参数。 + +```makefile +define greet + @echo "Hello, $(1)!" +endef + +all: + $(call greet,World) +``` + +### 27. 使用 `shell` 函数执行外部命令 +`shell` 函数可以执行外部命令并返回结果。 + +```makefile +DATE := $(shell date) +``` + +### 28. 使用 `info` 和 `warning` 输出信息 +`info` 和 `warning` 函数可以用于输出信息。 + +```makefile +$(info Building target $(TARGET)) +$(warning This is a warning message) +``` + +### 29. 使用 `if` 条件判断 +`if` 函数可以用于条件判断。 + +```makefile +DEBUG = 1 + +CFLAGS += $(if $(DEBUG),-g,-O2) +``` + +### 30. 使用 `or` 和 `and` 逻辑操作 +`or` 和 `and` 函数可以用于逻辑操作。 + +```makefile +ifeq ($(DEBUG),1) + CFLAGS += -g +else ifeq ($(OPTIMIZE),1) + CFLAGS += -O2 +endif +``` + +### 31. 使用 `not` 取反 +`not` 函数可以用于取反操作。 + +```makefile +ifneq ($(DEBUG),1) + CFLAGS += -O2 +endif +``` + +### 32. 使用 `filter` 和 `filter-out` 过滤列表 +`filter` 和 `filter-out` 函数可以用于过滤列表。 + +```makefile +SRCS = foo.c bar.c baz.c + +C_SRCS = $(filter %.c,$(SRCS)) +NON_C_SRCS = $(filter-out %.c,$(SRCS)) +``` + +### 33. 使用 `sort` 排序列表 +`sort` 函数可以用于排序列表。 + +```makefile +SRCS = foo.c bar.c baz.c + +SORTED_SRCS = $(sort $(SRCS)) +``` + +### 34. 使用 `strip` 去除空格 +`strip` 函数可以用于去除字符串中的空格。 + +```makefile +STR = foo bar + +STRIPED_STR = $(strip $(STR)) +``` + +### 35. 使用 `findstring` 查找子字符串 +`findstring` 函数可以用于查找子字符串。 + +```makefile +ifeq ($(findstring foo,$(STR)),foo) + @echo "Found foo" +endif +``` + +### 36. 使用 `subst` 替换字符串 +`subst` 函数可以用于替换字符串。 + +```makefile +STR = foo bar baz + +NEW_STR = $(subst foo,FOO,$(STR)) +``` + +### 37. 使用 `patsubst` 模式替换 +`patsubst` 函数可以用于模式替换。 + +```makefile +SRCS = foo.c bar.c baz.c + +OBJS = $(patsubst %.c,%.o,$(SRCS)) +``` + +### 38. 使用 `wildcard` 匹配文件名 +`wildcard` 函数可以用于匹配文件名。 + +```makefile +SRCS = $(wildcard *.c) +``` + +### 39. 使用 `dir` 和 `notdir` 获取目录和文件名 +`dir` 和 `notdir` 函数可以用于获取目录和文件名。 + +```makefile +FILE = /path/to/file.c + +DIR = $(dir $(FILE)) +NAME = $(notdir $(FILE)) +``` + +### 40. 使用 `suffix` 和 `basename` 获取后缀和主干名 +`suffix` 和 `basename` 函数可以用于获取文件的后缀和主干名。 + +```makefile +FILE = file.c + +SUFFIX = $(suffix $(FILE)) +BASENAME = $(basename $(FILE)) +``` + +### 41. 使用 `addsuffix` 和 `addprefix` 添加后缀和前缀 +`addsuffix` 和 `addprefix` 函数可以用于添加后缀和前缀。 + +```makefile +FILES = foo bar baz + +FILES_WITH_SUFFIX = $(addsuffix .c,$(FILES)) +FILES_WITH_PREFIX = $(addprefix src/,$(FILES)) +``` + +### 42. 使用 `join` 连接列表 +`join` 函数可以用于连接两个列表。 + +```makefile +LIST1 = foo bar +LIST2 = baz qux + +JOINED_LIST = $(join $(LIST1),$(LIST2)) +``` + +### 43. 使用 `word` 和 `wordlist` 获取列表中的元素 +`word` 和 `wordlist` 函数可以用于获取列表中的元素。 + +```makefile +LIST = foo bar baz + +FIRST = $(word 1,$(LIST)) +SUBLIST = $(wordlist 2,3,$(LIST)) +``` + +### 44. 使用 `words` 获取列表长度 +`words` 函数可以用于获取列表的长度。 + +```makefile +LIST = foo bar baz + +LENGTH = $(words $(LIST)) +``` + +### 45. 使用 `firstword` 获取列表的第一个元素 +`firstword` 函数可以用于获取列表的第一个元素。 + +```makefile +LIST = foo bar baz + +FIRST = $(firstword $(LIST)) +``` + +### 46. 使用 `lastword` 获取列表的最后一个元素 +`lastword` 函数可以用于获取列表的最后一个元素。 + +```makefile +LIST = foo bar baz + +LAST = $(lastword $(LIST)) +``` + +### 47. 使用 `abspath` 获取绝对路径 +`abspath` 函数可以用于获取绝对路径。 + +```makefile +FILE = file.c + +ABS_PATH = $(abspath $(FILE)) +``` + +### 48. 使用 `realpath` 获取规范化的绝对路径 +`realpath` 函数可以用于获取规范化的绝对路径。 + +```makefile +FILE = ../file.c + +REAL_PATH = $(realpath $(FILE)) ``` diff --git a/radio/antenna.md b/radio/antenna.md new file mode 100644 index 0000000..3990a05 --- /dev/null +++ b/radio/antenna.md @@ -0,0 +1,37 @@ +# 天线相关 + +## index +- [极化](# 极化) + +## 极化 +在无线电通信中,垂直极化和水平极化是两种常见的天线极化方式,它们的区别主要体现在电磁波的振动方向、传播特性以及应用场景上。以下是具体对比: + +### **1. 极化方向** +- **垂直极化**:电磁波的电场分量(E-field)与地面垂直振动,天线通常垂直于地面放置(如直立杆状天线)。 +- **水平极化**:电磁波的电场分量与地面平行振动,天线通常水平架设(如水平拉长的偶极天线)。 + +### **2. 传播特性** +- **地面反射影响**: + - 垂直极化波在地面反射时相位变化较小,更适合地面波传播(如AM广播、车载通信)。 + - 水平极化波的地面反射可能导致信号抵消(尤其在仰角较低时),但对天波传播(如短波通信)更有利。 +- **抗干扰能力**: + - 垂直极化更容易受到地面物体(如建筑物、树木)的反射干扰。 + - 水平极化受地面干扰较小,但在城市环境中可能受多径效应影响。 + +### **3. 应用场景** +- **垂直极化**: + - **移动通信**(如车载天线、对讲机):便于安装,适应移动设备姿态变化。 + - **低频段通信**(如30MHz以下):地波传播效率高。 +- **水平极化**: + - **电视广播**(传统地面电视):减少地面反射干扰,覆盖更稳定。 + - **卫星通信**:减少电离层对极化旋转的影响(常与圆极化结合使用)。 + - **短波通信**:利用电离层反射时效率更高。 + +### **4. 天线安装与兼容性** +- **极化匹配**: + - 收发天线极化方式需一致,否则会导致严重信号衰减(如垂直天线无法有效接收水平极化波)。 + - 特殊场景(如卫星通信)可能采用圆极化以避免极化失配。 + +### **总结选择依据** +- **优先垂直极化**:移动通信、地波传播、简化安装。 +- **优先水平极化**:固定点对点通信、减少地面干扰、高频段应用。 diff --git a/tool/git/github b/tool/git/github deleted file mode 100644 index a6fda47..0000000 --- a/tool/git/github +++ /dev/null @@ -1,15 +0,0 @@ -加速器 - https://cloud.tsinghua.edu.cn/d/df482a15afb64dfeaff8/ -推送到github - git remote add origin https:// - git branch -M master - git push -u origin master - -github访问令牌 - 创建: - 用户头像 -> setting -> 最后一项 -> 创建令牌 - tips:令牌要当场复制,离开页面就没有了 - - 使用: - git remote set-url origin https://@github.com//.git - diff --git a/tool/git/github.md b/tool/git/github.md new file mode 100644 index 0000000..653d21f --- /dev/null +++ b/tool/git/github.md @@ -0,0 +1,40 @@ +# github + +## 目录 +- [search](#search) + +## search + +1. 限定搜索范围 +- `in:name`:搜索仓库名称。 +- `in:description`:搜索仓库描述。 +- 使用`is:issue`或`is:pr`搜索Issue或Pull Request。 +- **星标筛选**:使用`stars:>1000`筛选星标数超过1000的项目。 +- **fork数量筛选**:使用`forks:>100`筛选fork数量超过100的项目。 +- **语言筛选**:使用`language:java`筛选使用Java语言的项目。 +- **仓库大小筛选**:使用`size:>=1000`筛选仓库大小超过1000KB的项目。 +- **更新时间筛选**:使用`pushed:>2020-01-01`筛选自2020年1月1日之后有更新的项目。 +- **搜索特定用户或组织的仓库**:使用`user:username`或`org:organization`。 +- **搜索特定文件**:使用`filename:README.md`搜索包含特定文件名的项目。 +- **搜索代码**:必须登录GitHub账户,且仅对默认分支和小于384KB的文件进行索引。 + +2. 排序搜索结果 +- **按交互排序**:`sort:interactions`按反应和评论的最高组合数排序。 +- **按反应排序**:`sort:reactions`按最高反应数排序。 +- **按作者日期排序**:`sort:author-date`按作者日期降序排序。 + +加速器 + https://cloud.tsinghua.edu.cn/d/df482a15afb64dfeaff8/ +推送到github + git remote add origin https:// + git branch -M master + git push -u origin master + +github访问令牌 + 创建: + 用户头像 -> setting -> 最后一项 -> 创建令牌 + tips:令牌要当场复制,离开页面就没有了 + + 使用: + git remote set-url origin https://@github.com//.git + diff --git a/tool/konsole.md b/tool/konsole.md new file mode 100644 index 0000000..3c1d52e --- /dev/null +++ b/tool/konsole.md @@ -0,0 +1,31 @@ +# konsole-use + +## 目录 + +- [strat](#start) +- [标签页管理](#标签页管理) +- [窗口分割](#窗口分割) +- [shortkey](#shortkey) + +## strat +`Ctrl-Alt-t` + +## 标签页管理 +`Ctrl-T` 打开新标签页 +`Ctrl-W` 关闭标签页 +`Ctrl-PgUp` and `Ctrl-PgDn` 切换标签页 +`Alt-[num]` 切换到指定标签页 + +## 窗口分割 +`Ctrl-(` 水平分割 +`Ctrl-)` 垂直分割 +`Ctrl-Shift-方向键` 聚焦指定方向的终端 +`Ctrl-Shift-H` 分离 + +## shortkey +`Ctrl-F` 查找 +`Shift-F3` 查找上一个 +`F3` 查找下一个 + +`Shift-F10` 打开菜单 + diff --git a/tool/vim/.vimrc b/tool/vim/.vimrc index a31bb36..4e5ab98 100644 --- a/tool/vim/.vimrc +++ b/tool/vim/.vimrc @@ -14,28 +14,73 @@ set cursorline "光标行高亮 set hlsearch "高亮显示搜索结果 set incsearch "搜索模式下,每输入一个字符,就跳到对应结果 set ignorecase "忽略搜索大小写 +set tags=./tags;,tags "表示从当前文件所在的目录开始查找 tags 文件,如果没有,则向上递归查找 - +"缓冲区操作 nnoremap b :buffers:b nnoremap e :b# nnoremap n :bnext + +"页面分割操作 nnoremap s :split nnoremap v :vsp nnoremap d w + +"保存 nnoremap w :w nnoremap q :q nnoremap fq :q! +nnoremap pq :%s/\t/ /g:wq + +"多标签页 nnoremap tt :tabedit nnoremap tm :vert term + +"操作优化 +nnoremap gm $ +nnoremap r :reg inoremap jf -inoremap jl cnoremap jf -"inoremap jq :wq -"inoremap jw -"nnoremap to :tabonly +vnoremap gm $ +inoremap ! ! +inoremap ( ( +inoremap ) ) +inoremap 【 [ +inoremap 】 ] +inoremap ; ; +inoremap : : +inoremap ‘ ' +inoremap “ " +inoremap , , +inoremap 。 . +inoremap ? ? +inoremap 《 < +inoremap 》 > +inoremap · ` + +"自动补全 +inoremap jl +inoremap jbf +inoremap jk + +" 启用字典补全(Ctrl-X Ctrl-K) +set complete+=k + +" 加载字典补全功能 + +" 根据文件类型设置不同的字典文件 +autocmd FileType c setlocal dictionary+=~/.vim/dict/cpp.dict +autocmd FileType cpp setlocal dictionary+=~/.vim/dict/cpp.dict +"autocmd FileType python setlocal dictionary+=~/.vim/dict/python.dict +"autocmd FileType javascript setlocal dictionary+=~/.vim/dict/javascript.dict +"autocmd FileType html setlocal dictionary+=~/.vim/dict/html.dict +"autocmd FileType css setlocal dictionary+=~/.vim/dict/css.dict + augroup numbertoggle "智能切换绝对行号和相对行号 autocmd! autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif augroup END + + diff --git a/tool/vim/ShortcutKeys.md b/tool/vim/ShortcutKeys.md deleted file mode 100644 index 28647c5..0000000 --- a/tool/vim/ShortcutKeys.md +++ /dev/null @@ -1,52 +0,0 @@ -# 小技巧 -使用 q[Key] 开始录制宏,再次点击q结束录制 -@[Key] 调用宏 -@@ 重复调用 - -# vim中打开终端 -`:term`或`:vert term` -从终端转到普通模式:`+` - -# 快捷键 - -> 移动 -## 0 gm - 行首行尾移动 -## ngg - 移动到第n行 -## fc tc - 搜索字符 ; , 可重复 - -> 插入 -## r R - 替换光标下的字符 -## n<< n>> - 多行左右移动 - - -> 删除 -## x - 删除光标下字符 -## J - 与下一行合并 - -> 复制 -## "x - 使用寄存器x进行下一次复制 粘贴 删除 - :reg 显示所有寄存器 - - -> 可视模式 -## o - 交换选择区域另一端和光标的位置 -## aw as ap ab aB - 选择一个单词 句子 段落 () {} -## vi{ - 选中一整个大括号内 -## va{ - 选中一整个大括号全部 - - -## ]f - 在文件中若出现文件名,指针放在上面使用这个快捷键可直接打开 - diff --git a/tool/vim/cpp.dict b/tool/vim/cpp.dict new file mode 100644 index 0000000..e871097 --- /dev/null +++ b/tool/vim/cpp.dict @@ -0,0 +1,157 @@ +include +auto +break +case +char +const +continue +default +do +double +else +enum +extern +float +for +goto +if +int +long +register +return +short +signed +sizeof +static +struct +switch +typedef +union +unsigned +void +volatile +while + +class +delete +explicit +friend +inline +namespace +new +operator +private +protected +public +template +this +throw +try +catch +virtual +using +typename +mutable +const_cast +dynamic_cast +reinterpret_cast +static_cast +typeid +endl + +printf +scanf +fopen +fclose +fgets +fputs +fread +fwrite +sprintf +sscanf + +malloc +free +calloc +realloc +exit +atoi +atof +rand +srand + +strcpy +strncpy +strcat +strncat +strcmp +strncmp +strlen +strstr +strtok +memset +memcpy +memmove + +sin +cos +tan +sqrt +pow +log +exp +ceil +floor +fabs + +time +clock +difftime +gmtime +localtime +strftime + +vector +list +map +unordered_map +set +unordered_set +queue +stack +deque +pair +tuple + +sort +find +copy +transform +accumulate +for_each +count +reverse +max_element +min_element + +define +NULL +EOF +true +false +stdin +stdout +stderr +EXIT_SUCCESS +EXIT_FAILURE + +open +close +read +write +fork +exec +pipe +dup2 +select +poll diff --git a/tool/vim/shortcutKeys.md b/tool/vim/shortcutKeys.md new file mode 100644 index 0000000..7d87cc7 --- /dev/null +++ b/tool/vim/shortcutKeys.md @@ -0,0 +1,89 @@ +# vim小技巧 +`.` 重复上一个操作 + +## 目录 +- [录制宏](# 录制宏) +- [打开终端](# 打开终端) +- [快捷键](# 快捷键) + - [移动](# 移动) + - [插入](# 插入) + - [修改](# 修改) + - [删除](# 删除) + - [复制](# 复制) +- [基本补全](# 基本补全) + - [补全菜单](# 补全菜单) +- [vimrc](# ./.vimrc) + +## 录制宏 +使用 q[Key] 开始录制宏,再次点击q结束录制 +@[Key] 调用宏 +@@ 重复调用 + +## 打开终端 +`:term`或`:vert term` +从终端转到普通模式:`+` + +## 快捷键 +### 移动 ++ 0 gm 行首行尾 ++ ngg 移动到第n行 ++ fc tc 搜索字符 ; , 可重复 ++ c-u 上半屏 ++ c-d 下半屏 ++ Shift-[ 跳转到上一个空行 ++ * 移动到下一个与当前指针下相同单词的位置 ++ # 移动到上一个与当前指针下相同单词的位置 ++ Ctrl + ] 跳转到标签,依赖于tags文件 ++ `ctags -R .` 创建目录下的跳转文件 ++ Vim 会记录跳转历史,使用 Ctrl + T 或 Ctrl + O 返回到上一个位置 ++ gf 跳转到文件路径 ++ `c-o` 后退一步 ++ `c-i` 前进一步 ++ `[a-z] / `[A-Z] 跳转到标记位置 大写全局,小写本文件,用m[a-z]设置标记 + + ` 上次跳转的位置 + + . 最后一次修改的位置 + +### 插入 ++ I A 行首 行末 插入 ++ n<< n>> 多行左右移动 + +## 修改 ++ r R 替换光标下的字符 ++ c-i-( 替换括号内的内容可以使用任何括号匹配 + +### 删除 ++ x 删除光标下字符 ++ J 与下一行合并 ++ Shift-d 从当前字符删除到行末 + +### 复制 ++ "x 使用寄存器x进行下一次复制 粘贴 删除 + :reg 显示所有寄存器 + +### 可视模式 ++ o + 交换选择区域另一端和光标的位置 ++ aw as ap ab aB + 选择一个单词 句子 段落 () {} ++ vi{ + 选中一整个大括号内 ++ va{ + 选中一整个大括号全部 ++ ]f + 在文件中若出现文件名,指针放在上面使用这个快捷键可直接打开 + +## 基本补全 +1. Ctrl+n - 普通关键字补全(向下浏览) + - 在当前文件和包含文件中查找匹配项 + - 适用于变量名、函数名等 +2. Ctrl+p - 普通关键字补全(向上浏览) + - 与 Ctrl+n 相同,只是方向相反 +3. Ctrl+x Ctrl+f - 文件名补全 + - 在输入路径时自动补全文件名 +4. Ctrl+x Ctrl+l - 整行补全 + - 补全整行代码(从当前文件中查找相似行) + +### 补全菜单 +1. `c-n``c-p` 上下移动 +2. `c-y` 确认 +3. `c-e` 退出