Linux
Linux的是类Unix体系,作者是Linus,也是git的作者。符合GPL(General Public License)就可以Linux的利用、修改、再发布。
Linux四部门:
- 内核:驱动、内存管理、进程管理、文件体系、网络协议栈…。作用:管理硬件和提供最根本的体系服务
- 体系库:libc(C标准库)、libm(数学库)、libdl(动态链接库)、libpthread(线程库)、第三方库…。作用:提供常用函数和接口供开辟利用。
- shell:用户利用Linux的接口
- 应用程序:Google、Vim、Git、MySQL、Nginx
Linux的发行版还包罗包管理器(apt\yum)、GUI、体系工具等,比如Ubuntu(个人用户)、Debian、CentOS、Kali(网络安全和渗透测试)
安装Linux:
- 虚拟机工具:VMware、VirtualBox、Hyper-V(window的WSL)、Multipass
- Docker
- 云服务器
Linux根目录:
- bin、sbin:可实行二进制文件
- home、root
- usr、opt、etc、
- lib\lib32\lib64、dev、mnt
- boot、sys、proc
- var、temp
Vim
一般服务器没有图形界面,只能利用Vim编辑器。vim是vi的提升版本(improved)。apt install vim -y
下令模式:
- a\A i\I o\O 表现进入插入模式,: 表现进入尾行模式。插入模式、尾行模式按ESC进入下令模式。
- 移动光标:h j k l 表现左下上右;ctrl + f/b/d/u 表现下页、上页、下半页、上半页;^ $表现行首、行末。gg G 3g 表现首行、尾行、第三行。:3 表现第三行。
- 3yy 表现复制三行;3dd 表现删除三行,D 表现清空本行;3p 表现复制三次粘贴板上的内容。
- ctrl + r 表现撤回,u 表现重做。
行末模式:
- 查找:/hello | ?hello 表现向下、向上查找。n | N 表现下一个、上一个。/hello\c 表现无视巨细写
- 替换::2,5s/hello/world/g 表现2,5行,g表现此行全部。:s/hello/world 表现此行第一个替换。:%s/hello/world 表现每行第一个替换。
还有~\.vimrc 文件:可以设置一些常用的
- set nu # set nonu
- syntax on
- set ic # 忽略大小写
复制代码 tip:vimrc中rc表现run commands。
常用下令
- ls -haltri # i:inode节点、t:time、r:reverse
- echo "hello world" > hello.txt # 覆盖文件之前的内容
- echo "second" >> hello.txt # 追加文件内容
- touch hello.txt # 创建文件、更新文件时间
- cat hello.txt
- ln -s hello.txt hello_soft.txt # 软连接
- ln hello.txt hello_hard.txt # 硬连接
- # 硬连接:文件; 软连接:文件或目录
- # 权限
- chmod u+x hello.txt # ugoa +- rwx
- chmod 777 hello.txt # 等效
- chmod root:root file # 修改 所有者:所属组
- mkdir dir # 删除空目录 rmdir dir
- mkdir -p dir1/dir2 # rm -r dir1。linux删除不可逆
- cp -r dir1 dir_copy
- mv hello.txt dir/hello_move.txt
- date whoami pwd tree
- du # 目录
- df -h # 磁盘
- which ls
- # 安装jdk1.8(java8)
- apt list | grep jdk
- sudo apt install openjdk-8-jdk
- java -version
- # 解压
- tar -xvzf file.tgz
复制代码 inode:文件类型、权限、所有者、文件巨细、时间戳、数据块指针。
下令
- ps -ef # e表示所有 f表示信息
- # 其中tty表示Teletypewriter, tty1,tty2表示物理终端界面; ?表示没有终端相连
- # 文件和进程的关系
- lsof -u root -p 1234 # 打开文件list,root中进程为1234所打开的文件
- lsof file # 哪些进程在使用file
- lsof -i :80 # 查看80端口的进程
- lsof -i tcp # 或者udp
- # FD文件描述符: cwd/rtd/dir/txt/NOFD/mem/pipe/socket/chr/blk
- # TYPE: REG(常规文件)DIR(目录)CHR(字符设备)
复制代码 Shell
脚本的作用:定时处理(比如定时清理、定时备份)、批处理…
Shell种类:sh、bash(默认)、csh、ksh、zsh、powershell。可以cat /etc/shells 查看。
.profile 和 .bashrc:用户打开bash前会利用这两个文件进行初始化环境。设置之后利用. bashrc 或 source .bashrc
/etc/bash 下的文件是对所有效户都有效。
环境变量
- echo $SHELL # 默认bash
- echo $HOME
- echo $PATH
- echo $0 # 表示当前的shell解释器。默认bash
- export name=adair # 在运行的shell中就可以获取
复制代码 常用的$:
- $0、$1、 2 、 2、 2、#:表现文件名、第一个参数、第二个参数、参数个数
- ∗ 、 *、 ∗、@:前者表现作为团体;后者表现按参数传递
- ? 、 ?、 ?、 、 、 、!:表现最后一个下令返回的结果;表现此进程PID;最后一个背景下令的PID
if中的数字比较:eq、ne、lt、le、gt、ge。
if中的字符串比较[[ "$str1" == "$str2" ]]:!=、>、== *、=~、-z、-n
举个例子
- #!/bin/bash # 默认解释器
- is_prime() {
- local num=$1 # 局部变量必须使用local,否则为全局变量
- if [ $num -lt 2 ]; then
- return 1
- fi
- for ((i=2; i*i<=num; i++)); do
- if [ $((num % i)) -eq 0 ]; then
- return 1
- fi
- done
- return 0
- }
- read -p "输入数字:" number
- if ! [[ "$number" =~ ^[0-9]+$ ]]; then # 正则表达式符
- echo "no number"
- exit 1
- fi
- if is_prime $number; then # 函数返回0表示OK
- echo "$number 是素数"
- else
- echo "$number 不是素数"
- fi
复制代码 猜数字
- #!/bin/bash
- # 等效 $(($RANDOM%10+1))
- number=$(shuf -i 1-10 -n 1) # 也可以使用反引号
- echo "随机数为$number"
- while true; do
- echo "输入猜的值"
- read guess
- if [[ $guess -eq $number ]]; then
- echo "对了, 请选择是否继续y/n"
- read choice
- if [[ $choice = "y" ]] || [[ $choice = "Y" ]]; then
- number=$(($RANDOM % 10 + 1))
- echo "随机数为$number"
- continue
- else
- break
- fi
- elif [[ $guess -lt $number ]]; then
- echo "小了"
- else
- echo "大了"
- fi
- done
复制代码 管道:
如果输入bash confirm.sh,则会一直循环输入。可以直接yes | bash confirm.sh
- #!/bin/bash
- for ((i=0; i<3; i++)); do
- read -p "输入y|n" flag
- echo "i=$i flag=$flag"
- if [ "$flag" == "y" ]; then
- continue
- fi
- done
复制代码 shell也可以结合:
- grep awk sed 等文本处理
- 函数和数组等高级特性。
- 体系管理和监控
RegEx
根本字符匹配:.、[ ]、[^ ]、|、
字符类:\d、\w、\s、\D、\W、\S。定位符:^、$、\b、\B、
量词:?、+、*、{n}、{n,m}、{n,}。贪心匹配:ab{3,}、ab{3,}?
旗帜:i、m、s、g、
分组:(abc)、(?:abc)
前瞻:dog(?=cat)、dog(?!cat)。后顾:(?<=cat)dog、(?<!cat)dog
前面的字符都是有特定意义的,如果需要这个字符本身,需要进行转义。但是转义字符同样需要转义\\。
- 基本类型:^$. [1-8B-Yc-x] [^] | \d \w \b \s \大写
- 量词:? + * {n} {n,m} {n,} {n,}?
- 前瞻:dog(?=cat) dog(?!cat) 后顾:(?<=cat)dog (?<!cat)dog
- 分组:(abc) (?:abc)。\1
- 旗帜:i\g\s\m
复制代码 部门表明:
- . 匹配除\n 的任意字符,s 让 . 也可匹配\n
- ^$ 表现文本开始和竣事。m 让 ^$ 表现每行开始和竣事。
- \b :比如\b\d+\b 匹配 %300 而不是 s300
其他版本的RE:
- POSIX根本的BR、扩展的ERE。
- 其他版本的比如Python、Java、JS等。具体环境看文档。
拓展结合:
Git
版本控制体系:会合式(比如:SVN)、分布式(比如Git)
Git的利用方式:下令行、GUI、IDE插件/扩展。
git设置:
- # system 系统配置/etc/gitconfig:对所有用户生效。global 全局配置~/.gitconfig:所有仓库生效。 不带范围.git/config:默认此仓库
- git config --global user.name "adair"
- git config --global user.email "123@qq.com"
- git config --global credential.helper store # 存储密码,不用git push每次都要输入密码
- git config --global --list # 查看属性
复制代码 .gitignore的内容:
- 中间文件大概结果文件,class文件\o文件
- log\temp
- user\password、Token等
- .a # 忽略所有a类型文件
- !lib.a # 不包括lib.a
- /TODO # 忽略根目录下的TODO文件
- build/ # 忽略任何目录的bulid文件夹
- doc/*.o # 忽略doc当前目录下o
- doc/**/*.class # 忽略doc所有下的class
复制代码 不外项目都有相应的模板,不消本身写。https://github.com/github/gitignore
.git/ 文件夹
- config:设置的信息,core、user、branch( -a)
- refs/ (分支):heads/ (本地分支);remotes/(远程);tags/
- index:暂存区指针; HEAD: 版本库中。 指向object/:里面都是对象
- logs/ :HEAD(git log的内容);refs/:相应git branch -a其他所引用的内容
创建堆栈:
- # 本质都是有.git才是仓库。否则就是个普通文件夹
- git init # 把当前文件夹为git仓库
- git init local-git # 创建文件夹local-git为git仓库
- git clone url # 克隆
- git clone git@github.com:name/repo.git
- git clone git@192.168.8.242:v40_7.1.git
复制代码 添加和提交
- # 工作区、暂存区、本地库。push 远程库
- ls # 工作区ls
- git ls-files # 暂存区ls
- git status # 状态:??(Untracked)、M(modifid)、A(added)、D(deleted)、R(renamed)、U(updated)、
- 修改file # 返回 git restore file \ git checkout file
- git add file # 返回 git restore --staged file \ git reset HEAD(原理) \
- git commit -m "message" # -a -v
- git commit --amend # 补充提交, 可以-m
- git log # --online --graph
复制代码 版本回退
- # 回退之前的版本
- git reset --soft commmitID # 指定commitID,且恢复工作区和暂存区
- git reset --hard commmitID # 指定commitID的,不恢复
- git reset commmitID # 指定commitID,且恢复工作区。默认--mixed
- # 从之前的版本到当前版本
- git reflog # 查看所有的提交的commitID
- # HEAD 当前版本
- # HEAD^ HEAD~ 上一个版本
- # HEAD~2 上两个版本
复制代码 内容对比
- git diff # 工作区 vs 暂存区
- git diff HEAD # 工作区 vs 本地库
- git diff commitID1 commitID2 # 两个版本的比较,
- git diff commitID1 commitID2 file.txt # 只比较file.txt
- # 也可以使用HEAD
复制代码 git diff 分析
- zql@adair-pc:~/git-learn/123$ git diff HEAD
- diff --git a/m1 b/m1 # a/m1: 新版 b/m1: 旧版
- index 0e6c128..83e9726 100644 # 新版和旧版索引(hash) 100普通文件, 644权限
- --- a/m1
- +++ b/m1
- @@ -1,3 +1,4 @@ # 旧版:1,3行。 新版:1,4行
- 123456
- 123
- q
- +123 # +表示新增的
复制代码 删除文件
- git rm file.txt # 综合 rm file.txt(工作区) 和 git rm --cached file.txt(暂存区)
- git mv m1.txt m2.txt # 改名,git status . 出现renamed
复制代码 分支
- git branch # 查看本地分支; -r:remote; -a:all;
- git branch dev # 创建分支。git branch -d dev # 删除分支,没有合并则需要D
- git checkout/switch dev # 切换分支。checkout -b,创建并切换
- # main、dev合并分支,不冲突
- git merge dev # 当前在main,则合并dev分支。并且自动会让你输入message,表示一次提交commitID。
- # main、feat合并分支,冲突
- git merge feat # 此处会把冲突的文件内容合并,重新整理冲突文件。
- git commit -am "zql:conflict merge" # 需要重新提交,产生commitID
- git merge --abort # 表示终止提交
- # rebase
- git rebase dev # 表示以dev为根,把main接到dev上。形成直线历史
- git rebase main # 同理
复制代码 git merge dev冲突
- # 提示冲突,
- <<<<<<< HEAD
- 456
- =======
- 123
- >>>>>>> dev
- # 修改冲突之后在进行git commit
复制代码 通过(github.com gitee.com)账户名和密码的方式克隆remote。
ssh设置,远程克隆到本地:
- cd ~/.ssh # 切换到~/.ssh下
- ssh-keygen -t rsa -b 4096 # rsa类型,4096个bit位数
- # 输入相应的名称比如demo,密码demo
- # 生成demo.pub,密钥demo
- vim config # 增加以下内容
- ```
- Host github.com
- HostName github.com
- PreferredAuthentications publickey
- IdentityFile ~/.ssh/demo
- ```
复制代码
- 把公钥复制到GitHub中。ssh -T git@gitee.com 测试
- 本地创建一个空堆栈,git remote add origin git@github.com:adair-zhang/learn-github.git 关联远程即可。
tip:这样创建空库再关联太慢了,不如clone。
本地推送到远程:
- GitHub中创建一个空堆栈
- 在本地堆栈中进行连接GitHub的空堆栈
- git remote add origin git@github.com:adair-zhang/learn-github.git
- git branch -M main # 强制修改当前名(默认为master),修改为main
- git push # git push -u origin main 第一次推送到远程。main其实是main(本地):main(远程)缩写
- git fetch # 默认git fetch origin main,此时并不在最新的commitID。然后合并git merge
- git pull # 等效fetch + merge。默认是git pull origin main
复制代码 代码托管平台:
- GitHub、gitee、gitlab
- 私有化部署:在本身服务器上部署一个gitlab代码托管平台。可以利用Docker进行部署。
- # 比如my-repo是本地关联到github上。
- git remote add gitlab git@gitlab.com:name/myrepo.git # 本地再次关联到gitlab上
- git remote -v # 可以查看本地关联远程的情况
- git push gitlab main # 推送到gitlab
- git remote add github2 git@github.com:adair-zhang/first-repo.git # 关联其他仓库
- git remote -v # 表示仓库关联的远程信息
复制代码 git的GUI:GitHub Desktop、SourceTree、GitKraken等
也可以在VS code中进行操作:
- windows安装git
- 然后可以利用vs code中的git
git本质
常用下令
拓展设置:
git心得:
- commit之前先review,查看代码是否错误,规范
- 平时开辟test分支,不要在master分支
C语言
丹尼斯创造为了Unix编写。
范围:Unix\Linux\Windows、git\vim、MySQL\Redis、Nginx
静态语言:编译时确定变量类型, C\C++\Java\Rust
动态语言:运行时确定变量类型,Python\JavaScript\Ruby\PHP
编译器:
- GCC:GNU Compiler Collection,包含了C、C++、Objective-C、Ada、Go等多种编译器
- Clang:编译C、C++、Objective-C、Objective-C++的编译器前端。接纳LLVM为后端,在MacOS下利用
安装开辟开辟环境:MinGW,安装后 gcc -v 测试。
IDE:CLion、Code::Blocks
VS code
安装好MinGW中的gcc。vs code中不提供编译器。
vs code中然后再增长扩展中,Code Runner 就可以直接运行C的源码了
根本语法
数据类型:
- 根本数据类型:short、int、long、long long、char、float、double
- 派生数据类型:数组、指针、结构体、摆列、共用体、void
- #define MAX 100 // 宏定义
- int num; // 全局变量,静态变量int默认0
- int main(){
- int age; // 不赋值,则默认内存的随机值
- const double PI = 3.14; // const表示常量
- }
复制代码 tip:sizeof(long)在win中始终是4,linux中sizeof(long)为4(32位体系),为8(64位体系)
goto:
- int main() {
- for (size_t i = 0; i < 3; i++) {
- printf("%d\n", i);
- if(i == 1) goto out;
- }
- out:
- printf("hello\n");
- }
复制代码 指针
- int main() {
- int a = 300;
- int *p = &a;
- printf("a = %d\n", a);
- printf("p = %p\n", p);
- printf("*p = %d\n", *p);
- printf("p + 1 = %p\n", p+1); // 地址+4字节
- int **p2 = &p; // 指向指针的指针。
- printf("p2 = %p\n", p2);
- printf("*p2 = %p\n", *p2); // 为p的地址
- printf("**p2 = %d\n", **p2);
- }
复制代码 数组
- int main() {
- int arr[5] = {1, 2, 3, 4}; // 默认初始值为0
- int *p = arr;
- *p = 10; // 修改a[0] = 10
- printf("*p = %d\n", *p); // a[0]值
- // +1表示指向下一个元素。sizeof(int)=4,所以加4。如果是double,加8
- p += 1;
- printf("*p = %d\n", *p); // a[1]值
- // 二维数组
- int b[3][4] = {
- {1, 2, 3, 4},
- {1, 2, 3, 5},
- {1, 2, 3, 6}
- };
- }
复制代码 堆栈
- int main() {
- // 栈内存:比较小,几M ~ 几十M
- int a = 1;
- int b = 2;
- int c = func(a,b);
- // 堆内存:很大,可以申请使用
- int *p = (int *)malloc(sizeof(int));
- *p = 100;
- printf("*p = %d", *p);
- free(p); // 释放p所指空间,防止内存溢出
- p = NULL; // 防止野指针。
- }
复制代码 函数
- // Demo1: 函数声明。项目开发中,则会声明函数在头文件,实现函数则文件\库中。
- int add(int a, int b); // 声明。也可以int add(int, int)
- //或者,直接把实现体放到前面
- int main() { }
- int add(int a, int b){
- return a+b;
- }
- // Demo2: 函数指针。项目开发中,实现一个回调函数,就把函数指针作为参数传递给另外一个函数,在此使用指针来执行此函数,比如事件处理或消息传递。
- #include <stdio.h>
- int add(int a, int b){
- return a+b;
- }
- int substract(int a, int b){
- return a-b;
- }
- typedef int (*Operation)(int, int);
- int main() {
- // 等效 int (*p)(int, int) = add;
- Operation p = substract;
- printf("%d\n", p(3,4));
- }
复制代码 static
- void test() {
- static int a = 0;
- a += 1;
- printf("a=%d\n", a);
- }
- int main() {
- test(); // print a=1
- test(); // print a=2
- }
- // static修饰全局变量和函数时:表示只能在当前文件使用,用于模块封装,防止命名冲突
复制代码 string
- #include <string.h> // 引入头文件
- int main() {
- // 字符串本身就是字符数组,也可以使用指针表示。
- char a[20] = "hi"; // 等效{'h', 'i', '\0'};
- char *b = "hello";
- printf("%s\n", a);
- printf("%s\n", b+1); // 输出:ello
- // 字符串函数:strcpy\strcmp\.\strncat\strncpy\strncmp
- strcat(a, b);
- printf("%s\n", a);
- }
复制代码 结构体struct
- typedef struct student {
- char name[20];
- int age;
- float score;
- }Student;
- int main() {
- struct student stu1 = {"Tom", 18, 60.1}; // Student stu1 =...
- strcpy(stu1.name, "Tommy");
- stu1.age = 19;
- printf("%s, %d, %f", stu1.name, stu1.age, stu1.score);
- }
复制代码 共用体union
- union student {
- // 两个变量共用一个地址。
- char name[10];
- int age;
- };
- int main() {
- union student stu1;
- stu1.age = 97;
- printf("%s, %d", stu1.name, stu1.age); // a, 97
- }
复制代码 摆列enum
- enum day { // 下面的属性默认从0开始
- MON,
- TUE,
- WED
- };
- int main() {
- enum day day1 = TUE;
- printf("%d", day1); // 1
- /**
- * 亦可
- * enum day {
- MON = 3,
- TUE,
- WED
- };
- */
- }
复制代码 库引用
- // a.h
- #ifndef A_H // 解决库重复引用导致的重复定义问题。
- #define A_H
- int a = 1;
- #endif
- // b.h
- #include "a.h"
- // hello.c
- #include <stdio.h>
- #include "a.h"
- #include "b.h"
- int main() {
- printf("hello %d\n", a); // 如果没有上面的条件编译。报错:重复定义
- }
复制代码 编译链接过程:
- 预处理:
- 编译阶段:源文件转为汇编代码
- 语法检查、类型检查
- 代码优化:常量表达式直接计算出来、删掉无用代码
- 汇编阶段:汇编代码转为机器码(目标文件 .o )
- 链接阶段:把所有目标文件利用的库文件链接起来,形成可实行文件。分为静态链接和动态链接。
- 静态链接:会将库默认直接嵌入到可实行文件中,运行时不再依赖外部库。
- 动态链接:程序运行时加载库。多个程序可以共享一个动态库,节省资源。
库:已经编译好的文件
- 静态库:.a (Linux中)、.lib (win中),并不是只用于静态链接。
- 动态库:.so (Linux中)、.dll (win中),并不是只用于动态链接。
有空再看:
特性CC++C#Objective-CObjective-C++编程范式过程化编程面向对象、过程化面向对象面向对象面向对象 + 泛型编程内存管理手动管理手动管理自动垃圾回收ARCARC + 手动管理平台跨平台跨平台Windows、跨平台macOS、iOSmacOS、iOS + 跨平台运行时静态编译静态编译静态编译动态运行时动态运行时模板编程无支持模板编程无无支持模板编程利用场景操作体系、嵌入式应用程序开辟、游戏企业应用、Web 开辟macOS、iOS 开辟混淆 C++ 和 Objective-C典型应用操作体系、硬件驱动高性能应用、游戏Web 应用、游戏开辟iOS/macOS 应用开辟iOS/macOS 应用开辟 C:如果你需要控制硬件或开辟底层体系,C 是最符合的选择。
C++:如果你需要高效且机动的面向对象编程,而且涉及到复杂的数据结构或体系性能要求,C++ 更为符合。
C#:如果你开辟 Windows 应用、Web 应用或跨平台应用,C# 是一个非常现代和高效的选择。
Objective-C:如果你在开辟 iOS 或 macOS 应用,Objective-C 是一个必备语言,尤其是在 Swift 出现之前。
Objective-C++:如果你需要结合 C++ 的高效性和 Objective-C 的面向对象特性,尤其是在需要同时调用 C++ 库和 Objective-C 库时,可以利用 Objective-C++。
高级特性
- 如何编译makefile
- gdb调试器
- 栈溢出毛病
编译运行机制
开辟环境
常用工具
利用技巧
Makefile
构建工具make中的makfile相当于 maven中 pom.xml ,Node.js(npm) 中 package.json。
安装:
- choco install make // win安装: 位置C:\ProgramData\chocolatey\bin\make.exe
- sudo apt install make // linux
复制代码 根本语法规则:
- target: soureces
- rules
- ...
复制代码 Demo:
目前有源文件
- // message.h
- void message();
- // message.c
- #include <stdio.h>
- void message() {
- printf("hello world\n");
- }
- // hello.c
- #include "message.h"
- int main() {
- message();
- }
复制代码 makefile
- .PHONY: clean all
- CFLAGS = -Wall -g -O2
- target = hello world
- object = hello.o message.o
- # source = hello.c message.c
- all: hello world
- @echo "all done"
- $(target): $(object)
- gcc $(CFLAGS) $(object) -o $@
- %.o: %.c
- gcc $(CFLAGS) -c $< -o $@
- clean:
- rm -f *.o hello
复制代码 表明:
- .PHONY 表明 make clean/all 后面接的是命令,而不是文件(比如有个clean文件)
- CFLAGS 设置编译选项,-Wall所有警告,-g调试,-O2中度优化
- $(target): $(object)
- gcc $(CFLAGS) $(object) -o $@
- 当所需$(object)没有时,向下查找生成目标。
- %.o: %.c
- gcc $(CFLAGS) -c $< -o $@
- 所有的c转为o: message.o 和 hello.o,
- message.o: message.c
- gcc $(CFLAGS) -c message.c -o message.o
-
- makefile中自动变量:$@ 表示target; $< 表示源文件第一个参数
复制代码 CMake
makefile 无需手动编写,CMake自动天生,设置文件为 CMakeLists.txt 文件
- sudo apt install cmake // linux安装cmake
复制代码 vs code利用cmake
- # 常用配置。手写
- cmake_minimum_required(VERSION 3.10)
- project(HelloWorld)
- set(SOURCES hello.c message.c)
- add_executable(hello ${SOURCES})
复制代码
- 实行 cmake 下令,自动辨认CMakeLists.txt,并天生Makefile文件。
- 仍旧实行下令:make 自动天生可实行文件hello,清理 make clean
Maven
Maven 在设置文件 pom.xml (Project Object Model)
- 管理依赖,将依赖jar和依赖的依赖jar的导入项目。手动导入依赖麻烦、大概冲突。
- 构建管理:java源文件 转为 class字节码,然后打包成可实行的jar大概war。实行 构建、打包、部署等工作。
Maven堆栈:
- 本地堆栈:~/.m2/repository/。本地没有则会去私服和中央堆栈中查找并下载到本地,提高效率。
- 私服堆栈:公司或构造的堆栈,可以私用Nexus构建。非必须的
- 中央堆栈:Maven官方堆栈
安装:windows中,官网下载bin二进制压缩包,设置环境变量 MAVEN_HOME 和 path。mvn -v 查看版本。
- # linux中安装
- sudo apt install maven # 自动配置环境变量。
- # 如果使用解压包,则.bashrc下
- export MAVEN_HOME=../..
- export PATH=$MAVEN_HOME/bin:$PATH
复制代码 设置.\config\settings.xml
- <!--配置本地仓库地址-->
- <localRepository>D:\environment\apache-maven-3.9.6\mvn_resp</localRepository>
- <!--配置中央仓库镜像,由于Maven在国内访问慢-->
- <mirror>
- <id>alimaven</id>
- <mirrorOf>central</mirrorOf>
- <name>aliyun maven</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public</url>
- </mirror>
- <!--配置对应jdk,可以不配-->
- <profile>
- <id>jdk-1.4</id>
- <activation>
- <jdk>1.4</jdk>
- </activation>
- <repositories>
- <repository>
- <id>jdk14</id>
- <name>Repository for JDK 1.4 builds</name>
- <url>http://www.myhost.com/maven/jdk14</url>
- <layout>default</layout>
- <snapshotPolicy>always</snapshotPolicy>
- </repository>
- </repositories>
- </profile>
复制代码 demo
Linux中创建demo:
- # 创建mvn项目
- mvn archetype:generate -DgroupId=net.geek -DartifactId=maven-sample -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
- # 编译,target下生成class字节码
- mvn compile
- # 打包:maven-sample-1.0-SNAPSHOT.jar
- mvn package
- # 运行项目 cp:classpath。输入:Hello World!
- java -cp target/maven-sample-1.0-SNAPSHOT.jar net.geek.App
复制代码 IDEA中创建demo
- 依然选择maven-archetype-quickstart,然后选择GroupId,ArtifactId。即可创建成功
- 可以在IDEA的settings中修改Maven的home和设置
从IDEA中可以看到maven的各种生命周期,各种生命周期都是有对应的插件实现的,插件也就是java类,maven本质上就是通过接口调用这类来实现生命周期,而且default中生命周期有顺序的,直接实行后一个下令,会自动实行之前的下令:
- clean
- default:validate; compile; test; package; verify; install(将jar安装到本地堆栈); deploy(将jar部署到公司的私服堆栈);
- site:天生网站的信息和文档为静态网站。会天生index.html可以在浏览器中查看
tip:install的位置,比如D:\environment\apache-maven-3.9.6\mvn_resp\net\hour\mvn-exapmle\1.0-SNAPSHOT\mvn-exapmle-1.0-SNAPSHOT.jar。(net\hour包名、mvn-exapmle项目名、1.0-SNAPSHOT版本)
比较常用下令:
- mvn clean package
- mvn clean install
pom.xml中利用GAV(groupId artifactId version)标定一个jar包,version中snapshot (快照,开辟中)和 release(开辟完)
- <!-- groupId不爆红说明有这个组,下面同理 -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>6.2.1</version>
- </dependency>
- <!--依赖传递: 直接依赖context,它会引用间接依赖core\aop\beans等-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>6.2.1</version>
- </dependency>
复制代码 依赖范围:
- <dependencies>
- <!--test: 只用于测试单元的源码,不会被正式源码引用,不会被打包-->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <!--compile默认:编译和运行都需要-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>6.2.1</version>
- <scope>compile</scope>
- </dependency>
- <!--provided:编译需要,运行不需。比如lombok简化Setter\Getter-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.34</version>
- <scope>provided</scope>
- </dependency>
- <!--servlet运行时Tomcat或其他Web容器会提供,所以也是provided-->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>4.0.1</version>
- <scope>provided</scope>
- </dependency>
- <!--runtime: 运行时需要,编译无需,比如jdbc驱动-->
- <dependency>
- <groupId>org.postgresql</groupId>
- <artifactId>postgresql</artifactId>
- <version>42.7.4</version>
- <scope>runtime</scope>
- </dependency>
- <!--system: 只能在本地电脑使用,因为源码放在git中,而git一般忽略jar,
- 除非其他环境手动引入这些jar
- 最好引入到私服仓库,其他成员只用pom即可-->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>system</scope>
- <systemPath>${basedir}/lib/junit-3.8.1.jar</systemPath>
- </dependency>
- </dependencies>
复制代码 父子工程:多个模块的依赖管理
- 创建maven-parent项目,同上demo。把此项目src删除。
- 在父类项目中,创建多个module,并定名为child-a、child-c、child-d、
- 可以在IDEA右侧栏中看到相应模块。
- <!--maven-parent 的 pom.xml-->
- <groupId>net.geek</groupId>
- <artifactId>maven-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- <!--pom值: 表示父类-->
- <packaging>pom</packaging>
- <modules>
- <module>child-a</module>
- <module>child-b</module>
- <module>child-c</module>
- </modules>
- <!--child-a 的 pom.xml-->
- <parent>
- <groupId>net.geek</groupId>
- <artifactId>maven-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>child-a</artifactId>
- <!--表示jar,还可以war-->
- <packaging>jar</packaging>
复制代码 maven-parent 的 pom.xml:这样dependencies由于无条件继承,父子耦合高
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>6.2.1</spring.version>
- </properties>
- <!--child-* 无条件继承-->
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
复制代码 低落耦合度:
- <!--maven-parent 的 pom.xml:子类不继承-->
- <!--properties 可以定义通用的属性,以便后面引用-->
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>6.2.1</spring.version>
- </properties>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <!--child-a 的 pom.xml:继承,默认version为父类的-->
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- </dependency>
- </dependencies>
复制代码 依赖冲突:比如A和B,A引入D,B通过引入C再引入D?大概A和B同时引入D?D是不同的版本,到底用谁人版本。
- maven本身有第一的规则:最短路径优先,先声明优先。
- 开辟者:通过exclusions标签清除依赖、optional标签标记可选依赖。
spring-jdbc版本此时就会冲突,此时child-a由于路径一样,则先声明优先,利用child-b中的spring-jdbc的版本。
- <!--child-a 的 pom.xml,引入child-b和 child-c -->
- <dependency>
- <groupId>net.geek</groupId>
- <artifactId>child-b</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>net.geek</groupId>
- <artifactId>child-c</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- <!--child-b 的 pom.xml-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>6.2.1</version>
- </dependency>
- <!--child-c 的 pom.xml-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>6.2.1</version>
- </dependency>
复制代码 如果开辟者想利用child-c中的spring-jdbc版本
- // 方式一:修改child-a的pom.xml,exclusions排除
- <dependency>
- <groupId>net.geek</groupId>
- <artifactId>child-b</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>net.geek</groupId>
- <artifactId>child-c</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- // 方式二:修改child-b的pom.xml, optional标签为ture表示可选(非必须的 )
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>6.2.1</version>
- <optional>true</optional>
- </dependency>
复制代码 Nexus
Nexus用于私服堆栈。
安装和利用:
- win中下载对应压缩包并解压,
- 通过./etc/nexus-default.properties知道端口为8081
- 开启服务nexus.exe/run ,通过浏览器 localhost:8081 访问。
Nexus网页介绍:
- 默认有maven-releases(本地hosts)、maven-snapshots(本地hosts)、maven-central(中央堆栈)、maven-public(包含三者)、
- 开辟者也可创建其他堆栈,nexus不仅支持maven2;也支持docker,npm,yum之类的包文件
从Nexus下载:
- <!-- ./conf/settings.xml 配置mirror和server -->
- <mirror>
- <id>maven-nexus</id>
- <mirrorOf>*</mirrorOf>
- <name>nexus私服</name>
- <url>http://localhost:8081/repository/maven-public/</url>
- </mirror>
- <server>
- <id>maven-nexus</id>
- <username>admin</username>
- <password>admin</password>
- </server>
复制代码 上传Nexus,即deploy:
- <!-- pom.xml-->
- <version>1.0.0</version>
- <!-- 配置nexus的id和具体仓库的url -->
- <distributionManagement>
- <!-- 会根据version值是否有SNAPSHOTS,自动决定是releases还是snapshots仓库 -->
- <repository>
- <id>maven-nexus</id>
- <url>http://localhost:8081/repository/maven-releases/</url>
- </repository>
- <snapshotRepository>
- <id>maven-nexus</id>
- <url>http://localhost:8081/repository/maven-snapshots/</url>
- </snapshotRepository>
- </distributionManagement>
复制代码 tip:默认不许重复上传正式版本,比如1.0.0,第二次进行deploy就会报错。
import依赖范围
Nginx
最常用的Web服务器。一个Master进程管理多个Work进程。
安装方式:
- 包管理器:linux通过apt、win通过choco、mac通过brew
- 编译安装:下载对应C语言源码,预编译、编译、安装的方式
- 利用Docker:docker pull nginx
安装好之后,实行nginx.exe 即可启动服务,在浏览器中 localhost 即可访问,
nginx -s quit/stop 制止服务
nginx.conf为设置文件,规定了一些work数量,文件类型等。nginx -s reload 修改之后重新加载(signal)
hexo
需要装hexo,条件需安装 Node.js和 git
- npm install -g hexo-cli;
- hexo init blog;
- cd blog;
- npm install; # 安装hexo默认的依赖
- hexo g; # generate 生成静态文件
- hexo s; # server 本地开发服务器,通常在localhost:4000
- # 此时只是hexo的服务
- # 把hexo生成的blog部署的nginx:把blog/public/* 复制到nginx的html下即可。
复制代码 反向代理
先安装go:choco install go 默认C:\Program Files\Go\bin
main_8000.go;然后创建内容雷同的main_8001.go; main_80001.go;
- package main
- import (
- "fmt"
- "net/http"
- )
- func handler(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "Hello, World!8000")
- }
- func main() {
- // 设置处理请求的路由
- http.HandleFunc("/", handler)
- // 启动服务器,监听8080端口
- fmt.Println("Server is running on http://localhost:8000")
- if err := http.ListenAndServe(":8000", nil); err != nil {
- fmt.Println("Error starting server:", err)
- }
- }
复制代码 启动服务
- go run main_8000.go; # 其他两个同理
- # 浏览器中可以localhost:8000 访问
复制代码 设置反向代理nginx.conf:通过 localhost/app 即可轮训访问8000\8001\8002,
- http{
- ...
- upstream backend {
- ip_hash;
- server 127.0.0.1:8000 weight=3;
- server 127.0.0.1:8001;
- server 127.0.0.1:8002;
- }
- server {
- ...;
-
- location /app {
- proxy_pass http://backend;
- }
- }
- ...
- }
复制代码 负载平衡:weight=3表现大部门在此服务器;ip_hash表如今一台服务器比如只在8000,解决session互传
HTTPS设置
HTTP + SSL = HTTPS。默认http端口为80,https端口为443。一些主流的云平台可以申请到免费的ssl(Secure Sockets Layer)证书,也可以通过自签名天生证书和密钥,已经被TLS(Transport Layer Security)所取代。
安装openssl下令:choco 。默认C:\Program Files\SSL\bin
- cd ssl # 创建一个ssl文件夹
- #
- openssl genpkey -algorithm RSA -out server.key
- openssl req -new -key server.key -out server.csr # 输入对应的信息,比如国家,公司,邮箱...
- openssl x509 -req -in server.csr -signkey server.key -out server.crt
复制代码 nginx.config
- # 解决重定向问题
- server {
- listen 80;
- server_name localhost;
- # 重定向到 HTTPS 版本
- return 301 https://localhost$request_uri;
- }
- server {
- listen 443 ssl; # 监听 443 端口,并启用 SSL
- server_name localhost; # 你的域名
- ssl_certificate D:/environment/nginx-1.27.3/ssl/server.crt; # 证书文件
- ssl_certificate_key D:/environment/nginx-1.27.3/ssl/server.key; # 私钥文件
- ssl_protocols TLSv1.2 TLSv1.3; # 推荐的 SSL/TLS 协议版本
- # ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256'; # 强加密套件
- ssl_prefer_server_ciphers on; # 强制使用服务器配置的加密算法
- # ssl_dhparam /path/to/dhparam.pem; # Diffie-Hellman 参数,用于增加安全性,确保生成该文件(见后文)
- ssl_session_cache shared:SSL:10m; # 缓存会话以提高性能
- ssl_session_timeout 1d; # 设置 SSL 会话超时
- # listen 80;
- # server_name localhost;
- #charset koi8-r;
- location /app {
- proxy_pass http://backend;
- }
- }
复制代码 然后 https://localhost
虚拟机
demo1:
可以在一台服务器部署多个站点,比如一个server 就相当于一个服务器
为了方便表现nginx.conf 的 server 设置在servers/local.conf 中
- # nginx.conf
- http {
- ...;
- include servers/*.conf;
- }
- # 新建servers/local.conf,把nginx.conf 中的server拷过来
- server{
-
- }
复制代码 demo2:
- npm create vite # 选择Vue和TypeScript
- npm install # 安装依赖node_modules/
- npm run build # 生成dist/ 下面有index.html
复制代码 同样把这个网站部署到nginx上
- server {
- listen 5173;
- server_name localhost;
- location / {
- root D:/environment/nginx-1.27.3/vuedemo/dist;
- index index.html index.htm;
- }
- }
复制代码 然后 https://localhost:5173
MySQL
数据库DB是按照数据结构进行构造、存储、管理数据的堆栈,DBMS是数据库管理体系,常见RDBMS有MySQL
安装:
- 下令行,choco | apt
- win在官网下载安装包
- docker pull mysql
需要进行一些设置
- # 创建文件在项目下 my.init
- [mysqld]
- basedir=D:\environment\mysql-8.0.33-winx64\
- datadir=D:\environment\mysql-8.0.33-winx64\data\
- port=3306
- # 输入命令
- mysqld --initialize # 初始化mysql,会生成data
- mysqld --install
- net start mysql # 启动mysql服务
- mysql -u root -p # 登陆,密码在data/*.err
- alter user 'root'@'localhost' identified with mysql_native_password by 'newpassworld';
复制代码 常用下令
- show databases;
- use mysql;
- show tables;
- select * from tables_priv;
复制代码 Redis
MongoDB
Docker
Kubernetes
堡垒机
Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境:
- 异步和事件驱动:非阻塞 I/O 模型,实用于大量并发
- 单线程
- 模块化,内置模块(fs、http、path)
安装:
- 下载Node.js安装包到environment\目录下。node -v | npm -v 测试
- 目录下创建文件夹node_cache,node_global。默认
- npm config set prefix "...\Nodejs\node_global"
- npm config set cache "...\Nodejs\node_cache"
- npm config get registry # 配置国内镜像
- npm config get prefix
- npm config list
复制代码
- 体系变量,NODE_PATH为…\Nodejs\node_global\node_modules。并在PATH中添加%NODE_PATH%
- 用户变量,…\AppData\Roaming\npm修改为…\Nodejs\node_global
- 测试:npm install express -g 安装在\node_global\node_modules\express
Windows
下令
- tasklist | findstr "nginx" # 查找任务
- taskkill /f /t /im nginx.exe # 终止任务,f强制,t递归子进程,im映像名称
- # net命令:网络和系统管理
- net stop nginx # 先停止系统的nginx服务,否则停止nginx,也会重新启动
- # netstat:查看端口
- netstat -ano # a:all n:number o:pid
复制代码 常见问题
端口占用
- # 8080 端口被占用
- netstat -ano | findstr "8080" # 查找端口对应的pid(1234)
- tasklist | findstr "1234" # 根据pid找到任务,
- # 终止任务
- tasklist /f /t /pid 1234
- tasklist /f /t /im demo.task
复制代码 tps://localhost:5173`
MySQL
数据库DB是按照数据结构进行构造、存储、管理数据的堆栈,DBMS是数据库管理体系,常见RDBMS有MySQL
安装:
- 下令行,choco | apt
- win在官网下载安装包
- docker pull mysql
需要进行一些设置
- # 创建文件在项目下 my.init
- [mysqld]
- basedir=D:\environment\mysql-8.0.33-winx64\
- datadir=D:\environment\mysql-8.0.33-winx64\data\
- port=3306
- # 输入命令
- mysqld --initialize # 初始化mysql,会生成data
- mysqld --install
- net start mysql # 启动mysql服务
- mysql -u root -p # 登陆,密码在data/*.err
- alter user 'root'@'localhost' identified with mysql_native_password by 'newpassworld';
复制代码 常用下令
- show databases;
- use mysql;
- show tables;
- select * from tables_priv;
复制代码 Redis
MongoDB
Docker
Kubernetes
堡垒机
Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境:
- 异步和事件驱动:非阻塞 I/O 模型,实用于大量并发
- 单线程
- 模块化,内置模块(fs、http、path)
安装:
- 下载Node.js安装包到environment\目录下。node -v | npm -v 测试
- 目录下创建文件夹node_cache,node_global。默认
- npm config set prefix "...\Nodejs\node_global"
- npm config set cache "...\Nodejs\node_cache"
- npm config get registry # 配置国内镜像
- npm config get prefix
- npm config list
复制代码
- 体系变量,NODE_PATH为…\Nodejs\node_global\node_modules。并在PATH中添加%NODE_PATH%
- 用户变量,…\AppData\Roaming\npm修改为…\Nodejs\node_global
- 测试:npm install express -g 安装在\node_global\node_modules\express
Windows
下令
- tasklist | findstr "nginx" # 查找任务
- taskkill /f /t /im nginx.exe # 终止任务,f强制,t递归子进程,im映像名称
- # net命令:网络和系统管理
- net stop nginx # 先停止系统的nginx服务,否则停止nginx,也会重新启动
- # netstat:查看端口
- netstat -ano # a:all n:number o:pid
复制代码 常见问题
端口占用
- # 8080 端口被占用
- netstat -ano | findstr "8080" # 查找端口对应的pid(1234)
- tasklist | findstr "1234" # 根据pid找到任务,
- # 终止任务
- tasklist /f /t /pid 1234
- tasklist /f /t /im demo.task
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |