百度网盘golang实习面经
goroutine内存泄漏的情况?如何避免?
goroutine内存泄漏基本上是因为异常导致阻塞, 可以导致阻塞的情况
1 死锁, goroutine 等待的锁发生了死锁情况
2 chan没有正常被关闭,导致读取读chan的goroutine阻塞
如何避免
1 避免死锁
2 正常关闭
3 使用context管理goroutine, 超时结束goroutine
在Go语言中,Goroutine内存泄漏通常是由于Goroutine未能正确退出,导致其引用的对象无法被垃圾回收(GC)。以下是常见的内存泄漏场景及避免方法:
常见Goroutine内存泄漏场景
-
无限循环未设退出条件
go func() {for { // 无退出条件// 持续执行任务...} }()
-
阻塞于未处理的Channel操作
ch := make(chan int) go func() {<-ch // 永久阻塞,无数据发送 }()
-
生产者提前退出,消费者未关闭
func consumer(ch <-chan int) {for v := range ch { // 若生产者未关闭ch,消费者永久阻塞// 处理v} }
-
未释放资源(如time.Ticker)
go func() {ticker := time.NewTicker(time.Second)for {<-ticker.C // 未调用ticker.Stop()} }()
-
WaitGroup使用不当
var wg sync.WaitGroup wg.Add(1) go func() {// 忘记调用wg.Done() }() wg.Wait() // 永久阻塞
避免内存泄漏的方法
1. 使用context.Context
或done
通道通知退出
- 通过
context
的取消机制或自定义done
通道,明确控制Goroutine生命周期。
ctx, cancel := context.WithCancel(context.Background())
defer cancel()go func(ctx context.Context) {for {select {case <-ctx.Done(): // 收到退出信号returndefault:// 执行任务}}
}(ctx)
2. 避免永久阻塞:超时与select
结合
- 为Channel操作添加超时,防止永久阻塞。
select {
case <-ch:// 正常处理
case <-time.After(1 * time.Second):// 超时处理
}
3. 正确关闭Channel
- 确保生产者完成后关闭Channel,或在退出时通过
done
通道通知消费者。
done := make(chan struct{})
ch := make(chan int)go func() {defer close(ch) // 确保关闭Channel// 生产数据
}()go func() {for {select {case v, ok := <-ch:if !ok {return}// 处理vcase <-done: // 外部终止信号return}}
}()
4. 释放资源(如Ticker、锁、文件句柄)
- 使用
defer
确保资源释放。
go func() {ticker := time.NewTicker(time.Second)defer ticker.Stop() // 确保停止Tickerfor {select {case <-ticker.C:// 执行任务case <-done:return}}
}()
5. 正确使用sync.WaitGroup
- 使用
defer wg.Done()
避免遗漏。
var wg sync.WaitGroup
wg.Add(1)
go func() {defer wg.Done() // 确保调用Done()// 执行任务
}()
wg.Wait()
6. 监控Goroutine数量
- 使用
pprof
或runtime.NumGoroutine()
诊断泄漏。
import (_ "net/http/pprof""net/http"
)func main() {go http.ListenAndServe(":6060", nil) // 暴露pprof接口// ...
}
访问http://localhost:6060/debug/pprof/goroutine?debug=2
查看Goroutine堆栈。
总结
- 设计原则:确保每个Goroutine都有明确的退出路径。
- 资源管理:通过
defer
、context
和done
通道管理生命周期。 - 工具辅助:利用
pprof
等工具监控和诊断泄漏。
遵循以上实践,可有效避免Goroutine内存泄漏问题。
讲一下协程和线程的区别?从多个角度说明,讲一下golang协程是如何调度的,和java线程的区别
主要的区别在于协程是用户级, 不需要进入到内核态处理. 所以协程更加轻量级, 不占用内核资源。2k
协程(Goroutine)和线程(Thread)是并发编程中的核心概念,它们在设计目标、资源管理、调度方式等方面有显著差异。以下是两者的详细对比,并重点分析 Go 协程的调度机制及其与 Java 线程的区别。
一、协程与线程的核心区别
角度 | 协程(Goroutine) | 线程(Thread) |
---|---|---|
调度主体 | 由用户态调度(Go 运行时调度器) | 由操作系统内核调度 |
内存占用 | 初始栈约 2KB,可动态扩展(最大默认 1GB) | 固定栈(如 Linux 默认 8MB,Java 线程约 1MB) |
切换成本 | 极低(无需内核切换,仅用户态操作) | 高(需陷入内核态,上下文切换开销大) |
并发数量 | 轻松支持百万级并发(资源占用小) | 通常最多数千(受内核资源限制) |
同步机制 | 基于 Channel 通信(CSP 模型),避免共享内存 | 依赖锁、信号量等(共享内存,需显式同步) |
错误处理 | 通过 panic /recover 或返回值传递错误 | 通过异常捕获(如 try-catch ) |
创建与销毁 | 极快(由 Go 运行时管理,无系统调用) | 较慢(需系统调用,内核分配资源) |
二、Go 协程的调度机制(GMP 模型)
Go 的协程调度器采用 GMP 模型,由以下三部分组成:
- G(Goroutine):协程对象,存储执行栈和状态。
- M(Machine):操作系统线程(实际执行单元),由内核调度。
- P(Processor):逻辑处理器,管理本地协程队列(每个 P 绑定一个 M)。
调度流程
-
协程创建:
当启动一个 Goroutine 时,它会被放入当前 P 的本地队列(或全局队列,若本地队列满)。 -
线程绑定(M 与 P 绑定):
每个 P 会绑定一个 M(操作系统线程),M 从 P 的本地队列中获取 G 并执行。 -
协作式与抢占式调度:
- 协作式:协程主动让出 CPU(如
runtime.Gosched()
或系统调用)。 - 抢占式:Go 1.14+ 引入基于信号的抢占,防止协程长时间占用 CPU。
- 协作式:协程主动让出 CPU(如
-
Work Stealing:
若某个 P 的本地队列为空,会尝试从其他 P 的队列或全局队列“窃取” G,提高 CPU 利用率。 -
系统调用优化:
- 当 G 执行系统调用时,M 会解绑 P,P 转而绑定其他空闲 M,避免阻塞其他 G。
- 系统调用完成后,M 尝试获取 P 继续执行,若无可用 P,则 G 进入全局队列。
三、Go 协程与 Java 线程的对比
1. 调度方式
- Go 协程:
- 由 Go 运行时调度,用户态协作式+抢占式混合调度。
- 无需内核介入,切换成本极低(如保存/恢复少量寄存器)。
- Java 线程:
- 依赖操作系统内核调度(完全抢占式)。
- 线程切换需陷入内核态,上下文切换开销大(如保存线程状态、切换页表等)。
2. 资源占用
- Go 协程:
- 初始栈 2KB,按需动态扩展(避免内存浪费)。
- 协程复用线程(M),1 个线程可运行数千个协程。
- Java 线程:
- 固定栈大小(默认约 1MB),大量线程易导致内存耗尽。
- 线程与内核线程 1:1 绑定,创建过多会触发 OOM。
3. 并发能力
- Go 协程:
- 轻松支持百万级并发(如 Web 服务器处理海量连接)。
- 典型场景:IO 密集型任务(网络、磁盘操作)。
- Java 线程:
- 线程数量受限于内核(通常数千级别)。
- 需结合线程池避免资源耗尽,但高并发时仍有瓶颈。
4. 同步与通信
- Go 协程:
- 通过 Channel 通信,遵循 CSP 模型(“不要通过共享内存通信,而通过通信共享内存”)。
- 天然避免竞态条件,减少锁的使用。
- Java 线程:
- 依赖
synchronized
、Lock
、volatile
等同步机制。 - 共享内存模型易引发死锁、数据竞争等问题。
- 依赖
5. 错误处理
- Go 协程:
- 错误通过返回值或
panic
/recover
传递。 - 若协程发生未捕获的
panic
,整个程序会终止。
- 错误通过返回值或
- Java 线程:
- 异常需在线程内捕获,否则导致线程终止但进程不退出。
- 可通过
Future
或全局异常处理器(UncaughtExceptionHandler
)处理。
四、总结
特性 | Go 协程 | Java 线程 |
---|---|---|
调度开销 | 极低(用户态调度) | 高(内核态调度) |
适用场景 | 高并发、IO 密集型任务 | CPU 密集型任务、少量并发 |
资源占用 | 极小(动态栈,复用线程) | 大(固定栈,线程与内核线程 1:1 绑定) |
并发模型 | CSP 模型(Channel 通信) | 共享内存模型(锁同步) |
调试复杂度 | 较低(天然避免部分竞态条件) | 较高(需处理死锁、数据竞争) |
五、为什么 Go 协程更适合高并发?
- 轻量级:协程创建和切换成本极低,允许海量并发。
- 高效调度:GMP 模型减少线程阻塞,最大化 CPU 利用率。
- 简化同步:Channel 取代锁,降低并发编程复杂度。
- 资源友好:动态栈和用户态调度避免内存和内核资源浪费。
七、结论
- 协程是用户态的轻量级抽象,适合高并发、IO 密集型场景。
- 线程是操作系统资源,适合 CPU 密集型任务,但需谨慎管理。
- Go 的 GMP 调度器通过解耦协程与线程,结合协作式与抢占式调度,实现高效并发。
- Java 线程受限于内核调度和资源开销,需依赖线程池等技术优化,但并发能力仍弱于协程。
slice和array的区别,讲一下底层的结构
array本质是一个固定数组, 内存层面就是一块固定的内存区域,不会改变, 传递的时候是拷贝一份完整数据.
slice本质上是一个动态数组的封装,底层指向不是一个固定内存,可以重新指向新的内存,包含一个指向 Array 的指针、长度和容量。
channel的用途和使用上要注意的点,底层的结构是怎样的
channel是golang中协程之间的数据交互的重要工具,相当于与进程内的一个消息队列.
注意点: 最重要的是chan的close处理, 不然很容易出现异常, 1写数据goroutine中调用close, 2不要多次调用close, 3使用信号通知chan close了
底层结构: 环形队列(缓存数据, 无缓存的时候用不上), 读goroutine 队列(链表), 写goroutine 队列(链表), 锁
在 Go 语言中,Channel(通道) 是 Goroutine 之间通信和同步的核心机制,基于 CSP 模型(Communicating Sequential Processes)。以下是 Channel 的用途、使用注意事项及其底层结构的详细分析。
一、Channel 的用途
-
Goroutine 间通信
- 传递数据:通过
ch <- data
(发送)和data := <-ch
(接收)实现数据交换。 - 替代共享内存:遵循 Go 的哲学——“不要通过共享内存通信,而要通过通信共享内存”。
- 传递数据:通过
-
同步控制
- 阻塞等待:无缓冲 Channel 的发送和接收会阻塞,直到对方准备好(天然的同步机制)。
- 协调多个 Goroutine:例如通过
close(ch)
通知接收方数据结束。
-
工作池和任务分发
- 结合缓冲 Channel,可构建生产者-消费者模型,控制并发数量。
-
超时控制
- 通过
select
结合time.After
实现超时机制:select { case <-ch:// 正常处理 case <-time.After(1 * time.Second):// 超时处理 }
- 通过
二、使用 Channel 的注意事项
1. 初始化与零值
- Channel 的零值为
nil
,向nil
Channel 发送或接收会永久阻塞:var ch chan int // ch 是 nil ch <- 1 // 永久阻塞(无 panic) <-ch // 永久阻塞(无 panic)
- 正确做法:使用
make
初始化 Channel:ch := make(chan int) // 无缓冲 Channel bufferedCh := make(chan int, 10) // 缓冲容量为 10
2. 避免死锁
- 无缓冲 Channel 的同步性:发送和接收必须成对出现,否则死锁。
func main() {ch := make(chan int)ch <- 1 // 发送后阻塞,无接收者导致死锁fmt.Println(<-ch) // 永远不会执行 }
- 解决方式:确保发送和接收在不同的 Goroutine 中:
go func() { ch <- 1 }() fmt.Println(<-ch)
3. 关闭 Channel 的规则
- 关闭后不可发送:向已关闭的 Channel 发送数据会引发
panic
。 - 接收已关闭的 Channel:可继续接收剩余数据,返回零值时需通过
ok
判断是否关闭:v, ok := <-ch if !ok {// Channel 已关闭 }
- 关闭 Channel 的原则:
- 只由发送方关闭,避免多个 Goroutine 同时关闭。
- 无需关闭 Channel(除非必须通知接收方“数据结束”)。
4. 避免泄漏
- 未关闭的 Channel:若接收方持续等待已不再发送数据的 Channel,会导致 Goroutine 泄漏。
- 解决方式:使用
context
或done
通道通知退出:done := make(chan struct{}) go func() {select {case <-done:returncase v := <-ch:// 处理数据} }() // 退出时关闭 done close(done)
5. 性能优化
- 缓冲 Channel:减少阻塞频率,但需权衡内存占用。
- 避免过度缓冲:缓冲大小应根据实际场景调整,避免资源浪费。
三、Channel 的底层结构
Go 的 Channel 实现基于 runtime.hchan
结构体(源码见 runtime/chan.go
),核心字段如下:
1. hchan
结构体
type hchan struct {qcount uint // 当前队列中元素数量dataqsiz uint // 缓冲区的固定大小(容量)buf unsafe.Pointer // 指向环形缓冲区的指针elemsize uint16 // 元素大小closed uint32 // 是否已关闭(0-未关闭,1-已关闭)sendx uint // 发送索引(指向缓冲区下一个写入位置)recvx uint // 接收索引(指向缓冲区下一个读取位置)recvq waitq // 等待接收的 Goroutine 队列(sudog 链表)sendq waitq // 等待发送的 Goroutine 队列(sudog 链表)lock mutex // 互斥锁(保护 Channel 的并发操作)
}
2. 环形缓冲区(Buffered Channel)
- 缓冲机制:当
dataqsiz > 0
时,Channel 使用环形队列存储数据。 - 写入流程:
- 若缓冲区未满,数据写入
buf[sendx]
,sendx = (sendx + 1) % dataqsiz
。 - 若缓冲区已满,发送方 Goroutine 加入
sendq
队列并阻塞。
- 若缓冲区未满,数据写入
- 读取流程:
- 若缓冲区非空,读取
buf[recvx]
,recvx = (recvx + 1) % dataqsiz
。 - 若缓冲区为空,接收方 Goroutine 加入
recvq
队列并阻塞。
- 若缓冲区非空,读取
3. 直接发送与接收(Unbuffered Channel)
- 无缓冲 Channel:
dataqsiz = 0
,发送和接收必须同时就绪。 - 同步过程:
- 若接收方已阻塞(在
recvq
中),发送方直接将数据拷贝到接收方的栈。 - 若发送方已阻塞(在
sendq
中),接收方直接从发送方拷贝数据。
- 若接收方已阻塞(在
4. 等待队列(waitq
)
- 阻塞的 Goroutine:当发送或接收无法立即完成时,Goroutine 被封装为
sudog
结构体,加入sendq
或recvq
队列。 - 唤醒机制:当条件满足时(如缓冲区有空间或数据),调度器唤醒队列中的 Goroutine。
四、总结
特性 | 说明 |
---|---|
核心用途 | Goroutine 间通信与同步,替代共享内存 |
底层结构 | 基于环形缓冲区和等待队列(hchan ),通过锁保证并发安全 |
注意事项 | 避免死锁、正确关闭、处理零值、防止泄漏 |
性能优化 | 合理使用缓冲、减少锁竞争、避免过度阻塞 |
Channel 是 Go 并发编程的核心工具,深入理解其机制和陷阱,能够编写出高效且健壮的并发代码。
orm框架的优缺点
orm封装了对数据库的操作,并且自动转换内存数据结构和数据库字段, 优点是方便,开发效率高, 缺点是有些场景性能低, 复杂对像转换处理起来不方便.
操作系统内核态和用户态的区别,何时进入内核态or用户态
进入内核态: 中断(系统调用, 时间片到期等)
进入用户态: 内核态处理完成,调度用户线程处理程序
tcp和udp的区别,他们的报头结构,tcp的三次握手和四次握手的中间状态有哪些
https中的TLS/SSL层是用来干什么的,讲一下根证书和证书链和https握手的流程
TLS/SSL 层的作用
TLS(Transport Layer Security) 及其前身 SSL(Secure Sockets Layer) 是位于传输层(如 TCP)和应用层(如 HTTP)之间的安全协议,主要用于:
- 加密通信:防止数据在传输过程中被窃听。
- 身份认证:验证服务器(或客户端)的身份,防止中间人攻击。
- 数据完整性:确保数据未被篡改(通过哈希算法和消息认证码)。
HTTPS = HTTP + TLS/SSL,所有数据在传输前会被 TLS 层加密。
根证书与证书链
1. 根证书(Root Certificate)
- 颁发者:由受信任的根证书颁发机构(Root CA,如 DigiCert、Let’s Encrypt)签发。
- 存储位置:预装在操作系统或浏览器中(如 Windows 的受信任根证书存储)。
- 作用:作为信任链的起点,用于验证其他证书的合法性。
2. 证书链(Certificate Chain)
- 结构:
根证书 → 中间证书(Intermediate CA) → 服务器证书
。 - 示例:
- 根证书:
DigiCert Global Root CA
- 中间证书:
DigiCert TLS RSA SHA256 2020 CA1
- 服务器证书:
www.example.com
- 根证书:
- 作用:
- 分层信任:根证书不直接签发服务器证书,通过中间证书隔离风险(即使中间证书私钥泄露,只需吊销中间证书,无需替换根证书)。
- 链式验证:客户端从服务器证书逐级向上验证,直到找到信任的根证书。
3. 证书验证过程
- 客户端收到服务器的证书(如
www.example.com
)。 - 检查证书是否过期、域名是否匹配。
- 通过证书链向上追溯,验证每一级证书的签名是否合法,直到找到受信任的根证书。
- 若验证失败(如根证书不在信任库中),浏览器会提示“证书不受信任”。
HTTPS 握手流程(以 TLS 1.2 为例)
以下是客户端(如浏览器)与服务器建立 HTTPS 连接的详细步骤:
1. Client Hello
- 客户端发送:
- 支持的 TLS 版本(如 TLS 1.2)。
- 客户端随机数(Client Random,用于生成会话密钥)。
- 支持的密码套件(如
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
)。 - SNI(Server Name Indication):指定访问的域名(用于多域名服务器)。
2. Server Hello
- 服务器回应:
- 选择的 TLS 版本和密码套件。
- 服务器随机数(Server Random,用于生成会话密钥)。
- 服务器证书链(包含服务器证书和中间证书)。
3. 证书验证
- 客户端验证服务器证书链的合法性(如前文所述)。
4. 密钥交换(Key Exchange)
- RSA 密钥交换(传统方式):
- 客户端生成预主密钥(Pre-Master Secret),用服务器证书的公钥加密后发送。
- 服务器用私钥解密,得到预主密钥。
- ECDHE 密钥交换(现代方式,支持前向保密):
- 服务器生成临时椭圆曲线参数和公钥(Server Params),签名后发送。
- 客户端生成临时公钥(Client Params),发送给服务器。
- 双方通过椭圆曲线算法生成预主密钥。
5. 生成会话密钥
- 客户端和服务器使用以下三个随机数生成主密钥(Master Secret):
Client Random
Server Random
Pre-Master Secret
- 主密钥进一步派生出会话密钥(对称加密密钥,如 AES 密钥),用于后续通信加密。
6. Finished
- 双方发送加密的
Finished
消息,验证握手过程未被篡改。 - 握手完成,后续应用数据通过对称加密传输。
TLS 1.3 的优化
TLS 1.3 简化握手流程,提升安全性和速度:
- 合并步骤:将密钥交换与证书验证合并为单次往返(1-RTT)。
- 移除不安全算法:禁用 RSA 密钥交换(仅支持前向保密的 ECDHE)。
- 0-RTT 模式:对重复连接可跳过握手(需谨慎使用,存在重放攻击风险)。
总结
关键点 | 说明 |
---|---|
TLS/SSL 作用 | 加密数据、验证身份、保障完整性 |
根证书 | 信任链的起点,预装在系统中 |
证书链 | 分层签发,隔离风险,支持灵活吊销 |
握手流程 | 协商参数 → 交换密钥 → 生成会话密钥 → 加密通信 |
前向保密 | ECDHE 确保即使服务器私钥泄露,历史会话仍安全(TLS 1.3 强制要求) |
示例场景:
当访问 https://www.example.com
时:
- 浏览器通过 TLS 握手验证服务器的证书链,确认其属于
example.com
。 - 双方协商出会话密钥,后续所有 HTTP 数据(如登录密码、支付信息)均通过 AES 加密传输,确保安全。
常见的攻击手法有哪些,讲一下中间人攻击和跨域攻击的原理,跨域攻击主要是利用了浏览器的什么机制
一、常见攻击手法分类
以下是网络安全中常见的攻击类型:
攻击类型 | 描述 |
---|---|
中间人攻击(MITM) | 攻击者拦截并篡改通信双方的数据流。 |
跨站脚本(XSS) | 向网页注入恶意脚本,窃取用户数据或会话 Cookie。 |
SQL 注入 | 通过输入恶意 SQL 语句,操纵数据库查询。 |
跨站请求伪造(CSRF) | 诱使用户在已认证的站点上执行非预期的操作(如转账)。 |
拒绝服务(DoS/DDoS) | 通过大量请求耗尽目标资源,使其无法正常服务。 |
钓鱼攻击 | 伪造可信页面(如银行网站),诱导用户提交敏感信息。 |
目录遍历/文件包含 | 利用路径漏洞访问或执行服务器上的敏感文件。 |
社会工程学 | 通过心理欺骗获取敏感信息(如假冒客服骗取密码)。 |
二、中间人攻击(MITM)原理
1. 攻击场景
- 未加密的通信:如 HTTP 明文传输、公共 Wi-Fi 环境。
- 证书欺骗:伪造 SSL/TLS 证书(如自签名证书),诱导用户信任。
2. 攻击步骤
-
窃听(Eavesdrop):
攻击者通过 ARP 欺骗、DNS 劫持或 Wi-Fi 嗅探,成为通信链路的中间节点。- ARP 欺骗:伪造 IP 和 MAC 地址映射,劫持局域网流量。
- DNS 劫持:篡改 DNS 响应,将域名解析到攻击者控制的 IP。
-
篡改或伪造数据:
- 修改传输内容(如插入广告、重定向到钓鱼网站)。
- 窃取敏感信息(如登录凭证、Cookie)。
-
伪装身份:
- 在 HTTPS 场景下,攻击者可能伪造证书(需用户手动信任),解密 HTTPS 流量。
3. 防御措施
- 使用 HTTPS:加密通信内容,防止明文数据泄露。
- HSTS(HTTP Strict Transport Security):强制浏览器使用 HTTPS,防止降级攻击。
- 证书固定(Certificate Pinning):客户端固定合法证书,拒绝非预期证书。
- 网络层防护:使用 VPN、避免使用公共 Wi-Fi 进行敏感操作。
三、跨域攻击(Cross-Origin Attacks)原理
跨域攻击主要利用浏览器**同源策略(Same-Origin Policy)**的漏洞,绕过安全限制,窃取数据或执行恶意操作。
1. 同源策略(SOP)
- 定义:浏览器限制脚本只能访问与当前页面同源(协议、域名、端口相同)的资源。
- 目的:防止恶意网站读取其他站点的敏感数据(如 Cookie、DOM 内容)。
2. 跨域攻击类型
(1) 跨站脚本(XSS)
- 原理:攻击者注入恶意脚本到合法页面,脚本在用户浏览器执行。
<!-- 示例:通过未过滤的用户输入注入脚本 --> <input value="<script>stealCookie()</script>">
- 利用点:
- 窃取用户的 Cookie 或 Session ID。
- 伪造用户操作(如自动转账)。
(2) 跨站请求伪造(CSRF)
- 原理:诱导用户访问恶意页面,该页面自动向目标站点发送已认证的请求。
<!-- 恶意页面中隐藏的转账请求 --> <img src="https://bank.com/transfer?to=attacker&amount=1000000">
- 利用点:
- 用户已登录目标站点(如银行),浏览器自动携带 Cookie。
- 请求被执行(如转账、修改密码)。
(3) CORS 配置不当
- 原理:服务器错误设置
Access-Control-Allow-Origin: *
,允许任意域访问资源。HTTP/1.1 200 OK Access-Control-Allow-Origin: *
- 利用点:
- 攻击者通过恶意网站发起跨域 AJAX 请求,窃取数据。
(4) JSONP 劫持
- 原理:利用
<script>
标签跨域加载 JSONP 接口,通过回调函数窃取数据。<script src="https://api.com/user?callback=stealData"></script> <script> function stealData(data) {// 发送数据到攻击者服务器 } </script>
3. 防御措施
攻击类型 | 防御方法 |
---|---|
XSS | 输入输出过滤(如转义 < , > )、启用 CSP(Content Security Policy)。 |
CSRF | 使用 CSRF Token、检查 Referer 头、设置 SameSite Cookie 属性。 |
CORS | 严格限制 Access-Control-Allow-Origin (如白名单)、避免使用通配符 * 。 |
JSONP | 弃用 JSONP,改用 CORS;或校验回调函数名、添加随机 Token。 |
四、总结
攻击类型 | 核心原理 | 浏览器机制利用 |
---|---|---|
中间人攻击 | 拦截并篡改通信链路 | 无加密通信或证书信任漏洞 |
跨域攻击 | 绕过同源策略获取跨域数据或权限 | SOP 限制不严、CORS/JSONP 配置错误 |
关键点:
- 中间人攻击依赖网络层的漏洞,防御需加密通信(HTTPS)和身份验证。
- 跨域攻击利用浏览器同源策略的宽松配置,防御需严格限制跨域资源访问。
示例场景:
- MITM:公共 Wi-Fi 中,攻击者截获用户登录 HTTP 站点的密码。
- 跨域攻击:恶意网站利用银行站点的 CORS 配置错误,窃取用户账户数据。
通过理解攻击原理和浏览器机制,开发者可更有效地设计安全防护策略。
相关文章:
百度网盘golang实习面经
goroutine内存泄漏的情况?如何避免? goroutine内存泄漏基本上是因为异常导致阻塞, 可以导致阻塞的情况 1 死锁, goroutine 等待的锁发生了死锁情况 2 chan没有正常被关闭,导致读取读chan的goroutine阻塞 如何避免 1 避免死锁 2 正常关闭 3 使用context管…...
super_small_toy_tpu
super_small_toy_tpu 小狼http://blog.csdn.net/xiaolangyangyang 1、基础框图 2、源码下载: GitHub - dldldlfma/super_small_toy_tpu 3、安装iverilog、vvp、gtkwave windows安装:https://bleyer.org/icarus/ ubuntu安装:sudo ap…...
Redis缓存穿透、缓存击穿与缓存雪崩:如何在.NET Core中解决
在高并发的互联网系统中,缓存技术作为优化系统性能的重要手段,已被广泛应用。然而,缓存系统本身也存在一些常见的问题,尤其是 缓存穿透、缓存击穿 和 缓存雪崩。这些问题如果处理不当,可能导致系统性能严重下降&#x…...
驱动车辆诊断测试创新 | 支持诊断测试的模拟器及数据文件转换生成
一 背景和挑战 | 背景: 随着汽车功能的日益丰富,ECU和域控制器的复杂性大大增加,导致测试需求大幅上升,尤其是在ECU的故障诊断和性能验证方面。然而,传统的实车测试方法难以满足高频率迭代和验证需求,不仅…...
VS Code技巧2:识别FreeCAD对象
在使用VS Code阅读FreeCAD代码或者FreeCAD的工作台代码时,VS Code无法识别FreeCAD对象,会提示Import “FreeCAD” could not be resolved: 问题解决如下几步即可。 第一步:确认 FreeCAD 的 Python 环境路径 在FreeCAD的Python控制…...
泰迪杯特等奖案例学习资料:基于多模态融合与边缘计算的智能温室环境调控系统
(第十二届泰迪杯数据挖掘挑战赛特等奖案例解析) 一、案例背景与核心挑战 1.1 应用场景与行业痛点 在现代设施农业中,温室环境调控直接影响作物产量与品质。传统温室管理存在以下问题: 环境参数耦合性高:温度、湿度、光照、CO₂浓度等参数相互影响,人工调控易顾此失彼。…...
猿人学web端爬虫攻防大赛赛题第13题——入门级cookie
1. F12开发者模式 刷新第一页,仔细研究发现里面有三次请求名为13的请求,根据题目提示cookie关键字,所以主要留意请求和响应的cookie值。 三次请求都带了sessionid,说明存在session(后面写代码要用session来写&#x…...
机器指标监控技术方案
文章目录 机器指标监控技术方案架构图组件简介Prometheus 简介核心特性适用场景 Grafana 简介核心特性适用场景 Alertmanager 简介核心特性适用场景 数据采集机器Node ExporterMySQL ExporterRedis ExporterES ExporterRocketMQ ExporterSpringcloud ExporterNacos 数据存储短期…...
数据库设计理论:从需求分析到实现的全流程解析
引言 在当今信息爆炸的时代,数据已成为企业和组织最宝贵的资产之一。如何有效地组织、存储和管理这些数据,是数据库设计需要解决的核心问题。一个优秀的数据库设计能够提高系统性能,确保数据一致性,降低维护成本,而糟…...
一文详解 Linux下的开源打印系统CUPS(Common UNIX Printing System)
文章目录 前言一、CUPS 简介二、CUPS 常用指令解析2.1 安装 CUPS2.2 启动/重启服务2.3 添加打印机(核心操作)2.4 设置默认打印机2.5 打印文件2.6 查看打印任务2.7 取消打印任务2.8 查看、移除已添加的打印机 三、调试与常见问题3.1 日志查看3.2 驱动问题…...
uniapp打包apk详细教程
目录 1.打apk包前提条件 2.获取uni-app标识 3.进入dcloud开发者后台 4.开始打包 1.打apk包前提条件 1.在HBuilderX.exe软化中,登录自己的账号 2.在dcloud官网,同样登录自己的账号。没有可以免费注册。 2.获取uni-app标识 获取方法:点…...
C++初阶-string类2
目录 1.迭代器 1.1普通迭代器的使用 1.2string::begin 1.3string::end 1.4const迭代器的使用 1.5泛型迭代器和const反向迭代器 1.6string::rbegin 1.6string::rend 1.7string::cbegin、string::cend、string::crbegin、string::crend 与begin/end、rbegin/rend的区别 …...
Qt QComboBox 下拉复选多选(multicombobox)
Qt QComboBox 下拉复选多选(multicombobox),备忘,待更多测试 【免费】QtQComboBox下拉复选多选(multicombobox)资源-CSDN文库...
逻辑回归之参数选择:从理论到实践
在机器学习的广阔领域中,逻辑回归作为一种经典的有监督学习算法,常用于解决分类问题。它以其简单易懂的原理和高效的计算性能,在实际应用中备受青睐。然而,要充分发挥逻辑回归的优势,参数选择是关键环节。本文将结合信…...
10、属性和数据处理---c++17
一、[[fallthrought]] 用途:在 switch 语句中标记某个分支 (case) 故意不写 break,明确告知编译器“执行穿透”是有意为之。 仅在需要向下穿透时使用,且应添加注释说明原因 #include<cstdio> #include<iostream> using namesp…...
conda管理python环境
安装conda 使用anaconda官网安装地址:https://www.anaconda.com/download/success 配置镜像环境 conda config --add channels Index of /anaconda/pkgs/main/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror conda config --add channels Index of /an…...
【Python学习路线】零基础到项目实战系统
目录 🌟 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 🧠 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 💻 二、实战演示环境配置要求核心代码实现运行结果验证 ⚡ 三、性能对比测试方法论量化数据对比…...
C/C++核心机制深度解析:指针、结构体与动态内存管理(面试精要)
C/C核心机制深度解析:指针、结构体与动态内存管理(面试精要) 引言 在系统级编程领域,C/C语言凭借对硬件的直接操作能力和高效的内存管理机制,长期占据主导地位。面试中,指针、结构体和动态内存管理作为三…...
宇树科技举办“人型机器人格斗大赛”
2025 年 5 月至 6 月,一场全球瞩目的科技盛宴 —— 全球首场 “人形机器人格斗大赛”,将由杭州宇树科技盛大举办。届时,观众将迎来机器人格斗领域前所未有的视觉震撼。 为打造最强参赛阵容,宇树科技技术团队在过去数周里…...
getattr 的作用
getattr 是 Python 内置的一个函数,用于“动态地”获取对象的属性。**它允许你在运行时通过属性名称(字符串形式)来访问对象的属性,而不用在代码中直接硬编码属性名。**下面详细介绍该方法的用法和注意事项: ────…...
腾讯云服务器性能提升全栈指南(2025版)
腾讯云服务器性能提升全栈指南(2025版) 一、硬件选型与资源优化 1. 实例规格精准匹配 腾讯云服务器提供计算型CVM、内存型MEM、大数据型Hadoop等12种实例类型。根据业务特性选择: • 高并发Web应用:推荐SA3实例࿰…...
Kotlin与Jetpack Compose的详细使用指南
Kotlin与Jetpack Compose的详细使用指南,综合最新技术实践和官方文档整理: 一、环境配置与基础架构 项目创建 在Android Studio中选择Empty Compose Activity模板,默认生成包含Composable预览的MainActivity2要求Kotlin版本≥1.8.0&…...
潇洒郎: 100% 成功搭建Docker私有镜像仓库并管理、删除镜像
1、Registry Web管理界面 2、拉取Registry-Web镜像 创建配置文件 tee /opt/zwx-registry/web-config.yml <<-EOF registry:url: http://172.28.73.90:8010/v2name: registryreadonly: falseauth:enabled: false EOF 拉取docker-registry-web镜像并绑定Registry仓库 …...
【Spring Boot 注解】@ConfigurationProperties
文章目录 ConfigurationProperties注解一、简介二、依赖引入三、基本用法四、主要特性五、激活方式六,优点七、与 Value 对比 ConfigurationProperties注解 一、简介 ConfigurationProperties 是 Spring Boot 提供的一个强大注解,用于将外部配置&#…...
阿里云服务迁移实战: 06-切换DNS
概述 按前面的步骤,所有服务迁移完毕之后,最后就剩下 DNS 解析修改了。 修改解析 在域名解析处,修改域名的解析地址即可。 如果 IP 已经过户到了新账号,则不需要修改解析。 何确保业务稳定 域名解析更换时,由于 D…...
Java实现归并排序算法
1. 归并排序原理图解 归并排序是一种分治算法,其核心思想是将数组分成两半,分别对这两半进行排序,然后将排序后的两半合并。以下是归并排序的步骤: 1. 分治: - 将数组分成两半。 - 递归地对每半部分进行归并排序。 2. …...
Vue 项目中运行 `npm run dev` 时发生的过程
步骤1:找到「任务说明书」(package.json) 当你输入 npm run dev,系统首先会去查项目的 「任务说明书」(即 package.json 文件),看看 dev 这个任务具体要做什么。 示例代码(package.json 片段)…...
Python3(19)数据结构
在 Python 编程中,数据结构是组织和存储数据的重要方式,合理选择和使用数据结构能显著提升程序的效率和可读性。这篇博客通过丰富的代码示例深入学习 Python3 的数据结构知识,方便日后复习回顾。 一、列表(List) 1.1…...
macOS 安装了Docker Desktop版终端docker 命令没办法使用
macOS 安装了Docker Desktop版终端docker 命令没办法使用 1、检查Docker Desktop能否正常运行。 确保Docker Desktop能正常运行。 2、检查环境变量是否添加 1、添加环境变量 如果环境变量中没有包含Docker的路径,你可以手动添加。首先,找到Docker的…...
VR 汽车线束培训:探索高效学习新路径
在汽车线束生产领域,VR 汽车线束培训对于新员工的成长至关重要,它是一个关键环节,直接影响着生产效率和产品质量。传统的培训方式,通常是新员工在老员工的指导下,通过实际操作来学习线束装配流程。这种方式不仅耗费大量…...
k8s术语之Deployment
Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新 您只需要在Deployment中描述您想要的目标状态是什么,Deployment controller就会帮您将Pod和ReplicaSet的实际状态改变到您的目标状态。您可以定义一个全新的Deployment Controller的职责…...
对js的Date二次封装,继承了原Date的所有方法,增加了自己扩展的方法,可以实现任意时间往前往后推算多少小时、多少天、多少周、多少月;
封装js时间工具 概述 该方法继承了 js 中 Date的所有方法;同时扩展了一部分自用方法: 1、任意时间 往前推多少小时,天,月,周;参数1、2必填,参数3可选beforeDate(num,formatter,dateVal); befo…...
17、商品管理:魔药商店运营——React 19 CRUD实现
一、魔药商店的炼金基石 1. 魔药配方契约(数据模型设计) // 预言池契约(Supabase Schema) interface Potion { id: uuid, name: string, effect: healing | transformation | attack, stock: number, moonSensitive: boo…...
2025-04-30 AIGC-如何做短片视频
摘要: 2025-04-30 AIGC-如何做短片视频 如何做短片视频: 一、画图修图 1.保存视频(无水保存) 2.文案提取(提取文案) 3. DeepSeek(提示词) 4.小梦Ai(图片视频) 5.修图Ai 6.扩图Ai 7.养生…...
【自然语言处理与大模型】如何获取特定领域的微调数据集?
在特定领域中,数据集通常由提出需求的一方提供。然而,在某些情况下,如果他们未能提供所需的数据,或者你正在独立开展一个项目,并且需要相应的数据来推进工作,这时你应该怎么办呢?本文提供一种思…...
算法导论第6章思考题
6.3-2 func(A) 1 A.heap-sizeA.len 2 \quad for i ⌊ A . l e n 2 ⌋ \lfloor {A.len\over2}\rfloor ⌊2A.len⌋ downto 1 3 \qquad MAX-HEAPIFY(A,i) 对于第2行的循环控制变量i来说,为啥要求它是从 ⌊ A . l e n 2 ⌋ \lfloor {A.len\over2}\rfloor ⌊2A.len⌋…...
论文阅读:2024 ACM SIGSAC Membership inference attacks against in-context learning
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Membership inference attacks against in-context learning https://arxiv.org/pdf/2409.01380 https://www.doubao.com/chat/4030440311895554 速览 这篇论文主要研究了…...
读论文笔记-CoOp:对CLIP的handcrafted改进
读论文笔记-Learning to Prompt for Vision-Language Models Problems 现有基于prompt engineering的多模态模型在设计合适的prompt时有很大困难,从而设计了一种更简单的方法来制作prompt。 Motivations prompt engineering虽然促进了视觉表示的学习,…...
国产化海光C86架构服务器安装windows实录
最近几年与红蓝关系急转直下,尤其是科技领域尤为突出。随之而来的就是软硬件的国产化大潮。由于行业的原因根据要求必须使用国产化服务器、国产化操作系统、国产化数据库、国产化中间件。虽然闭关锁国断开红蓝联系可以在一定程度激发国产化发展,但是不得…...
基于SpringBoot的旅游网站的设计与实现
资源详情: 私信我或点击链接获取: 基于SpringBoot的旅游网站的设计与实现资源-CSDN文库 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势,旅游网站当然也不能排除在外…...
【Axure教程】增删改饼图
今天教大家制作增删改饼图的原型模版,该模版是用Axure原生元件制作的,所以不需要联网或者调用外部接口,使用也很方便,默认数据在中继器表格里填写,默认支持20个不同颜色的扇形,后续可根据实际需要自己增加扇…...
FastAPI系列12:使用JWT 登录认证和RBAC 权限控制
使用JWT 登录认证和RBAC 权限控制 1、身份认证(Authentication)与JWT身份认证(Authentication)的方式JWT(JSON Web Token)的实现原理 2、授权(Authorization)与RBAC授权(…...
定时任务xxl-job国产化改造,适配磐维数据库(PostgreSQL)
前言 因公司要求系统需要全面国产化改造,其中也涉及到定时任务xxl-job的改造。 使用的xxl-job版本为:2.5.0 一、修改配置 1、修改pom.xml,引入postgresql组件 <dependency><groupId>org.postgresql</groupId><artif…...
2025华东杯ABC题赛题已出速拿
2025华东杯ABC题赛题已出速拿 A: B: C:...
PostgreSQL事务与并发清理
1.并发清理概述 清理过程为指定的表,或数据库中的所有表执行以下任务。 1. 移除死元组 移除每一页中的死元组,并对每一页内的活元组进行碎片整理。 移除指向死元组的索引元组。 2. 冻结旧的事务标识(txid) 如有必要…...
基于DeepSeek与HTML的可视化图表创新研究
一、研究背景 在当今数字化时代,数据呈指数级增长,广泛渗透于社会各个领域。无论是商业运营、科学研究,还是公共管理等方面,海量数据蕴含着丰富的潜在价值,成为驱动决策优化、推动业务发展、促进科学创新的关键要素。数…...
游戏引擎学习第250天:# 清理DEBUG GUID
设置阶段,重新开始清理调试层 今天,我们将继续进行之前未完成的任务,主要是清理调试层的代码,并为其在游戏中使用做好准备。昨天我原本准备清理一些代码,但没能完成,所以今天我们将从那里开始,…...
删除k8s某命名空间,一直卡住了怎么办?
以 kubectl delete ns cert-manager 命令卡住为例,并且命名空间一直处于 Terminating 状态,说明 Kubernetes 无法完成删除操作,通常是因为 Finalizers 阻塞或某些资源无法正常清理。 解决方法 1. 检查命名空间状态 kubectl get ns cert-man…...
聊一聊接口自动化测试断言处理策略
目录 一、断言设计原则 1.1精准性 1.2可维护性 1.3容错性 二、常见断言类型及实现 2.1基础验证 2.2响应体验证 2.3业务逻辑验证 2.4异常场景验证 2.5数据库断言 三、断言策略 3.1 精准断言 vs 模糊断言 3.2关键字段优先 3.3数据动态处理 四、多断言处理 4.1单用…...
C# 实现列式存储数据
C#实现列式存储数据指南 一、列式存储概述 列式存储(Columnar Storage)是一种数据存储方式,它将数据按列而非行组织。与传统的行式存储相比,列式存储在以下场景具有优势: 分析型查询:聚合计算、分组统计等操作效率更高…...