第一套填空go-sdk.zip填空题：进程是一个 动态 的概念，而程序是一个 静态 的概念。在分时操作系统中进程调度经常采用 时间片轮转 算法，设备的独立性是指 应用于程序独立于实际使用的物理设备信箱通信是一种 间接 通信的方式。判断题1、多道程序设定并没有实现利用CPU或者通道进行工作来提高系统的效率 (X)2、银行家算法是一种检测死锁的算法 (X) 一种死锁避免算法3、页是信息的物理单位，段是信息的逻辑单位 (√)4、缺页中断与一般中断没有区别 (X)5、系统调用是由操作系统提供的内部调用，它只能通过用户程序间接使用 (√)简答简答题：1、说明进程的三个基本状态之间的转换的典型原因是什么？（1）处于就绪状态的进程，当进程调度程序为之分配了处理机后，该进程就由就绪状态变为执行状态。 （2）正在执行的进程因发生某事件而无法执行，如暂时无法取得所需资源，则由执行状态转变为阻塞状态。 （3）正在执行的进程，如因时间片用完或被高优先级的进程抢占处理机而被暂停执行，该进程便由执行状态转变为就绪状态。​ (1)就绪状态→执行状态:进程分配到cpu资源 ​ (2)执行状态→就绪状态:时间片用完 ​ (3)执行状态→阻塞状态:i/o请求 ​ (4)阻塞状态→就绪状态:i/o完成2、什么是零界区？进程进入临界区应该遵循的准则是什么？答：每个进程中访问临界资源的那段程序称为临界区（临界资源是一次仅允许一个进程使用的共享资源）。每次只准许一个进程进入临界区，进入后不允许其他进程进入。​ 2>、进程进入临界区的调度原则是：​ ①如果有若干进程要求进入空闲的临界区，一次仅允许一个进程进入。​ ②任何时候，处于临界区内的进程不可多于一个。如已有进程进入自己的临界区，则其它所有试图进入临界区的进程必须等待。​ ③进入临界区的进程要在有限时间内退出，以便其它进程能及时进入自己的临界区。​ ④如果进程不能进入自己的临界区，则应让出CPU，避免进程出现“忙等”现象。计算一.分页1、在一个请求分页系统中，一个长度为5页的进程。假如系统为它分配三个物理块，并且此进程的页面走向2,3,2,1,5,2,4,5,3,2,5,2，试用FIFO和LRU两种算法分别计算出程序访问过程中所发生的缺页次数。fifo:2 3 2 1 5 2 4 5 3 2 5 2 第1页2 2 2 2 5 5 5 5 3 3 3 3 第2页3 3 3 3 2 2 2 2 2 5 5 第3页 1 1 1 4 4 4 4 4 2 f f f f f f f f f 缺页中断次数 = 9lur: 2 3 2 1 5 2 4 5 3 2 5 2 第1页 2 2 2 2 2 2 2 2 3 3 3 3 第2页 3 3 3 5 5 5 5 5 5 5 5 第3页 1 1 1 4 4 4 2 2 2 f f f f f f f 缺页中断次数 = 7二. 非抢占式短进程2、有五个进程（表格：到达时间、执行时间）需要调度执行，如果采用非抢占式短进程调度算法，问这5个进程的平均周转时间是多少？表格进程到达时间执行时间P10.09P20.44P31.01P45.54p572三. 水果3 . 桌上有个能盛得下1个水果的空盘子。爸爸不停地向盘中放苹果，妈妈不停地向盘中放桔子，儿子不停地从盘中取出桔子享用，女儿不停地从盘中取出苹果享用。试用pv原语实现妈妈、爸爸、儿子和女儿进程之间的同步。empty=1,apple=0,orange=0,mutex=1; /*empty表示盘子的剩余量。mutex:是互斥信号，即同一时刻只有一个人能进行放或吃的操作*/ void parent(){ while(1){ p(empty); p(mutex); /放水果； v(mutex); if(放苹果){ v(apple); } if(放橙子){ v(orange); } } } void son(){ while(1){ p(orange); p(mutex); //吃橙子; v(mutex); v(empty); } } void daughter(){ while(1){ p(apple); p(mutex); //吃苹果； v(mutex); v(empty); } } 第二套填空1、系统感知进程存在的唯一标志是 进程控制块(pcb) ；系统感知作业存在的唯一标志 JCB ; 系统感知线程存在的唯一标识为 TCB2、线程之所以能减少并发执行的开销是因为 线程基本不拥有资源 。3、虚拟存储器中仅当系统允许将作业分多次调入内存中并实现将内存中暂时不运行的程序和数据换至台上，而多次性和 对换性 特征必须建立在 离散分配 的基础上。判断1、实时系统高度可靠和安全还必须要求资源利用率高且吞吐量 （X）不要求资源利用率2、两次打开word什么处理程序编辑同一篇因为程序一样，数据一样，所以系统中运行的这两个word是处于同一个进程的，两次打开word是同一个进程。（X）3、死锁状态中一定有两个或者两个以上的进程，但饥饿状态不一定（X）4、pv操作是不可以被中断的原语操作（√）5、DOS系统可能出现死锁现象 （√） 不清楚简答1、什么是进程？进程的基本特征是什么？进程是程序的一次执行过程进程是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序的一次执行.进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位.它的基本特征是: 动态性、并发性、独立性、异步性、结构性2、对于一个将页表存放在内存中的分页系统:​ (1)若是访问内存需要0.2微秒，有效访问时间为多少？​ 有效访问时间2*0.2=0.4us​ (2)若是加一个快表且假定在快表中找到页表上的机遇高达百分之九十，则有效访问时间为多少？​ 有效访问时间0.90.2+(1-0.9)2*0.2=0.22us​ (3)假定查快表时间需要为0.05微秒，有效访问时间为？​ 由于CPU以及块表本身耗用的时间没有给出,所以坚定这些时间可以忽略不计;计算一 . 围棋 伪代码1 . 生产围棋的工人不小心把相等数量的黑子和白子混装载一个箱子里，现要用自动分拣系统把黑子和白子分开，该系统由两个并发执行的进程组成，功能如下：​ ( 1 ) . 进程A专门捡黑子，进程B专门捡白子，每个进程每次只捡一个子。当一个进程在捡子时，不允许另一个进程捡子。用信号量操纵来实现一和二的要求​ ( 2 ) . 在上一题的基础上再添加一个功能，当一个进程捡一个棋子以后，必让另一个进程捡一个棋子，用信号量实现。解法一 :​ 解答：可以设置两个信号量S1和S2来协调进程P1和P2之间的同步。此外，由于不存在进程P1和进程P2之间同时取子的竞争问题，因此不必设置互斥信号量，如图3-3 所示。 若先让进程P1捡白子，则信号量S1value和S2.value的初值分别为1和0。两并发进程相应的程序如下。Semaphore S1,S2; S1.value=1; S2.value=0; cobegin process P1() { ​ while（白子不空） { ​ P(S1); 捡白子； ​ V(S2); ​ } } process P2() { ​ while(黑子不空) { ​ P(S2); 捡黑子； ​ V(S1); ​ } } coend解法二 :第一步：确定进程间的关系。由功能（1）（2）（3）可知，进程间的关系为 同步 关系。第二步：确定信号量及其值。进程 A 和 B 共享箱子这个公有资源，但规定两个进程必须轮流去取不同色的棋子，因而相互间要互通消息。对于进程 A 可设置一个私有信号量 s1，该私有信号量用于判断进程 A 是否能去拣黑子，初值为 1。对于进程 B 同样设置一个私有信号量 s2 ，该私有信号量用于判断进程 B 是否能去拣白子，初值为 0 。当然你也可以设置 s1 初值为 0 ，s2 初值为 1。begin s1,s2: semaphore; s1:=1;s2:=0; cobegin process A begin L1: P(s1); 拣黑子； V(s2); goto L1; end; process B begin L2: P(s2); 拣白子； V(s1); goto L2; end; coend; end; 二. 五个集合3、假设具有五个集合P（P0、P1、P2、P3、P4），有三类资源A B C，假设在某时刻有如下的状态：请问当前系统是否处于安全状态？eg:类似题目一:(找到相似的)​ 假设具有5个进程的集合p={p0,p1,p2,p3,p4},系统中有三类资源a、b、c,假设在某时刻有下图所示的资源分配状态. allocation abc max abc available abc p0 003 004 140 p1 100 175 p2 135 235 p3 002 064 p4 001 065 请问当前系统是否处于安全状态,如果系统中可利用资源available为 (0,6,2) ,系统是否安全,如果系统处于安全状态,请给出安全序列;如果系统处于非安全状态,请简要说明原因​ 解答​ 该状态是安全的 (2分),​ 系统中存在一个安全序列序列 p2,p1,p0,p3,p4 (3分) ​ 如果系统中可利用资源available为(0,6,2),此时系统处于非安全状态(2分)​ 银行家算法的工作过程p3需要资源(0,6,2),可以满足,执行完成;​ 可利用资源available为(0,6,4),p3进程可以满足,执行完成,可利用资源available为(0,6,5),p0进程可以执行完成,可利用资源available为(0,6,8),p2及p1进程都不能被满足,无法执行.(分析3分)三.分页上套题
数据上链的文件上传系统WeBase上链的数据user_Name Stringfile_Name Stringfile_Size Floatfile_Type Stringfile_Hash Stringcreate_Time Dateupdate_Time Date表user表IDuser_Name Stringuser_Account Stringuser_Password Stringuser_Role integer三字段create table user ( ID int auto_increment comment 'ID' primary key, user_Name char(15) not null comment '名称', user_Account char(10) not null comment '账号', user_Password char(20) default '123456' null comment '密码', user_Role tinyint(1) default 1 not null comment '角色' );file表ID Stringuser_Id Stringfile_Name Stringfile_Size Floatfile_Type Stringfile_Hash String三字段create table file ( ID int auto_increment comment 'ID' primary key, user_ID int null comment 'user_ID', file_Name char(20) not null comment '文件名称', file_Size float not null comment '文件大小', file_Type char(10) default '未知' null invisible comment '文件类型', file_Hash char not null comment 'Hash', create_Time datetime not null comment '创建时间', update_Time datetime not null comment '更新时间', is_Delete tinyint(1) default 1 null comment '是否删除', constraint file_user_ID_fk foreign key (user_ID) references user (ID) );链表看返回什么,到时候说
一个随时随地通过FTP上传文件系统基于SpringBoot的FilePD文件系统pom文件<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.8</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>demo</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <!-- <dependency>--> <!-- <groupId>com.baomidou</groupId>--> <!-- <artifactId>mybatis-plus-generator</artifactId>--> <!-- <version>3.1.0</version>--> <!-- </dependency>--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.23</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.7.8</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.9</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.3</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-gson</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.5</version> </plugin> </plugins> </build> </project> apache-maven-3.8.5.zipgit 下载 :https://registry.npmmirror.com/binary.html?path=git-for-windows/v2.42.0.windows.1/
Golang学习马-动态网站开发-复合数据类型.docxGoWeb编程实战派-从入门到精通2.pptxJava转GoGo配置go env高级安装 vscode注意root去运行idea等等 ， go环境变量会失效 ， 需在root权限下重新进bashrc设置用到的命令#没有vim sudo apt install vim #编辑 sudo vim ~/.bashrc #设置环境变量 export GOROOT=/usr/local/go export PATH=$PATH:$GOROOT/bin export GOPROXY=https://goproxy.io,direct #生效 source ~/.bashrc #终端输入goLinux安装Vscodesudo snap install --classic code不出意外 直接code就行打开1 . 基础1.1 包管理1.2 输入1.3 输出1.4 注释1.5 数据类型1.6 变量1.7 常量1.8 条件语句Day1整体package main import ( "awesomeProject/api" "fmt" "math" ) //go关键字 : break、default、func、interface、select、case、defer、 // go、map、struct、chan、else、goto、package、switch、const、 // fallthrough、if、range、type、continue、for、import、return、var /* * 全局常量 */ const Data = 999 const ( pi = 3.1415926 gender = "男" ) func main() { curriculum() gotoFunc(1) } /* * 输出 */ func Scan() { //fmt.Scan函数用于按空格分隔的连续输入，将用户输入的值分配给传递给它的参数。 var x, y int fmt.Scan(&x, &y) //fmt.Scanln函数用于按行读取用户输入， //类似于fmt.Scan，但在读取输入后会自动换行。 var name string var age int fmt.Scanln(&name, &age) //fmt.Scanf函数用于根据指定的格式从输入中读取用户输入。 //您可以使用格式字符串来指定要读取的值的类型和顺序。 fmt.Scanf("%s %d", &name, &age) } /* * 全局与局部变量 */ var number = 99 func bianliang() { //number := 66 //if true { // number := 33 // fmt.Println(number) //33 //} //fmt.Println(number) //66 //number := 66 //if true { // number := 33 // fmt.Println(number) //33 //} //number = 88 //fmt.Println(number) //88 if true { fmt.Println(number) //99 } number = 88 fmt.Println(number) //88 } /* * 上课用的 */ func curriculum() { //map遍历 键值对 m := map[string]int{ "go": 100, "web": 200, "java": 10000, } for key, value := range m { fmt.Println(key, value) } //通道 c := make(chan int) //创建一个整型类型通道 go func() { //启动一个goroutine //顺序表 c <- 7 //将数据推送进通道 c <- 8 c <- 9 close(c) }() for v := range c { fmt.Println(v) } //switch语句 var language = "golang" switch language { case "golang": fmt.Println("并发") case "java": fmt.Println("Popular languages") } /* 声明函数变量 */ getSquareRoot := func(x float64) float64 { return math.Sqrt(x) } fmt.Println(getSquareRoot(9)) //break和continue语句 OuterLoop: //外层循环的标签 for i := 0; i < 2; i++ { //双层循环 for j := 0; j < 5; j++ { switch j { //使用 switch 进行数值分支判断 case 1: fmt.Println(i, j) //继续 循环内层 continue // continue OuterLoop 会直接跳到外层循环 case 3: fmt.Println("循环结束", i, j) break OuterLoop //退出 OuterLoop 对应的循环之外 } } } } /* * goto语句 */ func gotoFunc(err int) { if err != 1 { goto doExit //跳转到错误处理标签处执行 } if err != 2 { goto doExit } fmt.Println("over") return doExit: //跳转标签 fmt.Println("错误的", err) } /* * 基础 */ func foundation() { // 包管理 fmt.Println("1") api.Add() //输出 print("内置") println("内置") fmt.Print("fmt包") fmt.Println("fmt包") // %s 字符串 %d 数字 %.2f浮点数 fmt.Printf("老汉开着%s,"+ "去接%s的媳妇，多少钱一次？%d块。"+"\n"+ "嫂子给打折吧，%.2f怎么样？小哥哥包你100%%满意", "车", "老男孩", 100, 3.889) // 数据类型 fmt.Println("Atanycosts" + "666") //变量 //一个变量未引用时会报红, 不管,跟Java一样 var a string = "Go中变量的用法" var b int = 10 var c bool = true fmt.Println(a) fmt.Println(b) fmt.Println(c) if c == true { fmt.Println("为真") } //变量简写 //var n string = "武沛齐" //var wuhan = "武沛齐" //声明并赋值 n := "武沛齐" // 推荐 fmt.Println(n) //先声明 再赋值 var name, message, data string name = "武沛齐" message = "中奖了" data = "中了5000w" fmt.Println(name, message, data) //转Java用不习惯的方法 //变量的因式分解 var ( ming = "武沛齐" age = 18 hobby = "大保健" salary = 1000000 gender string // 只声明但不赋值，有一个默认： "" length int // 只声明但不赋值，有一个默认： 0 sb bool // 只声明但不赋值，有一个默认： false ) fmt.Println(ming, age, hobby, salary, gender, length, sb) //作用域跟Java差不多 //方法内的为局部 , 方法外的为全局 newName := name var name2 = "武沛齐" fmt.Println("newName赋值:", newName, name2) bianliang() //常量定义 const nameAB = "At" fmt.Println(nameAB) // 常量因式分解 const ( v1 = 123 v2 = 456 pi = 9.9 ) fmt.Println(v1, v2, pi, gender) //iota 在声明常量时的一个计数器。 const ( monday = iota + 1 tuesday wednesday thursday friday saturday sunday ) fmt.Println(monday, thursday, wednesday, thursday, friday, saturday, sunday) } Day2整体package main import ( "bytes" "fmt" "strings" ) //day2整体 //字符串操作 func main() { arr() } // 字符串拼接 func StringJoin() { n := "hello world" m := "I am Tom" j := n + "," + m //用+号连接 fmt.Println(j) k := fmt.Sprintf("%s,%s", n, m) //用Sprintf函数连接 fmt.Println(k) g := strings.Join([]string{n, m}, ",") //用strings.Join函数连接 fmt.Println(g) var builder strings.Builder builder.WriteString(n) //用string.Builder builder.WriteString(",") builder.WriteString(m) fmt.Println(builder.String()) var buffer bytes.Buffer //用bytes.Buffer连接 buffer.WriteString(n) buffer.WriteString(",") buffer.WriteString(m) fmt.Println(buffer.String()) } func stringCourse() { //ASCII str := "programming" fmt.Println(str[1]) //获取字符码点 ASCII fmt.Println(str[1:3]) //获取字符子串 ro fmt.Println(str[1:]) //截取从1到结尾的子串 fmt.Println(str[:3]) //截取从0到2位的字串 pro fmt.Println(len(str)) //获取字串字节数 fmt.Println([]rune(str)) //将字串每个字节转换为码点 fmt.Println(string(str[1])) //获取索引位为1的字符 //遍历 str1 := "I love go web 编程技术" //str[0]提取的是单个字节 chars := []rune(str1) //将字符串转换为rune切片，就可以按字符提取了 for _, char := range chars { fmt.Printf(string(char)) } fmt.Println("!") //比较ASCII大小 fmt.Println(str[0] >= str1[2]) //迭代 for index, char := range str { fmt.Printf("%d %U %c \n", index, char, char) } //字符串的修改 //[]byte str2 := "Hi 世界" by := []byte(str2) by[2] = ',' //把空格改为逗号， fmt.Printf("%s\n", str2) fmt.Printf("%s\n", by) //[]rune str3 := "Hi 世界" by1 := []rune(str3) by1[3] = '中' by1[4] = '国' fmt.Printf("%s\n", str3) fmt.Printf(string(by1)) //字符串分割 n := "hello@-world@-I@-am@-Tom" m := strings.Split(n, "@-") fmt.Printf("分割后的数据类型： %T\n", m) for _, i := range m { fmt.Println(i) } } // 优化后 func arr() { //没使用报红 // var array_name[10] int var numbers = [5]float32{100.0, 8.0, 9.4, 6.8, 30.1} //声明i并赋值 索引-1 for i := 0; i < 5; i++ { //先强转 numbers[i] = (float32(i + 66)) //打印 fmt.Printf("numbers[%d] = %.0f\n", i, numbers[i]) } }Day 3整体package main import ( "awesomeProject/api" "bytes" "fmt" "math" "strings" ) //go关键字 : break、default、func、interface、select、case、defer、 // go、map、struct、chan、else、goto、package、switch、const、 // fallthrough、if、range、type、continue、for、import、return、var /* * 结构体 */ type Book struct { title string author string subject string press string } /* * 全局常量 */ const Data = 999 const ( pi = 3.1415926 gender = "男" ) func main() { //day1() //day2() day3() } /* * 基础 */ func day1() { curriculum() gotoFunc(1) } /* * 字符串 */ func day2() { bianliang() StringJoin() stringCourse() } /* * 复合数据类型 */ func day3() { arr() structCourse() sliceCourse() } // 修改后 func sliceCourse() { map1 := map[string]string{"first": "go", "second": "web"} createdMap := make(map[string]float32) createdMap["k1"] = 99 createdMap["k2"] = 199 var map2 map[string]string map2 = map1 // 对map引用的内容修改会影响原始map的值 mapA := make(map[int][]int) // 切片可以作为map的值 mapB := make(map[int]*[]int) // 切片指针作为map的值 fmt.Println(map1, createdMap, map2, mapA, mapB) } /* 结构体 */ func structCourse() { // 创建一个新的结构体 fmt.Println(Book{"Go Web编程实战派从入门到精通", "廖显东", "Go语言教程", "电子工业出版社"}) // 也可以使用 key => value 格式 fmt.Println(Book{title: "Go Web编程实战派从入门到精通", author: "廖显东", subject: "Go语言教程", press: "电子工业出版社"}) // 忽略的字段为 0 或 空 fmt.Println(Book{title: "Go Web编程实战派从入门到精通", author: "廖显东"}) } // 优化后 复合数据类型 func arr() { //没使用报红 // var array_name[10] int var numbers = [5]float32{100.0, 8.0, 9.4, 6.8, 30.1} //声明i并赋值 索引-1 for i := 0; i < 5; i++ { //先强转 numbers[i] = (float32(i + 66)) //打印 fmt.Printf("numbers[%d] = %.0f\n", i, numbers[i]) } } // 字符串拼接 func StringJoin() { n := "hello world" m := "I am Tom" j := n + "," + m //用+号连接 fmt.Println(j) k := fmt.Sprintf("%s,%s", n, m) //用Sprintf函数连接 fmt.Println(k) g := strings.Join([]string{n, m}, ",") //用strings.Join函数连接 fmt.Println(g) var builder strings.Builder builder.WriteString(n) //用string.Builder builder.WriteString(",") builder.WriteString(m) fmt.Println(builder.String()) var buffer bytes.Buffer //用bytes.Buffer连接 buffer.WriteString(n) buffer.WriteString(",") buffer.WriteString(m) fmt.Println(buffer.String()) } func stringCourse() { //ASCII str := "programming" fmt.Println(str[1]) //获取字符码点 ASCII fmt.Println(str[1:3]) //获取字符子串 ro fmt.Println(str[1:]) //截取从1到结尾的子串 fmt.Println(str[:3]) //截取从0到2位的字串 pro fmt.Println(len(str)) //获取字串字节数 fmt.Println([]rune(str)) //将字串每个字节转换为码点 fmt.Println(string(str[1])) //获取索引位为1的字符 //遍历 str1 := "I love go web 编程技术" //str[0]提取的是单个字节 chars := []rune(str1) //将字符串转换为rune切片，就可以按字符提取了 for _, char := range chars { fmt.Printf(string(char)) } fmt.Println("!") //比较ASCII大小 fmt.Println(str[0] >= str1[2]) //迭代 for index, char := range str { fmt.Printf("%d %U %c \n", index, char, char) } //字符串的修改 //[]byte str2 := "Hi 世界" by := []byte(str2) by[2] = ',' //把空格改为逗号， fmt.Printf("%s\n", str2) fmt.Printf("%s\n", by) //[]rune str3 := "Hi 世界" by1 := []rune(str3) by1[3] = '中' by1[4] = '国' fmt.Printf("%s\n", str3) fmt.Printf(string(by1)) //字符串分割 n := "hello@-world@-I@-am@-Tom" m := strings.Split(n, "@-") fmt.Printf("分割后的数据类型： %T\n", m) for _, i := range m { fmt.Println(i) } } /* * 输出 */ func Scan() { //fmt.Scan函数用于按空格分隔的连续输入，将用户输入的值分配给传递给它的参数。 var x, y int fmt.Scan(&x, &y) //fmt.Scanln函数用于按行读取用户输入， //类似于fmt.Scan，但在读取输入后会自动换行。 var name string var age int fmt.Scanln(&name, &age) //fmt.Scanf函数用于根据指定的格式从输入中读取用户输入。 //您可以使用格式字符串来指定要读取的值的类型和顺序。 fmt.Scanf("%s %d", &name, &age) } /* * 全局与局部变量 */ var number = 99 func bianliang() { //number := 66 //if true { // number := 33 // fmt.Println(number) //33 //} //fmt.Println(number) //66 //number := 66 //if true { // number := 33 // fmt.Println(number) //33 //} //number = 88 //fmt.Println(number) //88 if true { fmt.Println(number) //99 } number = 88 fmt.Println(number) //88 } /* * 上课用的 */ func curriculum() { //map遍历 键值对 m := map[string]int{ "go": 100, "web": 200, "java": 10000, } for key, value := range m { fmt.Println(key, value) } //通道 c := make(chan int) //创建一个整型类型通道 go func() { //启动一个goroutine //顺序表 c <- 7 //将数据推送进通道 c <- 8 c <- 9 close(c) }() for v := range c { fmt.Println(v) } //switch语句 var language = "golang" switch language { case "golang": fmt.Println("并发") case "java": fmt.Println("Popular languages") } /* 声明函数变量 */ getSquareRoot := func(x float64) float64 { return math.Sqrt(x) } fmt.Println(getSquareRoot(9)) //break和continue语句 OuterLoop: //外层循环的标签 for i := 0; i < 2; i++ { //双层循环 for j := 0; j < 5; j++ { switch j { //使用 switch 进行数值分支判断 case 1: fmt.Println(i, j) //继续 循环内层 continue // continue OuterLoop 会直接跳到外层循环 case 3: fmt.Println("循环结束", i, j) break OuterLoop //退出 OuterLoop 对应的循环之外 } } } } /* * goto语句 */ func gotoFunc(err int) { if err != 1 { goto doExit //跳转到错误处理标签处执行 } if err != 2 { goto doExit } fmt.Println("over") return doExit: //跳转标签 fmt.Println("错误的", err) } /* * 基础 */ func foundation() { // 包管理 fmt.Println("1") api.Add() //输出 print("内置") println("内置") fmt.Print("fmt包") fmt.Println("fmt包") // %s 字符串 %d 数字 %.2f浮点数 fmt.Printf("老汉开着%s,"+ "去接%s的媳妇，多少钱一次？%d块。"+"\n"+ "嫂子给打折吧，%.2f怎么样？小哥哥包你100%%满意", "车", "老男孩", 100, 3.889) // 数据类型 fmt.Println("Atanycosts" + "666") //变量 //一个变量未引用时会报红, 不管,跟Java一样 var a string = "Go中变量的用法" var b int = 10 var c bool = true fmt.Println(a) fmt.Println(b) fmt.Println(c) if c == true { fmt.Println("为真") } //变量简写 //var n string = "武沛齐" //var wuhan = "武沛齐" //声明并赋值 n := "武沛齐" // 推荐 fmt.Println(n) //先声明 再赋值 var name, message, data string name = "武沛齐" message = "中奖了" data = "中了5000w" fmt.Println(name, message, data) //转Java用不习惯的方法 //变量的因式分解 var ( ming = "武沛齐" age = 18 hobby = "大保健" salary = 1000000 gender string // 只声明但不赋值，有一个默认： "" length int // 只声明但不赋值，有一个默认： 0 sb bool // 只声明但不赋值，有一个默认： false ) fmt.Println(ming, age, hobby, salary, gender, length, sb) //作用域跟Java差不多 //方法内的为局部 , 方法外的为全局 newName := name var name2 = "武沛齐" fmt.Println("newName赋值:", newName, name2) bianliang() //常量定义 const nameAB = "At" fmt.Println(nameAB) // 常量因式分解 const ( v1 = 123 v2 = 456 pi = 9.9 ) fmt.Println(v1, v2, pi, gender) //iota 在声明常量时的一个计数器。 const ( monday = iota + 1 tuesday wednesday thursday friday saturday sunday ) fmt.Println(monday, thursday, wednesday, thursday, friday, saturday, sunday) }day 4 整体package main import "fmt" var nameCourse string = "go" func main() { sli := []int{1, 6, 8} // 使用匿名函数打印切片的内容 visPrint(sli, func(value int) { /*f函数的实参函数*/ fmt.Println(value) }) myname := deferCousre() fmt.Printf("main 函数里的name: %s\n", nameCourse) fmt.Println("main 函数里的myname: ", myname) funcCourse() deferCousre() } /* 遍历切片中每个元素，通过给定的函数访问元素*/ func visPrint(list []int, f func(int)) { for _, value := range list { f(value) /*每个元素用f函数处理一遍*/ } } /* * 匿名函数 */ func funcCourse() { f := func(data int) { // 定义匿名函数并赋值给f变量 fmt.Println("hi, this is a closure", data) } f(6) // 此时f变量的类型是func(), 可以直接调用 func(data int) { fmt.Println("hi, this is a closure, directly", data) }(8) //直接声明并调用 } /* * 延迟执行 */ func deferCousre() string { defer func() { nameCourse = "python" }() fmt.Printf("myfunc 函数里的name：%s\n", nameCourse) return nameCourse }package main import ( "crypto/sha256" "fmt" ) type MerkleTree struct { nodes []string } func (mt *MerkleTree) insert(data string) { mt.nodes = append(mt.nodes, data) } func (mt *MerkleTree) getLeafHashes() []string { hashes := make([]string, len(mt.nodes)) for i, node := range mt.nodes { hashes[i] = fmt.Sprintf("%x", sha256.Sum256([]byte(node))) } return hashes } func (mt *MerkleTree) getParentHashes(hashes []string) []string { parentHashes := make([]string, len(hashes)/2) for i := 0; i < len(hashes); i += 2 { parentHash := fmt.Sprintf("%x", sha256.Sum256([]byte(hashes[i]+hashes[i+1]))) parentHashes[i/2] = parentHash } return parentHashes } func (mt *MerkleTree) display() { hashes := mt.getLeafHashes() parentHashes := mt.getParentHashes(hashes) for i, hash := range hashes { fmt.Printf("%d --> %s\n", i, hash) } for i, hash := range parentHashes { fmt.Printf("%d --> %s\n", i+len(hashes), hash) } } func main() { mt := &MerkleTree{} mt.insert("a") mt.insert("b") mt.insert("c") mt.insert("d") mt.insert("e") mt.insert("f") mt.insert("g") mt.insert("h") mt.insert("i") mt.insert("j") mt.display() } day 5 整体package main import "fmt" /** 封装 */ type Triangle struct { Bottom float32 Height float32 } type Student struct { name string score float32 Age int } type Square struct { sideLen float32 } type Shape interface { Area() float32 } // type Engine interface { Run() Stop() } type Bus struct { Engine } /** 函数 */ //面积计算 func (t *Triangle) Area() float32 { return (t.Bottom * t.Height) / 2 } func (sq *Square) Area() float32 { return sq.sideLen * sq.sideLen } //getter和setter func (s *Student) GetName() string { // 获取 name return s.name } func (s *Student) SetName(newName string) { s.name = newName // 设置 name } func (s *Student) GetAge() int { return s.Age // 获取age } func (s *Student) SetAge(newName int) { s.Age = newName // 设置age } //工作 func (c *Bus) Working() { c.Run() c.Stop() } func main() { //面积 //｛｝直接传参数 //类似实例化对象 t := &Triangle{6, 8} s := &Square{8} shapes := []Shape{t, s} for n, _ := range shapes { fmt.Println("图形数据: ", shapes[n]) fmt.Println("面积：", shapes[n].Area()) } //getter和setter a := new(Student) a.SetName("Shirdon") fmt.Println(a.GetName()) fmt.Println() }
Magic安装解压文件 --> 打开 Clash for Windows.exe开机自启按需选择 ， 其他默认下载成功后会出现一个文件 ， 右键文件可以改名称等等如图选中这个文件会出现一堆地址 ， 导航栏会出现 自动选择 等选项 ，不会就自动选择右键在用得使用选择系统代理就可以上网了
区块链原理-实验一.docx# 学校文件快捷word等文件可进预览下载全家桶破解方法一 : 亲测可用https://3.jetbra.in/方法二 :各类文件VMware许可证:​ JU090-6039P-08409-8J0QH-2YR7FGo笔记计网实验一.docx计网第二次实验.docx计网软件-PacketTracer53.rarwin 破解软件.rar合约PPT.rar区块连PPT.rarGoWeb编程实战派-从入门到精通1.pptx《区块链系统搭建与应用》0908.docxAxure-基础教程.docxgame_msgq.rargame-pipe.rarsync.zip动态网站开发技术实验模板.docx58064《计算机操作系统实验指导》源代码.zip.zip全家桶-傻瓜式一键鸡活2023.rar马-计网实验一.docx计网-VLAN及STP实验.docx马-计网-VLAN及STP实验.docx区块链原理-实验一.docx计网实验1018.docx马-计操-进程同步实验.doc计网-静态路由.rar马-GoWeb的Web入门.docx马-区块链实验10.31.docx12.15操作.zip合约安装remixD执行这俩命令,不会报错npm install -g @remix-project/remixd remixd -s C:\Users\Admin\Documents\test --remix-ide https://remix.ethereum.org安装1 . Goland和Vscode安装点击直装 , 无脑下一步VScode下载Goland-2022版本Go安装程序clash-win魔法1.1 . 第一个Go程序go安装后 ,进 cmd 输入 go再将服务器网址一改, 就能完美下包go env -w GOPROXY=https://goproxy.cn根据自己安装的位置设置设置环境变量 , 可以只设置 GOROOT , GOPATH 可以不设置再在path中添加go的bin目录VScode版再打开VsCode , 下载三个插件中文包 : code Runner :go : 随便创个目录, 调出终端 : 快捷键 Ctrl+`package main import "fmt" // 导入内置 fmt func main() { // main函数，是程序执行的入口 fmt.Println("Hello World!") // 在终端打印 Hello World! } 输入 ://根据自己文件名更改 go run 1.goGoland版需要先进行破解 , 如上的有一键破解包未激活示例 : 忘截图了,拿到激活码后,在这里填之后新建项目到自己的目录,直接无脑创建如果没有运行配置,手动创建1.2 . 下载离线帮助文档直接进入bin目录输入cmd回车go install golang.org/x/tools/cmd/godoc@latest godoc -http=:3333 //3333可自定义4位数最后浏览器输入loaclhost:3333 或 127.0.0.1:3333就能打开2 . VMware安装2.1. 基础VMware安装不再阐述 (没找到安装包)上面有许可证,不行的话百度有很多记住自己镜像文件的位置打开虚拟机-->创建-->自定义选择最新的就行再选择稍后安装选择Linux --> Ubuntu64位 -->下一步更改虚拟机名称和位置此位置有相同名称的虚拟机 , 进目录删除就行 然后再点下一步按老师的 处理器:1 核:4 看自己电脑配置 核可以更小一点内存默认就行不使用网络连接I/O默认磁盘默认磁盘大小按需分配 , 注意选择存储为单个文件不管,下一步 --> 完成创建成功后 --> 编辑 --> 首选项只用更改位置就行自己的电脑不用管如下图 , 默认就行之后进入管理删除无用的设备在显示器中关闭加速再引入自己的镜像文件到这个界面按需选择语言选择最小安装填入自己的信息 -->等待安装完成此时如果没有鼠标 请同时按 Ctrl+Alt如此请关闭虚拟机添加网络适配器 -->开机 -->输入密码进入系统2.2 . 安装魔法
Travel储备1 . 攻略储备2 . 物品储备一. 景点篇1 . 观山湖公园介绍 : ​ 开放时间 : 6:00-22:00​ 门票免费 , 电瓶车10r , 5500亩​2 . 黔灵山公园时间 : 过去50分钟左右路线 : 酒店乘坐地铁1号线 国际生态会议中心/阳关站上 八鸽岩C口出3 . 青岩古镇酒店出发有点远机场出发4 . 蓬莱仙界园有点远5 . 白宫(花果山湿地公园)最好从 黔灵山公园 出发 , 白天逛完黔灵山公园晚上去白宫时间 : 50分钟 路线 : 乘坐41/260/320路 黔灵山公园 站上车到 花果山湿地公园6 . 钟书阁(云上方舟商场)理由:贵州喀斯特地貌和溶洞元素设计酒店附近,遨游太空好像也在云上方舟里面7 . 省博和省图省博:​ 时间 : 9:00-17:00 16:00停止入场 周一闭馆 提前十天约就行(人不是很多)​ 国家一级博物馆 免费需预约省图:​ 时间 : 9:00-20:008 . CCpark贵州小威尼斯 , 异国风情二 . 吃喝玩乐篇美食三条街 : 正新街 民生路 蔡家街1 . 贵阳糯米饭2 . 厕所馒头3 . 田孃素粉​ 有宽有细 : 正宗入味就吃细的 不吃辣的就吃脆哨素粉 吃辣的就吃烧椒素粉4 . 脆哨炒饭5 . 安顺小裹卷
膳食搭配智能平台智能推荐算法的实现与应用智能推荐帖子算法是基于协同过滤算法实现的。​ 基于物品的协同过滤算法 : 给用户推荐与他之前喜欢的物品相似的物品​ 我们通过定义了一张 user_Goods 表来存储用户 , ​ 基于用户的协同过滤算法 : 给用户推荐与他兴趣相似的用户喜欢的物品余弦相似度算法算法编辑距离算法 、Jacquard相似度匹配算法和余弦相似度算法对帖子和方案的标题进行使用 Elasticsearch 框架 中的 IK 分词 : 最细粒度划分标签素食、蛋奶、纯素、低卡、高蛋白、低脂、高纤维、高盐、健康、清真、绿色、糖尿病["素食", "烤鱼", "烤肉", "火锅", "海鲜"]["甜点", "蛋糕", "面包", "冰淇淋", "巧克力"]["早餐", "午餐", "晚餐", "夜宵", "零食"]["酒", "红酒", "啤酒", "白酒", "葡萄酒"]["健康饮食", "减肥", "饮食搭配", "营养均衡", "饮食习惯"]["烹饪", "料理", "烘焙", "调味品", "厨具"]["地方特色美食", "江浙菜", "川菜", "粤菜", "湘菜"]["食材", "蔬菜", "水果", "肉类", "海鲜"]["宵夜", "夜市美食", "街边小吃", "快餐", "烧烤"]["饮品", "茶", "咖啡", "果汁", "饮料"]分词(标签)#分词器测试ik_max_word POST _analyze { "analyzer":"ik_max_word", "text":"我是中国人" }{ "tokens" : [ { "token" : "我", "start_offset" : 0, "end_offset" : 1, "type" : "CN_CHAR", "position" : 0 }, { "token" : "是", "start_offset" : 1, "end_offset" : 2, "type" : "CN_CHAR", "position" : 1 }, { "token" : "中国人", "start_offset" : 2, "end_offset" : 5, "type" : "CN_WORD", "position" : 2 }, { "token" : "中国", "start_offset" : 2, "end_offset" : 4, "type" : "CN_WORD", "position" : 3 }, { "token" : "国人", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 4 } ] }编辑距离算法计算两组最相似的标签@Test public void Test() { List<String> list1 = Arrays.asList("健康", "膳食", "减肥", "健美", "美食"); List<String> list2 = Arrays.asList("美味", "特色", "减肥", "瘦身"); int max = Math.max(list1.size(), list2.size()); double similarity = minDistance(list1, list2); double distance = 1 - similarity / max; System.out.println(distance); // 0.19999999999999996 } public static int minDistance(List<String> tagList1, List<String> tagList2) { int n = tagList1.size(); int m = tagList2.size(); if (n * m == 0) { return n + m; } int[][] d = new int[n + 1][m + 1]; for (int i = 0; i < n + 1; i++) { d[i][0] = i; } for (int j = 0; j < m + 1; j++) { d[0][j] = j; } for (int i = 1; i < n + 1; i++) { for (int j = 1; j < m + 1; j++) { int left = d[i - 1][j] + 1; int down = d[i][j - 1] + 1; int left_down = d[i - 1][j - 1]; if (!Objects.equals(tagList1.get (i - 1), tagList2.get(j - 1))) { left_down += 1; } d[i][j] = Math.min(left, Math.min(down, left_down)); } } return d[n][m]; }余弦相似度/** * 余弦相似度 */ public class CosineSimilarityUtil { // 计算余弦相似度 public static double cosineSimilarity(List<String> tag1, List<String> tag2) { // 将两个标签列表转换为向量 Map<String, Integer> vector1 = getVector(tag1); Map<String, Integer> vector2 = getVector(tag2); // 计算两个向量的点积 int dotProduct = 0; for (String key : vector1.keySet()) { if (vector2.containsKey(key)) { dotProduct += vector1.get(key) * vector2.get(key); } } // 计算两个向量的模长 double magnitude1 = getMagnitude(vector1); double magnitude2 = getMagnitude(vector2); // 计算余弦相似度 double cosineSimilarity = dotProduct / (magnitude1 * magnitude2); return cosineSimilarity; } // 将标签列表转换为向量 public static Map<String, Integer> getVector(List<String> tags) { Map<String, Integer> vector = new HashMap<>(); for (String tag : tags) { vector.put(tag, vector.getOrDefault(tag, 0) + 1); } return vector; } // 计算向量的模长 public static double getMagnitude(Map<String, Integer> vector) { double magnitude = 0; for (int value : vector.values()) { magnitude += Math.pow(value, 2); } return Math.sqrt(magnitude); } }Jacquard相似度匹配算法@Test public static void Test() { List<String> list1 = Arrays.asList("健康", "膳食", "减肥", "健美", "美食"); List<String> list2 = Arrays.asList("美味", "特色", "减肥", "瘦身"); double similarity = calculateJacquardSimilarity(list1, list2); System.out.println(similarity); //0.125 } /** * Jacquard 相似度匹配 * * @param list1 * @param list2 * @return */ public static double calculateJacquardSimilarity(List<String> list1, List<String> list2) { Set<String> set1 = new HashSet<>(list1); Set<String> set2 = new HashSet<>(list2); Set<String> intersection = new HashSet<>(set1); intersection.retainAll(set2); HashSet<String> strings = new HashSet<>(set1); strings.addAll(set2); return (double) intersection.size() / strings.size(); }未来与展望1 . 提供更优的搜索方式目前如今只是模糊搜索下个版本Elastic StackElasticsearch 搜索引擎（重点）Logstash 数据管道Kibana 数据可视化2 . 压力测试目前下个版本通过 JMeter 更进一步的进行压力测试3 . 在现有的项目中接入TensorFlow框架目前通过用户行为进行分析, 推荐热帖,热方案等下个版本加入基于物品、用户的协同过滤算法 :余弦相似度加入基于帖子、方案中内容的推荐算法 : 基于内容的推荐算法是通过分析物品的属性和用户的历史偏好来预测用户可能喜欢哪些物品。地图功能需求分析前端传省份来 , 在表balance_area和post_area中查数据balance_area的字段 , post也是同理​ id ​ balance_id 方案id​ province 省份 area​ create_Time​ update_Time​ is_Delete将查到的balance_id封装成一个List , 再去调用写好的balance_food_relation查询方法使用Mybatis-Plus的链式查询,只查询balance_id这个字段List<Integer> balanceIds = new LambdaQueryChainWrapper<BalanceArea>(balanceAreaMapper) .eq(BalanceArea::getProvince, province) .list() .stream() .map(BalanceArea::getBalanceId) .collect(Collectors.toList());请对这个功能优化一下,不用给出代码, 只需要在逻辑上等等方面进行优化 , 技术栈是SSM+SpringBoot+Mybatis-plus系统关键技术1. SpringBoot框架Spring Boot 是 Spring 的一种全新的开发模式，它可以帮助开发者更快速地搭建 Java Web 应用，并提供许多自动化的配置，大大减少了项目的初始化和部署时间。Spring Boot 框架的整体优点 ：简单快速：Spring Boot 的自动配置和约定大于配置的设计理念，可以帮助开发者更快速地创建项目并集成各种框架和服务。开箱即用：Spring Boot 预置了常用的依赖和配置，可以帮助开发者省去很多初始化的工作。多开发场景支持：Spring Boot 不仅可以用于 Web 开发，还可以支持多种开发场景，如批处理、消息队列、数据处理等。可插拔架构：Spring Boot 架构采用模块化设计，开发者可以只使用需要的模块，同时也可以方便地添加和删除第三方模块。2. SSM框架1 . Spring框架Spring 框架是一种轻量级的 Java 开发框架，它提供了一系列的框架和类库，可以帮助开发者构建复杂的企业级应用程序。Spring 框架的核心功能包括：IoC（Inversion of Control）容器、AOP（Aspect Oriented Programming）框架、数据访问和集成、Web 开发、测试和监控等。Spring 框架的整体优点 :易于使用和扩展：Spring 框架的一个主要优点是它非常容易学习和使用。它具有许多类库和插件，可以快速实现复杂的业务逻辑，并可以方便地进行模块化开发和组件化重用。提高代码的可测试性：Spring 框架的依赖注入（DI）和面向切面编程（AOP）特性，可以帮助开发人员将应用程序中的业务逻辑与非业务逻辑分离，从而提高代码的可测试性。增加应用程序的灵活性和可拓展性：Spring 框架可以帮助开发者实现应用程序的可插拔性和可扩展性。因为开发人员可以将不同的模块通过轻松的组装与集成来构建一个更加强大、可定制的应用程序。促进企业级应用程序的开发和部署：Spring 框架可以帮助企业级应用程序快速且可靠地实现各种业务需求，同时提供了丰富的工具和类库，方便应用程序的部署和运行。2 . SpringMvc框架Spring MVC 框架是基于 Model-View-Controller（MVC）设计模式的一种框架。它可以帮助开发者实现 Web 应用程序的开发和部署，提供了一种简单而灵活的方式来处理 HTTP 请求和响应。Spring MVC 框架的整体优点 ：简单易用：Spring MVC 框架的 API 简单易用，开发者可以快速上手并进行开发。灵活性强：可以自由选择各种框架比如 JSP、Thymeleaf、FreeMarker 作为视图模板技术，并且可以支持 RESTful 风格，使其更加灵活。解耦合：Spring MVC 框架采用了分离 MVC 的思路，使得 Controller、View、Model 可以独立进行开发和维护，从而达到解耦合的效果。可测试性强：Spring MVC 框架的请求和响应处理、MVC 拦截器等功能都是基于接口的，这意味着整个应用程序的单元测试和集成测试可以更容易地进行。可扩展性强：Spring MVC 框架提供了丰富的扩展点，比如拦截器、视图解析器、处理器映射器等，使得开发者可以自由扩展框架的功能。3 . Mybatis框架MyBatis是一个开源的持久层框架，它支持自定义SQL、存储过程和高级映射。使用其可以避免很多JDBC的重复代码和样板式代码。其作为一种简单、灵活、高效的ORM框架得到了广泛的应用和推广，对于需要进行复杂查询和业务逻辑处理的项目，使用MyBatis可以极大地提高开发效率和代码的可维护性。Mybatis 框架的整体优点 :灵活而强大：MyBatis支持各种不同的数据库操作方法，例如通过XML或注解定义映射、支持动态SQL，满足了不同类型的数据库操作需求。性能好：MyBatis可以通过多种配置方式进行SQL语句的优化和缓存，能够提高程序的性能和稳定性。易于测试：MyBatis可以在测试环境中快速方便地进行单元测试，也方便进行数据的回滚操作。可扩展性强：MyBatis提供了插件的机制，可以通过自定义插件来扩展MyBatis的功能，也可以自定义类型转换器、错误处理等。3 . SpringSecurity框架Spring Security是Spring的安全框架，它提供了全面而灵活的安全性，支持多种身份验证和授权机制，助力开发者构建安全可靠的Web应用程序。Spring Security的核心原理是在Spring框架上附加一个安全层，通过过滤器来处理请求，从而实现对Web应用程序的保护。接下来我们将详细介绍Spring Security的核心组件和优点。Spring Security 框架的整体优点 :高度可定制：通过Spring Security框架提供的多种配置选项，可以实现对Web应用程序的高度定制，从而满足特定的安全性需求。多种身份验证和授权机制：Spring Security框架支持多种身份验证和授权机制，如基于表单的认证、基于http基本认证、基于用户证书验证等。安全性高：通过过滤器实现用户身份认证和请求过滤，在确保应用程序可用性的同时，保证了应用程序的安全性。容易集成：Spring Security框架与Spring框架天然的结合在一起，可方便地集成到现有的Spring应用程序中。多种加密方式：Spring Security框架提供了多种加密认证方式，包括MD5、SHA、BCrypt等，支持普通密码和密码加盐等模式。4 . Redis框架Redis是一个开源的高性能、非关系型的内存数据结构存储系统，它支持多种数据结构，如字符串、哈希、列表、集合、有序集合等，同时也提供了一些高级功能，如事务、发布/订阅、Lua脚本等，可广泛应用于缓存、消息队列、计数器、实时排行榜等场景。Redis 框架的整体优点 :高性能：Redis的数据存储在内存中，读写速度非常快，而且支持多线程访问，保证了高并发访问时的性能。可扩展性好：Redis可以很方便地扩展到多个节点，实现数据的分布式存储和高可用性。数据结构多样化：Redis支持多种数据结构，如字符串、哈希、列表、集合、有序集合等，适合不同类型的数据存储和管理。丰富的功能：Redis提供了丰富的功能，如事务、发布/订阅、Lua脚本等，方便应用程序的开发和运维。易于使用和管理：Redis的命令简单易懂，同时提供了良好的客户端接口和管理工具，方便使用和管理。需求分析膳食小搭项目需要实现用户上传文件、用户论坛发帖、食物功能以及基于编辑距离算法、Jacquard相似度匹配算法和余弦相似度算法实现推荐系统等功能。用户上传文件：包括用户上传各种图片格式的食物图片，以及文件的存储、管理、查询和分类等功能。用户论坛发帖：用户可以在论坛中发布相关饮食话题，包括帖子的创建、浏览、回复和管理等功能。食物功能：包括对食物信息的管理，如食材名、营养信息、图片等，以及根据食材的营养信息计算营养价值和推荐合理搭配。推荐系统：根据精确的算法，在数据库中处理用户消费和购物车中的商品信息，为每个用户定制精准的推荐方案。系统设计思想数据层：使用MySQL作为主要的关系型数据库，用于存储用户个人信息、帖子内容等，同时使用Redis作为缓存，加快食物信息的查询速度。业务逻辑层：采用Spring和Spring Boot框架实现业务逻辑，包括用户身份验证、食物信息处理、推荐算法处理等。表示层：使用Spring MVC框架实现前台页面和后台管理页面，包括用户注册、登录、个人信息管理、食谱推荐等。用户论坛发帖功能：使用Spring MVC框架实现论坛页面的开发，采用Java EE中的后端技术实现。食物功能：使用Redis缓存和MySQL数据库存储食品信息，采用Spring Boot框架实现食品信息的查询、计算营养值、搭配推荐等功能。推荐系统：基于编辑距离算法、Jacquard相似度匹配算法和余弦相似度算法实现推荐系统的关键算法，使用Hadoop和Spark等大数据技术存储和处理用户数据，向用户提供个性化推荐服务。系统安全：采用Spring Security和JWT实现用户身份验证和授权功能，防止攻击者获取非法访问权限。详细设计数据层设计用户表：用于存储用户的基本信息，如用户名、密码、邮箱、手机号等。方案表：用于存储方案的基本信息，如方案名、方案描述、创建者等。帖子表：用于存储帖子的基本信息，包括标题、内容、作者等。地图表：用于存储人数分布地图的信息，包括地区、人数等。轮播图表：用于存储轮播图的基本信息，包括图片、标题、链接等。食物表：用于存储食物的基本信息，包括食物名称、食材、营养成分等。业务层设计用户管理：采用SpringSecurity和JWT等框架实现用户身份验证和授权，保障用户信息安全。同时，在业务层中实现用户的注册、登录、个人信息管理等功能。文件上传：采用上传组件hutools来实现文件上传功能，同时使用私有图床系统来存储用户上传的图片、文件等数据。论坛功能：采用Spring Boot框架实现论坛页面的开发，使用Java EE中的后端技术实现帖子的创建、浏览、回帖等功能。食物功能：采用Redis缓存和MySQL数据库存储食物信息，使用SpringBoot框架实现食物信息的查询、计算营养值、搭配推荐等功能，同时使用Gson等框架对JSON数据进行处理和解析。推荐系统设计：基于编辑距离算法、Jacquard相似度匹配算法和余弦相似度算法实现推荐系统的关键算法，向用户提供个性化推荐服务。表示层设计接口(API)：前端请求数据的接口，后端返回数据的接口。接口主要分为三种类型：CRUD(create、read、update、delete)接口：用于对数据库中数据进行增删改查操作，如食物列表、食物详情等接口。用户认证与授权接口：用于用户登录、注册、重置密码等操作。业务逻辑接口：自定义的业务相关接口。比如，根据用户的身体情况和营养需求，返回符合条件的膳食配餐方案等。控制器(Controller)：连接视图和接口，负责请求的处理。主要包括以下功能：接受并解析请求参数，对请求进行验证和过滤。调用模型层处理数据，根据业务逻辑生成响应数据。对响应数据进行封装，输出给客户端。除此之外，控制器还可包括一些常用的功能模块，如认证模块、权限验证模块等。模型(Model)：连接数据库层，负责数据的存储和处理。主要包括以下功能：定义数据库表结构，提供对表的增删改查等操作。根据业务需求，实现一些复杂的查询和计算逻辑，如膳食计算等。对外提供API接口，供上层控制器调用。
我的面试宝典AIJava框架篇打乱顺序解析 : B D当发现有多种类型的Bean时，@Primary注解会通知IoC容器优先使用它所标注的Bean进行注入；@Quelifier注解可以与@AutoWired注解组合使用，达到通过类型和名称一起筛选Bean的效果。解析 : CSpring MVC 拦截器包含三个方法：preHandle()、postHandle()、afterCompletion()。​ preHandle() 方法：该方方法在控制器方法前执行，其返回值表示是否中断后续操作。当其返回值为true时，表示继续向下执行；当其返回值为false时，会中断后续的所有操作（包括调用下一个拦截器和控制器类中的方法执行等）。 ​ postHandle()方法：该方法在控制器方法调用之后，且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。 ​ afterCompletion()方法：该方法在整个请求完成，即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。解析 : Cmethod属性代表指定请求的method的类型，value属性指请求的实际地址，params是指定request中一定要有的参数值。required是@RequestParam注解的属性，是指该参数是否为必传项，默认为true，表示请求中一定要传入对应的参数。解析 : C解析 : A拦截器需实现 HandlerInterceptor 接口，而 WebMvcConfigurer 接口是 MVC 配置类要实现的接口解析 : C 目标方法允许结束后，若发生异常，会先执行异常通知，再执行后置通知。返回通知仅在无异常时执行@Before:Before 通知，用于方法执行前增强 @AfterReturning ：After Returning 通知，方法正常执行返回后增强 @AfterThrowing：After Throwing 通知，方法执行通过抛出异常退出时 @After：After (Finally) 通知，方法执行退出时执行增强，不管是正常返回，还是抛出异常退出，相当于try{}catch{}finally{}中的finally的语句。 @Around：Around 通知，最强大的通知，环绕在目标方法前后执行。它有机会在方法运行之前和之后进行工作，并确定该方法何时、如何以及是否真正开始运行@EnableAutoConfiguration注解解析 : A B C D@EnableAutoConfiguration由@SpringBootApplication引入，它的主要功能是启动Spring应用程序上下文时进行自动配置，它会尝试猜测并配置项目可能需要的Bean。@Import是@EnableAutoConfiguration注解的组成部分，也是自动配置功能的核心实现者。@SpringBootApplication @SpringBootConfiguration @EnableAutoConfiguration @AutoConfigurationPackage @Import(AutoConfigurationPackages.Registrar.class) @Import(AutoConfigurationImportSelector.class) @ComponentScanSpringBoot的核心注解 : @SpringBootApplication注解包含三个注解@SpringBootConfiguration​@EnableAutoConfiguration​ 实现自动配置的关键 , 此注解又包含两个关键注解@AutoConfigurationPackage将主启动类所在包以及子包里面的所有组件扫描并加载到spring的容器中，所以我们开发过程中Controller层、Service层、Dao层的代码总是和主启动类在同一级目录或者次级目录之下。@Import(AutoConfigurationImportSelector.class)来作自动配置至于哪些才是需要自动配置的类呢，AutoConfigurationImportSelector类里面有一个方法selectImports()，该方法通过层层调用，最终会调用一个方法loadSpringFactories()，此方加载所有的spring.factories文件，而spring.factories文件中的数据以（key-value）的形式存储，key就是EnableAutoConfiguration，value自然就是那些需要自动配置的类的全类名了，解析这个文件然后返回需要做自动配置的类的全类名@ComponentScanSpring常用容器解析 : A C​ A，B考察BeanFactory与FactoryBean。BeanFactory是Spring容器的接口，FactoryBean是Spring中用于实现“工厂Bean”的接口。​ C 是ApplicationContext，是BeanFactory的子接口。​ D应该是干扰选项，暂时没有找到相关解释。 另外，BeacFactory和ApplicationContext其实是有继承关系的两个接口。个人觉得题目所说的，“属于Spring容器的类”，存在问题。Spring AOP解析 : D 在运行时织入 , 需要为目标生成代理对象MySQL数据库篇MySQL技能树MySQLl触发器 : http://t.csdn.cn/2UGaQMySQL视图 : http://t.csdn.cn/0qUVaMySQL存储过程 : http://t.csdn.cn/B062N一 . 基础篇相关概念 、三大范式 、基本操作 、约束 、事务 、索引在MySQL中，"@@"和"@"符号用于引用系统和用户定义的变量，其区别在于：@@var_name：引用系统预定义的变量，如@@version、@@global.tx_isolation、@@autocommit等。这些变量的值是数据库服务器针对会话级别或全局级别的设置。@var_name：引用自定义会话级别变量，在当前会话中定义该变量，并将值赋给变量。可以使用SET 或 SELECT语句来声明和赋值变量，例如：SET @my_var := 10; SELECT @my_var;。1 . SQL分类1. 1 数据定义语言(DDL) Definition用来操作数据库、表、列等； 常用语句：create 、 alter 、drop1. 2 数据操作语言(DML) Manipulation用来操作数据库中表里的数据；常用语句：insert 、 update 、 deleteinsert-- 用法 insert into 'student' ('name') values ('At'); insert into 'student' ('name','pwd') values ('At','123'); -- 省略字段(值必须一一对应) , isdelete等公共字段可以不填 INSERT INTO `student` values ('xxx','xxx','xxx','xxx','xxx','xxx'); -- 语法 INSERT INTO 表名([字段1,字段2..])VALUES('值1','值2'..),[('值1','值2'..)..]; update-- 语法 UPDATE 表名 SET 字段1=值1,[字段2=值2...] WHERE 条件[]; -- 修改名字,指定条件 UPDATE `student` SET `name`='zsr204' WHERE id=1; -- 不指定条件的情况,会改动所有表 UPDATE `student` SET `name`='zsr204'; -- 修改多个属性 UPDATE `student` SET `name`='zsr',`address`='湖北' WHERE id=1; -- 通过多个条件定位数据 UPDATE `student` SET `name`='zsr204' WHERE `name`='zsr' AND `pwd`='200024';delete-- 删除数据(避免这样写,会全部删除) DELETE FROM `student`; -- 删除指定数据 DELETE FROM `student` WHERE id=1;关于DELETE删除的问题，重启数据库现象：INNODB 自增列会从1开始（存在内存当中，断电即失）MYISAM 继续从上一个子增量开始（存在内存当中，不会丢失）truncate ：完全清空一个数据库表，表的结构和索引约束不会变！ 不支持数据回滚1. 3 数据库控制语言(DCL) Control用来操作访问权限和安全级别； 常用语句：grant 、deny1. 4 数据查询语言(DQL) Query用来查询数据 常用语句：select-- 基本数据 -- 创建student表 CREATE TABLE student ( sid CHAR(6), sname VARCHAR(50), age INT, gender VARCHAR(50) DEFAULT 'male' ); -- 向student表插入数据 INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1007', 'hjop', 16, 'male'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1008', 'tyop', 15, 'female'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1009', 'nhmk', 13, 'male'); INSERT INTO student (sid,sname,age,gender) VALUES ('S_1010', 'xdfv', 17, 'female');-- 查询所有 select * from student; -- 查询指定字段 select sid,sname from student; -- 数据过滤 select distinct gender from student; -- 查询出来的所有age全部加10 select sname,age+10 from student;distinct作用 : 从查询结果中过滤重复数据在select查询语句中distinct关键字只能用在第一个所查列名之前。查询中的算术运算符在select查询语句中还可以使用加减乘除运算符。2 . 三大范式第一范式每列的值具有原子性，不可再分割第二范式在第一范式的基础上建立 , 如果表是单主键，那么主键以外的列必须完全依赖于主键；如果表是复合主键，那么主键以外的列必须完全依赖于主键，不能仅依赖主键的一部分。第三范式也是在第二范式的基础撒花姑娘建立的 , 意思是 : 非主键列之间不能相关依赖。3 . 基本操作完整的流程3 .1 库的操作0-- 如果存在先删除 drop database if exists 数据库名称; -- 创建数据库 create database 数据库名称; -- 创建数据库后查看该数据库基本信息MySQL命令 show create database 数据库名称; -- 删除命令 drop database 数据库名称; -- 展示所有数据 show databases; -- 更改字符集 alter database 数据库名称 character set gbk; -- 切换数据库 use 数据库名称; -- 查看当前使用的数据库 select database();3 . 2 表的操作创建数据表一个完整的用户表-- 用户表 create table if not exists user ( id bigint auto_increment comment 'id' primary key, userAccount varchar(256) not null comment '账号', userPassword varchar(512) not null comment '密码', userName varchar(256) null comment '用户昵称', userAvatar varchar(1024) null comment '用户头像', userProfile varchar(512) null comment '用户简介', userRole varchar(256) default 'user' not null comment '用户角色：user/admin/ban', createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', isDelete tinyint default 0 not null comment '是否删除' ) comment '用户' collate = utf8mb4_unicode_ci;展示库中所有的表和查看数据表-- 查看所有表 show tables; -- 查询基本信息 show create table user; -- 查看字段信息 desc user;修改数据表修改表名、修改字段名、修改字段 数据类型…等等-- 修改表名 (下文还是user) alter table user rename to use; -- 修改字段 , 修改userName 为Uername (下文还是userName) alter table user change userName username varchar(10); -- 修改字段名 alter table user modify userName int; -- 增加字段 (新增otherID) alter table user add otherID int; -- 删除字段 alter table user drop otherID;删除数据表drop table 表名;4 . 约束约束分为 : 主键约束 、非空约束、默认值约束、外键约束、唯一性约束4 . 1 主键约束用于唯一的标识表中的每一行。被标识为主键的数据在表中是唯一的且其值不能为空-- 方式一 create table student( id int primary key, name varchar(20) ); -- 方式二 create table student( id int, name varchar(20), primary key(id) );4 . 2 非空约束即 NOT NULL指的是字段的值不能为空create table student02( id int name varchar(20) not null );4 . 2 默认值约束即 default 用于给数据表中的字段指定默认值create table student( id int, name varchar(20), gender varchar(10) default 'male' );4 . 4 唯一性约束即UNIQUE用于保证数据表中字段的唯一性 , 可以设置多个create table student( id int, name varchar(20) unique );4 . 5 外键约束常用于多张表之间的约束 , 主从关系-- 在创建数据表时语法如下： constraint 外键名 foreign key (从表外键字段) references 主表 (主键字段) -- 将创建数据表创号后语法如下： alter table 从表名 add constraint 外键名 foreign key (从表外键字段) references 主表 (主键字段);示例 :-- 创建student表 create table student( id int primary key, name varchar(20) ); -- 创建班级表 create table class( classid int primary key, studentid int ); -- 将班级表中的studentid设置为外键 叫fk_class_studentid alter table class add constraint fk_class_studentid foreign key(studentid) references student(id); 数据一致性建立外键是为了保证数据的完整和统一性 , 如果主表中的数据被删除或修改从表中对应的数据 , 从表对应的数据也应该被删除删除外键-- 以上述为例 alter table class drop foreign key fk_class_studentid;5 . 事务四个特性原子性（Atomicity）：指事务是一个不可分割的最小工作单位，事务中的操作只有都发生和都不发生两种情况一致性（Consistency）：事务必须使数据库从一个一致状态变换到另外一个一致状态，举一个栗子，李二给王五转账50元，其事务就是让李二账户上减去50元，王五账户上加上50元；一致性是指其他事务看到的情况是要么李二还没有给王五转账的状态，要么王五已经成功接收到李二的50元转账。而对于李二少了50元，王五还没加上50元这个中间状态是不可见的。隔离性（Isolation）：一个事务的执行不能被其他事务干扰，即一个事务内部的操作及使用的数据对并发的其他事务是隔离的，并发执行的各个事务之间不能互相干扰。持久性（Durability）：一个事务一旦提交成功，它对数据库中数据的改变将是永久性的，接下来的其他操作或故障不应对其有任何影响。事务分类事务分为隐式事务和显式事务两种。DML语句（insert、update、delete）就是隐式事务。显示事务：该事务具有明显的开启和结束标记；也是本文重点要讲的东西。使用显式事务的前提是你得先把自动提交事务的功能给禁用。禁用自动提交功能就是设置autocommit变量值为0（0:禁用 1:开启）隐式事务：该事务没有明显的开启和结束标记，它们都具有自动提交事务的功能；不妨思考一下，update语句修改数据时，是不是对表中数据进行改变了，它的本质其实就相当于一个事务。二 . 进阶篇此篇包含聚合函数及其他函数的运用 、条件查询的各种关键字 、关联查询 、子查询 、连接查询2. 1 函数聚合函数count()统计表中数据的行数或者统计指定列其值不为NULL的数据个数select count(*) from student;max()计算指定列的最大值，如果指定列是字符串类型则使用字符串排序运算select max(age) from student;min()计算指定列的最小值，如果指定列是字符串类型则使用字符串排序运算select sname,min(age) from student;sum()计算指定列的数值和，如果指定列类型不是数值类型则计算结果为0select sum(age) from student;avg()计算指定列的平均值，如果指定列类型不是数值类型则计算结果为select avg(age) from student;其他函数-- 时间函数 SELECT NOW(); SELECT DAY (NOW()); SELECT DATE (NOW()); SELECT TIME (NOW()); SELECT YEAR (NOW()); SELECT MONTH (NOW()); SELECT CURRENT_DATE(); SELECT CURRENT_TIME(); SELECT CURRENT_TIMESTAMP(); SELECT ADDTIME('14:23:12','01:02:01'); SELECT DATE_ADD(NOW(),INTERVAL 1 DAY); SELECT DATE_ADD(NOW(),INTERVAL 1 MONTH); SELECT DATE_SUB(NOW(),INTERVAL 1 DAY); SELECT DATE_SUB(NOW(),INTERVAL 1 MONTH); SELECT DATEDIFF('2019-07-22','2019-05-05'); -- 字符串函数 -- 连接函数 SELECT CONCAT () -- 用于在字符串中查找指定字符串或子字符串的位置（索引） SELECT INSTR (); -- 统计长度 SELECT LENGTH(); -- 数学函数 -- 绝对值 SELECT ABS(-136); -- 向下取整 SELECT FLOOR(3.14); -- 向上取整 SELECT CEILING(3.14);2. 2 条件查询关系运算符关系运算符说明=等于<>不等于!=不等于<小于<=小于等于>大于>=大于等于in关键字查询in关键字用于判断某个字段的值是否在指定集合中。如果字段的值恰好在指定的集合中，则将字段所在的记录将査询出来。-- 查询这俩 select * from student where sid in ('S_1002','S_1003'); -- 查询除过s_1001以外的 select * from student where sid not in ('S_1001'); between and关键字查询between and 用于判断某个字段的值是否在指定的范围之内。如果字段的值在指定范围内，则将所在的记录将查询出来-- 查询15到18的学生 select * from student where age between 15 and 18; -- 查询不在这个区间的 select * from student where age not between 15 and 18;空值查询在MySQL中，使用 IS NULL关键字判断字段的值是否为空值。请注意：空值NULL不同于0，也不同于空字符串-- 查询不为空 select * from student where sname is not null;and关键字查询在MySQL中可使用AND关键字可以连接两个或者多个查询条件。select * from student where age>15 and gender='male';or 关键字查询在使用SELECT语句查询数据时可使用OR关键字连接多个査询条件。在使用OR关键字时，只要记录满足其中任意一个条件就会被查询出来select * from student where age>15 or gender='male';like关键字查询MySQL中可使用LIKE关键字可以判断两个字符串是否相匹配-- 查询sname中与wang匹配的学生信息 select * from student where sname like 'wang';含有%通配的字符串-- 查询学生姓名以li开始的 select * from student where sname like 'li%'; -- 查询学生姓名以g结尾的 select * from student where sname like '%g'; -- 查询学生姓名包含s的 select * from student where sname like '%s%';含有__通配的字符串_-- 查询学生姓名以zx开头且长度为4的 select * from student where sname like 'zx__'; -- 查询学生姓名以g结尾且长度为4的 select * from student where sname like '___g';limit限制查询当执行查询数据时可能会返回很多条记录，而用户需要的数据可能只是其中的一条或者几条select * from student order by age asc limit 3;group by分组查询俗地理解为：通过GROUP BY将原来的表拆分成了几张小表。order by 排序查询2. 3 关联查询基本数据DROP TABLE IF EXISTS student; DROP TABLE IF EXISTS class; -- 创建班级表 CREATE TABLE class( cid int(4) NOT NULL PRIMARY KEY, cname varchar(30) ); -- 创建学生表 CREATE TABLE student( sid int(8) NOT NULL PRIMARY KEY, sname varchar(30), classid int(8) NOT NULL ); -- 为学生表添加外键约束 ALTER TABLE student ADD CONSTRAINT fk_student_classid FOREIGN KEY(classid) REFERENCES class(cid); -- 向班级表插入数据 INSERT INTO class(cid,cname)VALUES(1,'Java'); INSERT INTO class(cid,cname)VALUES(2,'Python'); -- 向学生表插入数据 INSERT INTO student(sid,sname,classid)VALUES(1,'tome',1); INSERT INTO student(sid,sname,classid)VALUES(2,'lucy',1); INSERT INTO student(sid,sname,classid)VALUES(3,'lili',2); INSERT INTO student(sid,sname,classid)VALUES(4,'domi',2); 查询-- 查询Java班的所有学生 select * from student where classid=(select cid from class where cname='Java');2. 4 连接查询举例student表学号姓名性别001Alice女002Bob男003Charlie男004David男005Eve女course表课程号课程名学分001数据结构4002操作系统5003计算机网络3004编译原理4005数据库系统原理5SC 表学号课程号成绩001001900010028500100392002002880020038900200495003001800030038700300596004001850040028200400389005001900050028800500393出几道子查询不用join的题目(分组并having过滤啥的各种函数),并给出答案问题 : 1> 查询学生姓名、课程名和成绩SELECT student.姓名, course.课程名, sc.成绩 FROM student JOIN sc ON student.学号 = sc.学号 JOIN course ON course.课程号 = sc.课程号; 2> 查询每个学生的平均成绩，并按照平均成绩从高到低排序。SELECT s.学号, s.姓名, AVG(sc.成绩) AS 平均成绩 FROM 学生 s INNER JOIN SC sc ON s.学号 = sc.学号 GROUP BY s.学号, s.姓名 ORDER BY 平均成绩 DESC;3> 查询每门课程的平均成绩，并按照平均成绩从高到低排序。SELECT c.课程号, c.课程名, AVG(sc.成绩) AS 平均成绩 FROM course c INNER JOIN SC sc ON c.课程号 = sc.课程号 GROUP BY c.课程号, c.课程名 ORDER BY 平均成绩 DESC;4> 查询选修了数据结构课程的男生中，成绩最高的学生的学号、姓名和成绩。SELECT s.学号, s.姓名, MAX(sc.成绩) AS 成绩 FROM 学生 s INNER JOIN SC sc ON s.学号 = sc.学号 WHERE s.性别 = '男' AND sc.课程号 = '001' GROUP BY s.学号, s.姓名 ORDER BY 成绩 DESC LIMIT 1;内连接查询内连接(Inner Join)又称简单连接或自然连接，是一种非常常见的连接查询。内连接使用比较运算符对两个表中的数据进行比较并列出与连接条件匹配的数据行，组合成新的 记录。也就是说在内连接查询中只有满足条件的记录才能出现在查询结果中。select student.name , sc.grade from sc inner join student on sc.sno = student.sno; -- 其他举例 -- 查询学员所属的年级（学号，学生姓名，年级名称） SELECT `StudentNo`,`StudentName`,`GradeName` FROM student s INNER JOIN grade g ON s.GradeID=g.GradeID; -- 查询科目所属的年级 SELECT `SubjectName`,`GradeName` FROM `subject` s INNER JOIN `grade` g ON s.GradeID=g.GradeID; -- 查询列参加程序设计考试的同学信息（学号，姓名，科目名，分数） SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult` FROM student s INNER JOIN result r on s.StudentNo=r.StudentNo INNER JOIN `subject` sub on r.SubjectNo=sub.SubjectNo where SubjectName='课程设计';外连接查询在使用内连接查询时我们发现：返回的结果只包含符合查询条件和连接条件的数据。但是，有时还需要在返回查询结果中不仅包含符合条件的数据，而且还包括左表、右表或两个表中的所有数据，此时我们就需要使用外连接查询。左外连接查询右外连接查询2. 5 子查询举例1> 查询每个学生的平均分SELECT s.学号, s.姓名, AVG(sc.成绩) AS 平均分 FROM student AS s, sc WHERE s.学号 = sc.学号 GROUP BY s.学号, s.姓名;2> 查询成绩优秀的前三名学生SELECT s.学号, s.姓名, SUM(sc.成绩) AS 总成绩 FROM student AS s, sc WHERE s.学号 = sc.学号 GROUP BY s.学号, s.姓名 ORDER BY 总成绩 DESC LIMIT 3;3>查询选修了所有课程的学生SELECT s.学号, s.姓名 FROM student AS s WHERE NOT EXISTS( SELECT c.课程号 FROM course AS c WHERE NOT EXISTS( SELECT sc.学号 FROM sc WHERE sc.课程号 = c.课程号 AND sc.学号 = s.学号 ) )查询分数最高的学生及其所修的课程和成绩-- join on SELECT student.姓名, course.课程名, sc.成绩 FROM student JOIN sc ON student.学号 = sc.学号 JOIN course ON course.课程号 = sc.课程号 WHERE sc.成绩 = ( SELECT MAX(成绩) FROM sc WHERE 学号 = student.学号 ); -- and SELECT S.姓名, C.课程名, SC.成绩 FROM student S, course C, sc SC WHERE S.学号 = SC.学号 AND C.课程号 = SC.课程号 AND SC.成绩 = ( SELECT MAX(成绩) FROM sc WHERE 学号 = S.学号 );带比较运算符比较运算符前面我们提到过得，就是>、<、=、>=、<=、!=等select * from class where cid=(select classid from student where sname='张三'); select * from class where cid>(select classid from student where sname='张三');带exists关键字EXISTS关键字后面的参数可以是任意一个子查询， 它不产生任何数据只返回TRUE或FALSE。当返回值为TRUE时外层查询才会 执行select * from class where exists (select * from student where sname='王五');带any关键字ANY关键字表示满足其中任意一个条件就返回一个结果作为外层查询条件。select * from class where cid > any (select classid from student);带all关键字ALL关键字与ANY有点类似，只不过带ALL关键字的子査询返回的结果需同时满足所有内层査询条件。select * from class where cid > all (select classid from student);重要（从关键字分析）：查询语句的书写顺序和执行顺序select ==> from ==> where ==> group by ==> having ==> order by ==> limit查询语句的执行顺序from ==> where ==> group by ==> having ==> select ==> order by ==> limit2 . 6 视图CSDN视图不是表，不保存数据，只是一张虚拟表；示例: ​ 数据库视图是在关系数据库中定义的虚拟表格。它是一个基于一个或多个数据库表的查询结果集，并且与查询结果集相关联的视图是动态的。与实际的数据库表格不同，视图并不具有自己的数据，而是从一个或多个实际数据库表格中提取出数据，并根据某种规则呈现出来。视图的作用在于提供一种通过表的连结机制而过滤的数据表视图机制。一般情况下，视图只存储视图定义，而不存储数据。在访问视图时，查询解析器会使用视图定义来生成查询语句，并将其发送给关系数据库 引擎执行。因此，使用视图可以在不修改基础表结构的情况下，实现数据的不同组合、排序、分组和筛选等处理方式。同时，视图还可以提供一个对基础表的安全性和完整性进行控制的手段，以保护敏感数据的访问。-- 以下是一个简单的视图示例，假设我们有一个名为“students”的表格，其中包含学生的成绩和基本信息，我们可以通过创建一个“优秀学生”的视图来筛选出所有分数大于等于80分（即“优秀”的学生）的学生信息： CREATE VIEW excellent_students AS SELECT name, score FROM students WHERE score >= 80; -- 这样一来，我们就可以通过访问excellent_students视图来查询包含所有“优秀”的学生信息了： SELECT * FROM excellent_students;总之，数据库视图是一种虚拟的、动态的表格，可以根据自定义的规则从一个或多个实际数据库表格中提取数据，并提供一种安全、灵活、高效的操作方式。它在关系数据库实现中扮演着重要的角色。相关的MySQL指令操作指令代码创建视图CREATE VIEW 视图名(列1，列2...) AS SELECT (列1，列2...) FROM ...;使用视图当成表使用修改视图CREATE OR REPLACE VIEW 视图名 AS SELECT [...] FROM [...];查看数据库已有视图SHOW TABLES [like...];（可以使用模糊查找）查看视图详情DESC 视图名或者SHOW FIELDS FROM 视图名视图条件限制[WITH CHECK OPTION]​创建视图创建视图和查询相比，增加了前面的create view 视图名 ascreate view 视图名(列1，列2...) as select (列1，列2...) from ...;查询视图正常当一张表来使用就行select * from 视图名称 [可跟条件];修改视图create or replace view 视图名 as select [...] from [...];查看视图show tables; -- 查看视图详情 , 俩都行 desc 视图名; show fields from 视图名;2 . 7 存储过程就是数据库 SQL 语言层面的代码封装与重用。存储过程：（PROCEDURE）是事先经过编译并存储在数据库中的一段SQL语句的集合。调用存储过程可以简化应用开发人员的很多工作，减少数据在数据库和应用服务器之间的传输，对于提高数据处理的效率是很有好处的。存储过程就类似于Java中的方法，需要先定义，使用时需要调用。存储过程可以定义参数，参数分为IN、OUT、INOUT类型三种类型。in代表输入参数（默认情况下为in参数），表示该参数的值必须由调用程序指定。out代表输出参数，表示该参数的值经存储过程计算后，将out参数的计算结果返回给调用程序。inout代表即时输入参数，又是输出参数，表示该参数的值即可有调用程序制定，又可以将inout参数的计算结果返回给调用程序。格式-- 调用 CALL xxx(); -- 定义 DELIMITER // CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE 数据库名.存储过程名([in变量名 类型,out 参数 2，...]) /*LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'*/ BEGIN [DECLARE 变量名 类型 [DEFAULT 值];] 存储过程的语句块; END// -- DELIMITER ; 存储过程中的语句必须包含在BEGIN和END之间。DECLARE中用来声明变量，变量默认赋值使用的DEFAULT，语句块中改变变量值，使用SET 变量=值；示例查询student表中的sex为男的有多少个人。DELIMITER // CREATE PROCEDURE `demo`.`demo2`(IN s_sex CHAR(1),OUT s_count INT) -- 存储过程体 BEGIN -- 把SQL中查询的结果通过INTO赋给变量 SELECT COUNT(*) INTO s_count FROM student WHERE sex= s_sex; SELECT s_count; END// -- DELIMITER ; -- @s_count表示测试出输出的参数 CALL demo2 ('男',@s_count); 管理显示存储过程SHOW PROCEDURE STATUS显示存储过程的源码SHOW CREATE PROCEDURE 存储过程名;删除存储过程DROP PROCEDURE 存储过程名;Mybatis与存储过程<parameterMap type="savemap" id=“usermap"> <parameter property="name" jdbcType="VARCHAR" mode="IN"/> <parameter property="sex" jdbcType="CHAR" mode="IN"/> <parameter property="result" jdbcType="VARCHAR" mode="OUT"/> </parameterMap> <insert id="saveUserDemo" parameterMap="savemap" statementType="CALLABLE"> {call saveuser(?, ?, ?)} </insert >HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", "Jim"); map.put("sex","男"); //调用 userDao.saveUserDemo(map); map.get(“result”);//获得输出参数2 . 8 触发器触发器是一种特殊的存储过程，它在试图更改触发器所保护的数据时自动执行。在MySQL中，只有执行insert,delete,update操作时才能触发触发器的执行；触发器的这种特性可以协助应用在数据库端确保数据的完整性，日志记录，数据校验等操作；使用别名OLD和NEW来引用触发器中发生变化的记录内容，这与其他的数据库是相似的。现在触发器还只支持行级触发，不支持语句级触发；创建触发器1 . 创建只有一个执行语句的触发器create trigger 触发器名 before|after 事件 on 表名 for each row 语句;eg: 当给user表中插入一条数据时 , user_logs添加日志create trigger trigger_test1 after insert on user for each row insert into user_logs values(NULL,now(),'new');2 . 创建多个执行语句的触发器create trigger 触发器名 before|after 事件 on 表名 foreach row begin 语句 end;三 . 应用篇JDBC 、Mybatis 、Mybatis-PlusJava篇Linux篇理论篇1 . Linux的基本使用1 . 常用命令命令格式 :command [-options] [parameter]command ：命令名，相应功能的英文单词或单词的缩写[-options] ：选项，可用来对命令进行控制，也可以省略parameter ：传给命令的参数，可以是 零个、一个 或者 多个帮助命令-help 显示对应命令的帮助信息-man 查阅对应命令的使用手册操作键功能空格键显示手册页的下一屏回车键一次滚动手册页的一行b回滚一屏f前滚一屏q退出常用命令序号命令英文作用1lslist 2pwd 3cd 4touch 5mkdir 6rm 7clear 2 . 其他命令3 . 文件和目录的常用命令4 . 系统信息相关命令5 . 用户权限相关命令6 . 远程管理常用命令2 . 实战篇windows平台下 , 做一个类似cmd的网站Git篇
慢慢更新SpringSecurity的配置方法import com.example.demo.common.GlobalExceptionHandler; import com.example.demo.filter.JwtAuthenticationTokenFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; @Autowired private GlobalExceptionHandler authenticationFailureHandler; //创建BCryptPasswordEncoder注入容器 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http //关闭csrf .csrf().disable() //不通过Session获取SecurityContext .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() // 对于登录接口 允许匿名访问 // .antMatchers("/**").permitAll() .antMatchers("/user/login","/user/register").permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() .and() //其他异常处理 .formLogin() .failureHandler(authenticationFailureHandler) .and() //异常处理 .exceptionHandling() .authenticationEntryPoint((request, response, e) -> { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpStatus.FORBIDDEN.value()); response.getWriter().write("登录失效或未登录"); }) .accessDeniedHandler((request, response, e) -> { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpStatus.FORBIDDEN.value()); response.getWriter().write("无权访问"); }); //把token校验过滤器添加到过滤器链中 http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }