GeekHour

Linux

Linux的是类Unix系统,作者是Linus,也是git的作者。符合GPL(General Public License)就可以Linux的使用、修改、再发布。

Linux四部分:

  1. 内核:驱动、内存管理、进程管理、文件系统、网络协议栈…。作用:管理硬件和提供最基本的系统服务
  2. 系统库:libc(C标准库)、libm(数学库)、libdl(动态链接库)、libpthread(线程库)、第三方库…。作用:提供常用函数和接口供开发使用。
  3. shell:用户使用Linux的接口
  4. 应用程序:Google、Vim、Git、MySQL、Nginx

Linux的发行版还包括包管理器(apt\yum)、GUI、系统工具等,比如Ubuntu(个人用户)、Debian、CentOS、Kali(网络安全和渗透测试)

安装Linux:

  • 虚拟机工具:VMware、VirtualBox、Hyper-V(window的WSL)、Multipass
  • Docker
  • 云服务器

Linux根目录:

  1. bin、sbin:可执行二进制文件
  2. home、root
  3. usr、opt、etc、
  4. lib\lib32\lib64、dev、mnt
  5. boot、sys、proc
  6. var、temp

Vim

一般服务器没有图形界面,只能使用Vim编辑器。vim是vi的提升版本(improved)。apt install vim -y

命令模式:

  1. a\A i\I o\O 表示进入插入模式,: 表示进入尾行模式。插入模式、尾行模式按ESC进入命令模式。
  2. 移动光标:h j k l 表示左下上右;ctrl + f/b/d/u 表示下页、上页、下半页、上半页;^ $表示行首、行末。gg G 3g 表示首行、尾行、第三行。:3 表示第三行。
  3. 3yy 表示复制三行;3dd 表示删除三行,D 表示清空本行;3p 表示复制三次粘贴板上的内容。
  4. ctrl + r 表示撤回,u 表示重做。

行末模式:

  1. 查找:/hello | ?hello 表示向下、向上查找。n | N 表示下一个、上一个。/hello\c 表示无视大小写
  2. 替换::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中就可以获取

常用的$:

  1. $0、$1、 2 、 2、 2#:表示文件名、第一个参数、第二个参数、参数个数
  2. ∗ 、 *、 @:前者表示作为整体;后者表示按参数传递
  3. ? 、 ?、 ? 、 、 !:表示最后一个命令返回的结果;表示此进程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也可以结合:

  1. grep awk sed 等文本处理
  2. 函数和数组等高级特性。
  3. 系统管理和监控

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

部分解释:

  1. . 匹配除\n 的任意字符,s. 也可匹配\n
  2. ^$ 表示文本开始和结束。m^$ 表示每行开始和结束。
  3. \b :比如\b\d+\b 匹配 %300 而不是 s300

其他版本的RE:

  1. POSIX基本的BR、扩展的ERE。
  2. 其他版本的比如Python、Java、JS等。具体情况看文档。

