Golang 后端面经

文章目录

  • 一、Golang
    • golang GMP模型
    • Golang中make和new的区别
    • Golang内存逃逸,情况
    • go内存对齐原则
    • map的key值可以是函数、map和切片吗?
    • channel类型可以比较吗
    • 容量为1的channel在什么情况下会堵塞(除了常见的)
    • 多线程同时读写map中不同的key,一个线程只会读写一个key,会发送什么
    • map不安全,你要怎么解决 只能用go
    • 检查数据竞争
    • 实现了一个web的server,如何设置这个server返回的response的类型,比如说是一个图片一个视频一个json
    • 快速定位死锁
    • 用户从客户端访问一个页面,webserver如何主动的给这个页面推送一个通知
    • singleflght是使用什么方式去通知其他线程,其他线程怎么阻塞的
    • 不用waitgroup怎么实现这部分
    • slice是\[]int{1,2},把它传入一个函数,修改第一项的值为3,函数结束,原来slice值改变了吗
    • 如果函数是新建一个list等于append原来的slice,list=append(slice,3),调用完这个函数后在函数的外部打印这个原来slice的长度是多少,新的是多少,地址改变了吗,指向的原来的数组呢
    • a和b两个线程,a里面有defer recover,a里面新开了一个b,b没写defer recover,b发生了panic,ab两个线程会发生什么情况
    • 在函数参数传递一个非指针的互斥锁会发生什么事情?为什么会发生?
    • jwt鉴权管理实现怎么做的,怎么实现的鉴权,修改了token它怎么解析,为什么这么解析,原理是什么
    • 详细说一下令牌桶算法的实现
    • golang 垃圾回收机制
    • go 和 C++的区别,各有什么优劣?
    • MVCC
    • go中的并发utils了解多少?
    • 对consul的了解
    • 拦截器如何实现
    • 删除slice中间一个元素
  • 二、计算机网络
    • TCP和UDP的区别,TCP的三次握手四次挥手。
    • TCP的三次握手(Three-way Handshake)
    • TCP 的四次挥手
    • protobuf知道吗?thrift了解吗?什么原理?
  • 三、Mysql
    • 优化过sql吗,数据库是部署在哪里的,讲一个你认为最好的sql优化例子
    • mysql部署在阿里云上,如何找到最慢的sql语句
    • 用过gorm,如果一张上百万的数据的表,要新建一个字段的索引,如何保证线上的服务尽量少的被影响
    • MYSQL 索引有什么用?索引的数据结构说一下。什么情况下会失效?
  • 四、Redis
    • redis是单线程的还是多线程的?为什么快?适用于什么场景?
    • redis基本数据类型
    • redis写回策略你了解哪些?

一、Golang

golang GMP模型

Go 语言的并发模型基于 goroutine 和 Go runtime 的调度器。GMP 模型是 Go runtime 用来管理 goroutine 并发执行的核心机制,其中包含三个关键组成部分:G(Goroutine)、M(Machine)、P(Processor)。下面是对 GMP 模型的详细解释。

Goroutine(G)

G 表示 Goroutine,即 Go 语言中的轻量级线程。Goroutine 是由 Go runtime 管理的用户态线程,具有更低的创建和销毁成本。
每个 G 包含一个函数、栈、程序计数器和其他元数据。
Machine(M)

M 表示 Machine,可以理解为操作系统的线程。M 是实际执行 goroutine 的实体。
M 负责在操作系统层面管理和调度资源,如 CPU 和内存。
一个 M 可以绑定多个 G,并在合适的时候切换执行它们。
Processor(P)

P 表示 Processor,是 Go runtime 中用于调度 G 的逻辑处理器。
P 的数量由 GOMAXPROCS 环境变量决定,表示 Go 应用程序能并发执行的最大 CPU 核数。
P 管理一个运行队列,存储要在该处理器上运行的 goroutine。
GMP 关系
每个 P 绑定一个 M 执行 goroutine。
每个 M 执行一个 P 中的 goroutine。
G 被分配给 P,并由 M 执行。
GMP 模型的工作原理
创建 Goroutine