拓展结合:

  • grep 和 sed 和 awk

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的内容:

  1. 中间文件或者结果文件,class文件\o文件
  2. log\temp
  3. 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/ 文件夹

  1. config:配置的信息,core、user、branch( -a)
  2. refs/ (分支):heads/ (本地分支);remotes/(远程);tags/
  3. index:暂存区指针; HEAD: 版本库中。 指向object/:里面都是对象
  4. 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配置,远程克隆到本地:

  1. 本地生成公钥密钥。
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
```
  1. 把公钥复制到GitHub中。ssh -T git@gitee.com 测试

  2. 本地创建一个空仓库,git remote add origin git@github.com:adair-zhang/learn-github.git 关联远程即可。

tip:这样创建空库再关联太慢了,不如clone。

本地推送到远程:

  1. GitHub中创建一个空仓库
  2. 在本地仓库中进行连接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

代码托管平台:

  1. GitHub、gitee、gitlab
  2. 私有化部署:在自己服务器上部署一个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中进行操作:

  1. windows安装git
  2. 然后可以使用vs code中的git

git本质

image-20230916102952710

常用命令

image-20230916103020915


拓展配置:

  • post-git

git心得:

  • commit之前先review,查看代码是否错误,规范
  • 平时开发test分支,不要在master分支

C语言

丹尼斯创造为了Unix编写。

范围:Unix\Linux\Windows、git\vim、MySQL\Redis、Nginx

静态语言:编译时确定变量类型, C\C++\Java\Rust
动态语言:运行时确定变量类型,Python\JavaScript\Ruby\PHP

编译器:

  1. GCC:GNU Compiler Collection,包含了C、C++、Objective-C、Ada、Go等多种编译器
  2. 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的源码了

基本语法

数据类型:

  1. 基本数据类型:short、int、long、long long、char、float、double
  2. 派生数据类型:数组、指针、结构体、枚举、共用体、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);	// 如果没有上面的条件编译。报错:重复定义
}

编译链接过程:

  1. 预处理:
    1. 头文件和条件编译、宏定义
    2. 除掉注释
  2. 编译阶段:源文件转为汇编代码
    1. 语法检查、类型检查
    2. 代码优化:常量表达式直接计算出来、删掉无用代码
  3. 汇编阶段:汇编代码转为机器码(目标文件 .o
  4. 链接阶段:把所有目标文件使用的库文件链接起来,形成可执行文件。分为静态链接和动态链接。
    1. 静态链接:会将库默认直接嵌入到可执行文件中,运行时不再依赖外部库。
    2. 动态链接:程序运行时加载库。多个程序可以共享一个动态库,节省资源。

库:已经编译好的文件

  1. 静态库:.a (Linux中)、.lib (win中),并不是只用于静态链接。
  2. 动态库:.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++。


高级特性

  1. 如何编译makefile
  2. gdb调试器
  3. 栈溢出漏洞

编译运行机制

开发环境

常用工具

使用技巧

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

  1. 创建CMakeLists.txt
# 常用配置。手写
cmake_minimum_required(VERSION 3.10)

project(HelloWorld)

set(SOURCES hello.c message.c)

add_executable(hello ${SOURCES})
  1. 执行 cmake 命令,自动识别CMakeLists.txt,并生成Makefile文件。
  2. 依旧执行命令:make 自动生成可执行文件hello,清理 make clean

Maven

Maven 在配置文件 pom.xml (Project Object Model)

  1. 管理依赖,将依赖jar和依赖的依赖jar的导入项目。手动导入依赖麻烦、可能冲突。
  2. 构建管理:java源文件 转为 class字节码,然后打包成可执行的jar或者war。执行 构建、打包、部署等工作。

Maven仓库:

  1. 本地仓库:~/.m2/repository/。本地没有则会去私服和中央仓库中查找并下载到本地,提高效率。
  2. 私服仓库:公司或组织的仓库,可以私用Nexus构建。非必须的
  3. 中央仓库: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

  1. 依然选择maven-archetype-quickstart,然后选择GroupId,ArtifactId。即可创建成功
  2. 可以在IDEA的settings中修改Maven的home和配置

从IDEA中可以看到maven的各种生命周期,各种生命周期都是有对应的插件实现的,插件也就是java类,maven本质上就是通过接口调用这类来实现生命周期,而且default中生命周期有顺序的,直接执行后一个命令,会自动执行之前的命令:

  1. clean
  2. default:validate; compile; test; package; verify; install(将jar安装到本地仓库); deploy(将jar部署到公司的私服仓库);
  3. 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版本)

比较常用命令:

  1. mvn clean package
  2. 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>

父子工程:多个模块的依赖管理

  1. 创建maven-parent项目,同上demo。把此项目src删除。
  2. 在父类项目中,创建多个module,并命名为child-a、child-c、child-d、
  3. 可以在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是不同的版本,到底用那个版本。

  1. maven本身有第一的规则:最短路径优先,先声明优先。
  2. 开发者:通过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用于私服仓库。

安装和使用:

  1. win中下载对应压缩包并解压,
  2. 通过./etc/nexus-default.properties知道端口为8081
  3. 开启服务nexus.exe/run ,通过浏览器 localhost:8081 访问。

Nexus网页介绍:

  1. 默认有maven-releases(本地hosts)、maven-snapshots(本地hosts)、maven-central(中央仓库)、maven-public(包含三者)、
  2. 开发者也可创建其他仓库,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进程。

安装方式:

  1. 包管理器:linux通过apt、win通过choco、mac通过brew
  2. 编译安装:下载对应C语言源码,预编译、编译、安装的方式
  3. 使用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

安装:

  1. 命令行,choco | apt
  2. win在官网下载安装包
  3. 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 运行环境:

  1. 异步和事件驱动:非阻塞 I/O 模型,适用于大量并发
  2. 单线程
  3. 模块化,内置模块(fs、http、path)

安装:

  1. 下载Node.js安装包到environment\目录下。node -v | npm -v 测试
  2. 目录下创建文件夹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
  1. 系统变量,NODE_PATH为…\Nodejs\node_global\node_modules。并在PATH中添加%NODE_PATH%
  2. 用户变量,…\AppData\Roaming\npm修改为…\Nodejs\node_global
  3. 测试: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

安装:

  1. 命令行,choco | apt
  2. win在官网下载安装包
  3. 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 运行环境:

  1. 异步和事件驱动:非阻塞 I/O 模型,适用于大量并发
  2. 单线程
  3. 模块化,内置模块(fs、http、path)

安装:

  1. 下载Node.js安装包到environment\目录下。node -v | npm -v 测试
  2. 目录下创建文件夹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
  1. 系统变量,NODE_PATH为…\Nodejs\node_global\node_modules。并在PATH中添加%NODE_PATH%
  2. 用户变量,…\AppData\Roaming\npm修改为…\Nodejs\node_global
  3. 测试: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	


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/957583.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习golang语言时遇到的难点语法

作者是java选手&#xff0c;实习需要转go&#xff0c;记录学习go中遇到的一些与java不同的语法。 defer defer特性 1. 关键字 defer 用于注册延迟调用。 2. 这些调用直到 return 前才被执。因此&#xff0c;可以用来做资源清理。 3. 多个defer语句&#xff0c;按先进…

一个面向领域的直播平台开源!

面向教育等领域&#xff0c;二开后可以做视频会议等 在线直播平台 基于 Spring Boot 和 SRS 平台功能 视频直播 在线聊天 直播提醒 作业上传和批改 项目介绍了一个基于Spring Boot和SRS的在线直播平台&#xff0c;这个平台具备视频直播、在线聊天、直播提醒以及…

软件测试—— 接口测试(HTTP和HTTPS)

软件测试—— 接口测试&#xff08;HTTP和HTTPS&#xff09; HTTP请求方法GET特点使用场景URL结构URL组成部分URL编码总结 POST特点使用场景请求结构示例 请求标头和响应标头请求标头&#xff08;Request Headers&#xff09;示例请求标头 响应标头&#xff08;Response Header…

Mysql约束(学习自用)

一、概述 注意&#xff1a; 1&#xff09;多个约束之间用空格分开 二、外键约束 三、约束行为

linux-NFS网络共享存储服务配置

1.NFS服务原理 NFS会经常用到&#xff0c;用于在网络上共享存储&#xff0c;这样讲&#xff0c;你对NFS可能不太了解&#xff0c;举一个例子&#xff0c; 加入有三台机器A,B,C&#xff0c;它们需要访问同一个目录&#xff0c;目录中都是图片&#xff0c;传统的做法是把这些 图…

LabVIEW太赫兹二维扫描成像系统

使用LabVIEW设计太赫兹二维扫描成像系统。通过LabVIEW平台开发&#xff0c;结合硬件如太赫兹源、平移台、锁相放大器等&#xff0c;实现了高效、精准的成像功能。系统采用蛇形扫描方式&#xff0c;通过动态调整扫描参数&#xff0c;达到优化成像质量的目的。 ​ 项目背景 在非…

kafka学习笔记6 ACL权限 —— 筑梦之路

在Kafka中&#xff0c;ACL&#xff08;Access Control List&#xff09;是用来控制谁可以访问Kafka资源&#xff08;如主题、消费者组等&#xff09;的权限机制。ACL配置基于Kafka的kafka-acls.sh工具&#xff0c;能够管理对资源的读取、写入等操作权限。 ACL介绍 Kafka的ACL是…

ARM学习(42)CortexM3/M4 MPU配置

笔者之前学习过CortexR5的MPU配置,现在学习一下CortexM3/M4 MPU配置 1、背景介绍 笔者在工作中遇到NXP MPU在访问异常地址时,就会出现总线挂死,所以需要MPU抓住异常,就需要配置MPU。具体背景情况可以参考ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连…

Python----Python高级(正则表达式:语法规则,re库)

一、正则表达式 1.1、概念 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、 regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff0…

docker 使用远程镜像启动一个容器

使用前提&#xff1a; 首先你得安装docker,其次你得拥有一个远程镜像 docker run --name io_11281009 --rm -it -p 2233:22 -v .:/root/py -e ed25519_rootAAAAC3NzaC1lZDI1********Oy7zR7l7aUniR2rul ghcr.lizzie.fun/fj0r/io srv对上述命令解释&#xff1a; 1.docker run:…

SSM课设-学生管理系统

【课设者】SSM课设-学生管理系统 技术栈: 后端: SpringSpringMVCMybatisMySQLJSP 前端: HtmlCssJavaScriptEasyUIAjax 功能: 学生端: 登陆 学生信息管理 个人信息管理 老师端: 多了教师信息管理 管理员端: 多了班级信息管理 多了年级信息管理 多了系统用户管理

SpringMVC 实战指南:打造高效 Web 应用的秘籍

第一章&#xff1a;三层架构和MVC 三层架构&#xff1a; 开发服务器端&#xff0c;一般基于两种形式&#xff0c;一种 C/S 架构程序&#xff0c;一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序&#xff0c;B/S 架构又分成了三层架构三层架构&#xff1a; 表现…

工程上LabVIEW常用的控制算法有哪些

在工程应用中&#xff0c;LabVIEW常用的控制算法有很多&#xff0c;它们广泛应用于自动化、过程控制、机器人、测试测量等领域。以下是一些常见的控制算法&#xff1a; 1. PID 控制 用途&#xff1a;PID&#xff08;比例-积分-微分&#xff09;控制是最常用的反馈控制算法&…

2024年博客之星主题创作|从零到一:我的技术成长与创作之路

2024年博客之星主题创作&#xff5c;从零到一&#xff1a;我的技术成长与创作之路 个人简介个人主页个人成就热门专栏 历程回顾初来CSDN&#xff1a;怀揣憧憬&#xff0c;开启创作之旅成长之路&#xff1a;从平凡到榜一的蜕变持续分享&#xff1a;打卡基地与成长复盘四年历程&a…

【2024年华为OD机试】(B卷,200分)- 战场索敌 (JavaScriptJava PythonC/C++)

一、问题描述 题目描述 有一个大小为 N * M 的战场地图&#xff0c;被墙壁 # 分隔成大小不同的区域。上下左右四个方向相邻的空地 . 属于同一个区域&#xff0c;只有空地上可能存在敌人 E。请求出地图上总共有多少区域里的敌人数小于 K。 输入描述 第一行输入为 N, M, K&…

机器学习(5):支持向量机

1 介绍 支持向量机&#xff08;Support Vector Machine&#xff0c;简称 SVM&#xff09;是一种监督学习算法&#xff0c;主要用于分类和回归问题。SVM 的核心思想是找到一个最优的超平面&#xff0c;将不同类别的数据分开。这个超平面不仅要能够正确分类数据&#xff0c;还要使…

【Linux入门】2w字详解yum、vim、gcc/g++、gdb、makefile以及进度条小程序

文章目录 Ⅰ. Linux 软件包管理器 yum一、什么是软件包&#xff1f;二、查找软件包三、安装与卸载软件包 拓展&#xff1a;lrzsz简介拓&#xff1a;配置 yum 源路径的方法Ⅱ. Linux开发工具vim编辑器一、vim 的基本概念二、vim 的基本操作三、vim 命令模式的操作四、vim 底行模…

《动•情》组诗浅析

路遇一枚运动的灵魂&#xff0c;邂逅一张随拍的悸动。 (笔记模板由python脚本于2025-01-21 22:59:21创建&#xff0c;本篇笔记适合喜欢诗的coder翻阅) 【学习的细节是欢悦的历程】 Python官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 pyt…

redis-排查命中率降低问题

1.命中率降低带来的问题 高并发系统&#xff0c;当命中率低于平常的的运行情况&#xff0c;或者低于70%时&#xff0c;会产生2个影响。 有大量的请求需要查DB&#xff0c;加大DB的压力&#xff1b;影响redis自身的性能 不同的业务场景&#xff0c;阈值不一样&#xff0c;一般…

Android RTMP直播练习实践

前言&#xff1a;本文只是练习&#xff0c;本文只是练习&#xff0c;本文只是练习&#xff01; 直播的核心就是推流和拉流&#xff0c;我们就以RTMP的协议来实现下推流和拉流&#xff0c;其他的协议等我学习后再来补充 1.推流 1.1搭建流媒体服务器&#xff0c;具体搭建方法请参…