当 Go 程序创建一个新的 goroutine(如使用 go func()),G 会被分配到某个 P 的运行队列中。
调度 Goroutine

P 维护一个本地运行队列,存储要执行的 goroutine。
M 通过 P 从本地运行队列中取出 G 并执行。
如果 P 的本地运行队列为空,P 可以从全局运行队列或其他 P 的本地运行队列中窃取工作。
执行 Goroutine

M 负责实际执行 G。M 可以在执行过程中进行上下文切换(如遇到 I/O 操作、系统调用等),从而允许其他 G 继续执行。
当 G 执行完毕或被阻塞时,M 会将其放回队列,并从 P 中获取下一个 G 执行。
工作窃取

如果 P 的本地运行队列为空,P 可以从全局运行队列或其他 P 的本地运行队列中窃取 goroutine,以保证工作负载的平衡。

Golang中make和new的区别

new是分配内存,返回指针,但没有初始化,值是类型默认值
make 只能用于slice、map、channel对象的初始化

Golang内存逃逸,情况

内存逃逸是指栈上的变量逃逸到堆中。
情况:(1)函数返回指针变量,则函数中的变量逃逸到堆中。

package mainimport "fmt"func foo() *int {x := 42return &x
}func main() {p := foo()fmt.Println(*p)
}

(2)函数闭包:当局部变量被闭包引用时,变量会逃逸到堆上。
闭包函数adder里的sum就会逃逸到堆中。

package mainimport "fmt"// adder 返回一个闭包函数
func adder() func(int) int {sum := 0return func(x int) int {sum += xreturn sum}
}func main() {pos, neg := adder(), adder()for i := 0; i < 10; i++ {fmt.Println(pos(i), neg(-2*i))}
}

go内存对齐原则

基础对齐原则:每个类型的地址必须是其类型大小的倍数。例如,int32 类型的变量的地址必须是 4 的倍数,int64 类型的变量的地址必须是 8 的倍数。
结构体对齐:结构体的每个字段必须按照它们自身的对齐要求对齐,同时结构体的整体大小必须是其最大字段对齐要求的倍数。

package mainimport ("fmt""unsafe"
)type A struct {a int8   // 1 byteb int32  // 4 bytesc int64  // 8 bytes
}type B struct {a int8   // 1 byteb int8   // 1 bytec int64  // 8 bytesd int32  // 4 bytes
}func main() {fmt.Println("Size of struct A:", unsafe.Sizeof(A{})) // Output: 16fmt.Println("Size of struct B:", unsafe.Sizeof(B{})) // Output: 24
}

结构体A : 一共占16字节
a占用1字节,
b占用4字节 按基础对齐原则需要从4的整数倍地址开始,a后面需要补3个字节。
c是8字节,前面正好有8个字节了,不需要补。

结构体B: a占用1字节,b占用1字节
c占用8字节,按基础对齐原则,则b后面需要补6个字节,从而让c在8的倍数地址开始。
d占用4字节,现在一共是20个字节,不满足结构体对齐原则,需要补刀4和8的倍数,也就是24字节。

数据结构:

map的key值可以是函数、map和切片吗?

map 的键必须是可以比较的,所以不可以

channel类型可以比较吗

可以比较,但比较的是两个channel是不是引用同一个通道

容量为1的channel在什么情况下会堵塞(除了常见的)

当接收者没有准备好接收数据时:即使 channel 容量为 1,当通道已满且没有 Goroutine 在接收时,发送操作将阻塞。

多线程同时读写map中不同的key,一个线程只会读写一个key,会发送什么

在 Go 中,内置的 map 不是并发安全的,即使是对不同的 key 进行操作,也会导致数据竞争,从而引发未定义的行为。

map不安全,你要怎么解决 只能用go

在 Go 中,map 是并发不安全的。如果多个 goroutine 并发访问同一个 map,且至少有一个 goroutine 会对 map 进行写操作,就可能会导致竞态条件。
使用 sync.Mutex 进行显式加锁
使用 sync.Mutex 可以实现对 map 的显式加锁,保证并发安全。

使用 sync.Map
sync.Map 是 Go 1.9 引入的一个并发安全的 map,适用于读多写少的场景。与传统的 map 不同,sync.Map 不需要显式加锁。

检查数据竞争

可以使用 Go 的内置工具
go run -race 或
go test -race 来检查数据竞争。

实现了一个web的server,如何设置这个server返回的response的类型,比如说是一个图片一个视频一个json

可以通过设置 HTTP 头部的 Content-Type 来指定返回内容的类型:
Json:application/json
图片:image/png
视频:video/mp4

package mainimport ("encoding/json""net/http"
)func jsonHandler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "application/json")json.NewEncoder(w).Encode(map[string]string{"hello": "world"})
}func imageHandler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "image/png")// Write image data to the response
}func videoHandler(w http.ResponseWriter, r *http.Request) {w.Header().Set("Content-Type", "video/mp4")// Write video data to the response
}func main() {http.HandleFunc("/json", jsonHandler)http.HandleFunc("/image", imageHandler)http.HandleFunc("/video", videoHandler)http.ListenAndServe(":8080", nil)
}

快速定位死锁

使用 Go 的内置工具 go run -race 可以帮助检测并报告潜在的死锁。此外,还可以使用 runtime 包中的 Goroutine 和 Mutex 调试函数来手动检查死锁。

用户从客户端访问一个页面,webserver如何主动的给这个页面推送一个通知

可以使用 WebSocket 来实现服务器主动推送通知给客户端。

package mainimport ("fmt""net/http""github.com/gorilla/websocket"
)var upgrader = websocket.Upgrader{}func wsHandler(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {fmt.Println("Upgrade error:", err)return}defer conn.Close()for {_, msg, err := conn.ReadMessage()if err != nil {fmt.Println("Read error:", err)break}fmt.Printf("Received: %s\n", msg)}
}func main() {http.HandleFunc("/ws", wsHandler)http.ListenAndServe(":8080", nil)
}

singleflght是使用什么方式去通知其他线程,其他线程怎么阻塞的

singleflight 使用一个共享的等待组(sync.WaitGroup)来阻塞并通知其他线程。当一个线程发起一个请求时,其他线程会等待,直到第一个线程完成并通知它们。

不用waitgroup怎么实现这部分

可以用通道实现

slice是[]int{1,2},把它传入一个函数,修改第一项的值为3,函数结束,原来slice值改变了吗

是的,原来的 slice 值会改变,因为 slice 是引用类型。

package mainimport "fmt"func modify(slice []int) {slice[0] = 3
}func main() {s := []int{1, 2}modify(s)fmt.Println(s) // 输出: [3 2]
}

如果函数是新建一个list等于append原来的slice,list=append(slice,3),调用完这个函数后在函数的外部打印这个原来slice的长度是多少,新的是多少,地址改变了吗,指向的原来的数组呢

原来的 slice 长度不会改变,新建的 list 长度会增加,地址可能会改变。
如果新建的list超过原有容量,则会新建一个数组并扩容,这时地址就会改变,如果没有超过原有容量,那还是原来的地址。

a和b两个线程,a里面有defer recover,a里面新开了一个b,b没写defer recover,b发生了panic,ab两个线程会发生什么情况

b发生panic 程序直接崩溃
a无法接收b的panic

在函数参数传递一个非指针的互斥锁会发生什么事情?为什么会发生?

传递一个非指针的互斥锁会导致锁失效,因为互斥锁是不可复制的,传递时会产生副本,副本和原始锁是不同的对象。

jwt鉴权管理实现怎么做的,怎么实现的鉴权,修改了token它怎么解析,为什么这么解析,原理是什么

JWT 通常由三部分组成:

Header:标识类型和使用的签名算法(如 HMAC SHA256)。
Payload:包含声明(claims),如用户信息和其他元数据。
Signature:用于验证消息的真实性和完整性。
JWT 的基本结构如下:
header.payload.signature

服务器在用户登录成功后生成一个 JWT 并返回给客户端。这个 JWT 将用于后续的请求鉴权
JWT内容包含用户信息和有效期
每次客户端请求时都会携带 JWT,服务器需要验证该 JWT 的签名和有效期,确保其有效。
解析 JWT 时,服务器执行以下步骤:

分离 Header、Payload 和 Signature。
解码 Header 和 Payload。
使用相同的算法和密钥重新计算签名。
比较重新计算的签名与 JWT 中的签名,如果匹配则验证通过。
检查声明,如过期时间,确保 JWT 没有过期。

详细说一下令牌桶算法的实现

令牌桶算法用于流量控制。算法维护一个桶,定期向桶中添加令牌。请求到来时从桶中取走令牌,如果没有令牌则拒绝请求或等待。令牌桶算法可以通过控制令牌的添加速率和桶的容量来控制请求速率。

package mainimport ("sync""time"
)type TokenBucket struct {capacity  inttokens    intmutex     sync.Mutexticker    *time.TickerstopCh    chan struct{}
}func NewTokenBucket(rate int, capacity int) *TokenBucket {tb := &TokenBucket{capacity: capacity,tokens:   capacity,ticker:   time.NewTicker(time.Second / time.Duration(rate)),stopCh:   make(chan struct{}),}go tb.refill()return tb
}func (tb *TokenBucket) refill() {for {select {case <-tb.ticker.C:tb.mutex.Lock()if tb.tokens < tb.capacity {tb.tokens++}tb.mutex.Unlock()case <-tb.stopCh:return}}
}func (tb *TokenBucket) Stop() {tb.ticker.Stop()close(tb.stopCh)
}func (tb *TokenBucket) Allow() bool {tb.mutex.Lock()defer tb.mutex.Unlock()if tb.tokens > 0 {tb.tokens--return true}return false
}func main() {tb := NewTokenBucket(5, 10)defer tb.Stop()for i := 0; i < 20; i++ {if tb.Allow() {fmt.Println("Request allowed")} else {fmt.Println("Request denied")}time.Sleep(100 * time.Millisecond)}
}

golang 垃圾回收机制

Go 语言的垃圾回收机制(Garbage Collection, GC)是一种自动管理内存的功能,旨在自动回收不再使用的内存,以防止内存泄漏并提高程序的健壮性和效率。Go 的垃圾回收器是并发的、非阻塞的,并且自 Go 1.5 以来不断改进,以提高性能和减少对应用程序的影响。以下是 Go 垃圾回收机制的详细解释:

  1. 标记-清除算法
    Go 的垃圾回收器主要基于标记-清除(mark-and-sweep)算法。这种算法分为两个阶段:

标记阶段:从根对象(如全局变量和当前函数的栈帧)开始,递归地标记所有可以到达的对象为“存活”。
清除阶段:遍历堆中的所有对象,回收那些没有被标记为“存活”的对象。

  1. 三色标记法
    Go 的垃圾回收器使用三色标记法来实现标记阶段。这种方法将对象分为三种颜色:

白色:未被检查的对象,假设是不可达的。
灰色:被检查过的对象,但其引用的对象还未被检查。
黑色:被检查过的对象,并且其引用的对象也都被检查过。
垃圾回收器通过以下步骤进行标记:

初始时,所有对象都是白色的。
将根对象标记为灰色。
不断从灰色对象集中取出对象,将其引用的对象标记为灰色,并将该对象本身标记为黑色。
当灰色对象集为空时,标记阶段完成。

go 和 C++的区别,各有什么优劣?

go优点:
简单、开发效率高、原生并发编程、提供垃圾回收、跨平台编译
go缺点:
性能不如C++、缺乏一些高级特性。

c++ 面向对象 类继承多态 广泛标准库,更灵活更底层。
优点:速度快、提供底层控制、标准库多
缺点:复杂度高、手动内存管理、并发编程复杂
应用场景:
go:网络编程和微服务
C++:系统级编程 游戏服务器 、高性能计算、操作系统嵌入式等底层

MVCC

多版本并发控制(MVCC, Multi-Version Concurrency Control)是一种用于处理数据库并发访问的机制。MVCC 通过保存数据的多个版本,实现了数据库的读写操作互不阻塞,提升了并发性能。
每次对数据行进行修改(插入、更新、删除)时,都会生成一个新的版本。旧版本的数据不会立即删除,而是保留以供其他事务使用。
每个数据版本都会关联一个时间戳或事务 ID,用于标识该版本是由哪个事务生成的。通常,时间戳或事务 ID 是递增的,这样可以确定数据版本的先后顺序。
读操作根据事务的时间戳或事务 ID,读取在事务开始之前生成的最新数据版本。这样,读操作不会阻塞写操作,反之亦然。
特点:
高性能:由于读写操作互不阻塞,MVCC 提高了数据库的并发性能。
一致性读取:读操作总是读取事务开始之前的最新数据版本,确保了读取的一致性视图。
无锁操作:读操作无需加锁,从而避免了死锁问题。

go中的并发utils了解多少?

Goroutines、channel、Select、sync、context

对consul的了解

Consul 是由 HashiCorp 开发的一个分布式系统工具,用于实现服务发现配置共享健康检查

拦截器如何实现

拦截器(Interceptor)在软件开发中是一种设计模式,类似网关,用于在请求到达实际处理逻辑之前或之后对请求进行预处理或后处理。例如日志记录、身份验证、授权、性能监控等

package mainimport ("github.com/gin-gonic/gin""net/http""log""time"
)func main() {router := gin.Default()// 注册中间件router.Use(InterceptorMiddleware())// 定义路由router.GET("/ping", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",})})router.Run(":8080")
}// 拦截器中间件
func InterceptorMiddleware() gin.HandlerFunc {return func(c *gin.Context) {// 请求前拦截start := time.Now()log.Printf("Request: %s %s | Start Time: %v\n", c.Request.Method, c.Request.URL.Path, start)// 处理请求c.Next()// 请求后拦截latency := time.Since(start)log.Printf("Request: %s %s | Latency: %v | Status: %d\n", c.Request.Method, c.Request.URL.Path, latency, c.Writer.Status())}
}

删除slice中间一个元素

使用切片的特性和 append 函数来实现。

package mainimport "fmt"func main() {// 原始切片slice := []int{1, 2, 3, 4, 5}// 要删除的元素的索引index := 2// 保持顺序删除if index < len(slice) {slice = append(slice[:index], slice[index+1:]...)}fmt.Println(slice) // 输出 [1 2 4 5]
}

二、计算机网络

TCP和UDP的区别,TCP的三次握手四次挥手。

都是传输层协议
TCP:
面向连接:必须建立连接才能数据传输;
可靠性:提供可靠的数据传输,通过序列号、确认 号、重传机制和流量控制,确保数据包按顺序、无误地到达目标。
流量控制: 使用滑动窗口机制进行流量控制,确保发送方不会发送超过接收方处理能力的数据量。
拥塞控制:拥塞控制机制(如慢启动、拥塞避免、快速重传和快速恢复)来避免网络拥塞。
数据传输顺序:TCP 保证数据包按发送顺序到达接收方。
数据开销:由于需要建立连接、确认数据包和重传等功能、开销相对较大

UDP:
无连接、不可靠传输、无流量控制 、无拥塞控制、传输速度快、开销小。

TCP的三次握手(Three-way Handshake)

TCP 的三次握手是指在建立连接时,客户端和服务器之间需要进行的三次消息交换,以确保双方准备就绪并同步初始序列号。

第一次握手(客户端 -> 服务器):

客户端发送一个带有 SYN(同步序列号)标志位的包,表示请求建立连接,同时选择一个初始序列号(Seq=x)。
第二次握手(服务器 -> 客户端):

服务器收到 SYN 包后,返回一个带有 SYN 和 ACK(确认序列号)标志位的包,表示同意连接,并确认客户端的初始序列号(Ack=x+1),同时选择自己的初始序列号(Seq=y)。
第三次握手(客户端 -> 服务器):

客户端收到 SYN+ACK 包后,返回一个带有 ACK 标志位的包,确认服务器的初始序列号(Ack=y+1)。至此,连接建立。

TCP 的四次挥手

四次挥手是指在关闭连接时,客户端和服务器之间需要进行的四次消息交换,以确保双方都能安全地关闭连接。

第一次挥手(客户端 -> 服务器):

客户端发送一个带有 FIN(结束)标志位的包,表示没有数据要发送了,请求关闭连接。
第二次挥手(服务器 -> 客户端):

服务器收到 FIN 包后,返回一个带有 ACK 标志位的包,确认客户端的 FIN 包(Ack=客户端的Seq+1)。此时,服务器进入半关闭状态,可以继续发送数据给客户端。
第三次挥手(服务器 -> 客户端):

服务器确定没有数据要发送后,发送一个带有 FIN 标志位的包,表示请求关闭连接。
第四次挥手(客户端 -> 服务器):

客户端收到 FIN 包后,返回一个带有 ACK 标志位的包,确认服务器的 FIN 包(Ack=服务器的Seq+1)。此时,客户端等待一段时间(通常是 2 * 最大报文段寿命(MSL),确保服务器收到确认包后关闭连接)。至此,连接关闭。

protobuf知道吗?thrift了解吗?什么原理?

使用 Protobuf 的核心是定义一个IDL,描述数据结构和服务接口。数据被编码为二进制格式,序列化和反序列化速度快。

Thrift:同样使用 IDL 来定义数据结构和服务接口。
支持多种序列化格式(包括二进制和 JSON)。

三、Mysql

优化过sql吗,数据库是部署在哪里的,讲一个你认为最好的sql优化例子

在常用where条件查询上加索引
程序内使用缓存,减少查库次数

mysql部署在阿里云上,如何找到最慢的sql语句

可以使用 SHOW PROCESSLIST 查看当前运行的 SQL 语句,或者使用慢查询日志(slow query log)来记录执行时间超过一定阈值的查询。

用过gorm,如果一张上百万的数据的表,要新建一个字段的索引,如何保证线上的服务尽量少的被影响

异步索引创建和分片索引创建:
异步索引创建:在后台任务或低峰时段执行索引创建,以避免阻塞应用程序操作。
分片索引创建:将索引创建任务分成多个小批次,以减少对数据库的瞬时压力。

MYSQL 索引有什么用?索引的数据结构说一下。什么情况下会失效?

索引在数据库中主要用于提高查询性能。
常用结构是B+树、哈希
失效:(1)查询条件不符合索引左前缀
比如索引是(a,b);
select *from table where b=1;
(2)使用!=会遍历整个表
SELECT * FROM table WHERE a != 1;

(3)使用like
SELECT * FROM table WHERE name LIKE '%abc';

(4)使用函数或表达式:
SELECT * FROM table WHERE YEAR(date) = 2024;

四、Redis

redis是单线程的还是多线程的?为什么快?适用于什么场景?

redis 是单线程的、快是因为数据存储在内存中、读写速度快
适用场景:缓存、会话存储、实时数据分析、消息队列、分布式锁

redis基本数据类型

字符串、哈希、列表、集合、有序集合、流

redis写回策略你了解哪些?

RDB(Redis Database File)持久化:
通过定时保存或者在指定时间间隔内保存数据快照到磁盘。
AOF(Append Only File)持久化:通过将写操作追加到文件末尾的方式来记录每个写操作,确保每次写操作都能被持久化。
混合持久化:混合持久化是将 RDB 和 AOF 持久化结合使用,充分利用两者的优势。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搜维尔科技:我们用xsens完成了一系列高难度的运动项目并且捕获动作

我们用xsens完成了一系列高难度的运动项目并且捕获动作 搜维尔科技&#xff1a;我们用xsens完成了一系列高难度的运动项目并且捕获动作

zookeeper在哪里能用到

zookeeper是什么 ZooKeeper 顾名思义 动物园管理员&#xff0c;他是拿来管大象(Hadoop) 、 蜜蜂(Hive) 、 小猪(Pig) 的管理员&#xff0c; Apache Hbase和 Apache Solr 以及LinkedIn sensei 等项目中都采用到了 Zookeeper。 ZooKeeper是一个分布式的&#xff0c;开放源码的分…

【C++】多态进阶

标题&#xff1a;【C】多态进阶 水墨不写bug 目录 &#xff08;一&#xff09;多态的原理 &#xff08;1&#xff09;虚函数表 &#xff08;2&#xff09;多态的原理 &#xff08;3&#xff09;动态绑定与静态绑定 &#xff08;一&#xff09;多态的原理 &#xff08;1&am…

【1.合并两个数组】

题目&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&…

windows 11 PC查询连接过的wlan密码

1:管理员打开cmd 2:输入netsh wlan show profiles 3:netsh wlan show profiles Shw2024-5G keyclear 密码关键内容&#xff1a;12345678

[Unity]碰撞器的接触捕获层详解

目录 前言※关闭效果器(Effector)的遮罩接触捕获层的官方描述官方描述的翻译和注解接触捕获层作用简介接触(Contact)和捕获(Capture)配置接触捕获层的作用※接触捕获层对碰撞响应的影响需要接触捕获的物理查询需要接触捕获的物理回调注意运行时(Runtime)修改接触的相互性总结 相…

【Git分支管理】理解分支 | 创建分支 | 切换分支 | 合并分支 | 删除分支 | 强制删除分支

目录 前言 0.理解分支 1.查看本地仓库存在的分支 2.HEAD指向分支 3.创建本地分支 4.切换分支 5.分支提交操作 6.合并分支 快进模式Fast-forward 7.删除分支 8.强制删除分支 本篇开始介绍下Git提供的杀手级的功能&#xff1a;分支管理 先提交再合并 前言 在玄幻武侠…

Linux——文件目录指令、时间日期指令、搜索查找指令、压缩解压指令

目录 文件目录指令 pwd & ls 查看当前工作目录&显示当前目录所有文件及目录 cd 切换目录 mkdir & rmdir 创建&删除目录 touch 创建空文件 cp 拷贝文件/文件夹指令 rm 删除文件或文件夹 mv 移动或重命名文件 cat 查看文件 more指令 less 查看文件内容…

[激光原理与应用-115]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 19 - 主要硬件的介绍、安装与调试

目录 一、概述 1.1 前言 1.2 系统组成 1.2.1 机柜版&#xff1a; 1.2.2 非机柜版 1.3适用范围 1.4 工作条件 1.5 安全说明 1.6 装箱清单 二、硬件安装 2.1 光学传感器安装 2.1.1 转接件安装 2.1.2 光路校准模块的安装与光路校准 2.1.3 光学传感器的安装 2.2 通…

git往远程仓库新加分支,并在本地获取新分支,解决了不会上传分支以及他人上传分支之后自己无法查看问题

1.新建分支 git branch hzw2.切换分支 git checkout hzw也可以一步到位 git checkout -b hzw3.推送改分支到远端 git push -u origin hzw此时这个分支已经被推动到了远端&#xff0c;现在我们可以新开一个本地分支&#xff0c;连接这个仓库(默认已经连接好了) 此时输入命令…

文件上传1

上传文件到linux服务器 RestController public class UploadController {Value("${file.path}")private String filePath;PostMapping("/uploadFile")public Map<String, Object> uploadFile(RequestParam("file") MultipartFile file){M…

【学习笔记】min_25筛

背景 GDCPC2024 出题人&#xff1a;出这道 min25 筛是给大家增加过题数的 [呲牙][大哭][呲牙][大哭] min25筛是干啥的 快速求一个积性函数 F ( x ) F(x) F(x) 的前缀和 这个 F ( x ) F(x) F(x) 需要满足&#xff1a; F ( p ) ∑ i 0 a i p i F(p)\sum_{i0}a_ip^i F(p)∑…

Qt各个版本安装的保姆级教程

文章目录 前言Qt简介下载Qt安装包安装Qt找到Qt的快捷方式总结 前言 Qt是一款跨平台的C图形用户界面应用程序开发框架&#xff0c;广泛应用于桌面软件、嵌入式软件、移动应用等领域。Qt的强大之处在于其高度的模块化和丰富的工具集&#xff0c;可以帮助开发者快速、高效地构建出…

C++: 位图和布隆过滤器

目录 一、位图 1.1 概念 1.2 应用 1.3 模拟实现 1.31 把比特位上的值设置为1 1.32 把比特位上的值设置为0 1.33 检测比特位上的值是否是1 1.34 代码 二、布隆过滤器 2.1 概念 2.2 优点 2.3 缺点 2.4模拟实现 一、位图 1.1 概念 运用哈希的思想&#xff0c;将整型…

快速上手 Yarn:详解安装、配置、基本用法及其在 JavaScript 包管理中的作用

Yarn 是一个快速、可靠、安全的 JavaScript 包管理工具&#xff0c;专为解决 npm 的一些性能问题而设计。本文将详细介绍如何安装、配置和基本使用 Yarn。 安装 Yarn 使用 npm 安装 如果您已经安装了 npm&#xff0c;可以使用以下命令全局安装 Yarn&#xff1a; npm instal…

创建一个矩形,当鼠标进入这个矩形的时候,这个矩形边线变色,且鼠标变成手型

1.概要 创建一个矩形&#xff0c;当鼠标进入这个矩形的时候&#xff0c;这个矩形边线变色&#xff0c;且鼠标变成手型 2.代码 #include <QApplication> #include "customRectWidget.h" /** qt 6.7版&#xff0c; 创建一个矩形&#xff0c;当鼠标进入这个矩形…

【前端数据层高可用架构】

前端数据层高可用架构 前后端架构模式如下图 在这个架构下,客端数据可用率计算方式: 因此整体数据可用性分析表如下: 只有在客端和 BFF 都正常的情况下数据才能可用,而这种情况占比不是很高,因此整体的用户体验就不是很好。 本次建设目标 本文的设计方案就是要解决…

【设计模式之美】【建造型】建造者模式:处理复杂成员变量以及它们之间的关系

文章目录 一. 使用场景二. 具体实现三. 小结1. 结合场景使用2. 与工厂模式的区别 建造者模式本身不难&#xff0c;重点是掌握好它的适用场景。 一. 使用场景 如果一个类中有很多属性&#xff0c;为了避免构造函数的参数列表过长&#xff0c;影响代码的可读性和易用性&#xf…

Python Linux环境(Centos8)安装minicoda3+jupyterlab

文章目录 安装miniconda安装python环境启动 最近服务器检查&#xff0c;我下面的服务器有漏洞&#xff0c;不得已重装了&#xff0c;正好记录下怎么从零到python写代码。 安装miniconda miniconda是anconda的精简版&#xff0c;就是管理python环境的得力助手。 # 创建一个名…

C语言 do while循环语句练习 下

猜数字游戏实现 //猜数字游戏 //电脑产生 一个随机数&#xff08;1-100) //猜数字 //猜大了 //猜小了 //直到猜对了&#xff0c;结束 #include <stdlib.h> #include <time.h> void menu() {printf("********************************\n");printf("…