当前位置: 首页 > news >正文

go的singleFlight学习

Package singleflight provides a duplicate function call suppression mechanism
“golang.org/x/sync/singleflight”

原来底层是 waitGroup,我还以为等待的协程主动让出 cpu 了,没想到 waitGroup.Wait() 阻塞了
doCall 不但返回值是 func 的 val 和 error,而且 doCall 内部也给 chan 写入了一遍
这样外部的同步 Do 和异步 DoChan 都能复用了

当 Do->doCall 执行 fn 发生 panic 时:
对首发请求,直接在 defer 中把 fn 中捕获的 panic 进行回放
对非首发请求,c.wg.Wait() 结束之后,对 c.err 进行断言,判断是否是一个 panic 错误,如是则回放
这样就保证了首发请求和非首发请求都发生了 panic

一个协程对waitGroup进行Add(1)操作后,多个协程都可以监听它的读

package singleflightimport ("bytes""errors""fmt""runtime""runtime/debug""sync"
)// errGoexit indicates the runtime.Goexit was called in
// the user given function.
// 用户给定的函数中,调用了 runtime.Goexit
var errGoexit = errors.New("runtime.Goexit was called")// A panicError is an arbitrary value recovered from a panic
// with the stack trace during the execution of given function.
// 执行给定函数期间,panicError 是一个从 panic 中收到的任意值
// 带有栈追踪
type panicError struct {// value 中存储 errorvalue interface{}stack []byte
}// Error implements error interface.
func (p *panicError) Error() string {return fmt.Sprintf("%v\n\n%s", p.value, p.stack)
}func (p *panicError) Unwrap() error {err, ok := p.value.(error)if !ok {return nil}return err
}func newPanicError(v interface{}) error {stack := debug.Stack()// The first line of the stack trace is of the form "goroutine N [status]:"// but by the time the panic reaches Do the goroutine may no longer exist// and its status will have changed. Trim out the misleading line.// 去掉误导性的信息// 栈帧第一行,是"goroutine N [status]:"的信息if line := bytes.IndexByte(stack[:], '\n'); line >= 0 {stack = stack[line+1:]}return &panicError{value: v, stack: stack}
}// call is an in-flight or completed singleflight.Do call
type call struct {wg sync.WaitGroup// These fields are written once before the WaitGroup is done// and are only read after the WaitGroup is done.// WaitGroup Done 之前,这两个字段只会被写入一次// WaitGroup Done 之后,才能读取val interface{}err error// These fields are read and written with the singleflight// mutex held before the WaitGroup is done, and are read but// not written after the WaitGroup is done.// WaitGroup Done 之前,singleflight mutex 持有它的期间,这些字段被读取和写入// WaitGroup Done 之后,仅用于读取,不再被写入dups  intchans []chan<- Result
}// Group represents a class of work and forms a namespace in
// which units of work can be executed with duplicate suppression.
// Group 代表一个 work 类,形成一个 namespace
// 在该命名空间中(in which),可以通过重复抑制(duplicate suppression)来执行工作单元
type Group struct {mu sync.Mutex       // protects mm  map[string]*call // lazily initialized
}// Result holds the results of Do, so they can be passed
// on a channel.
type Result struct {Val    interface{}Err    errorShared bool
}// Do executes and returns the results of the given function, making
// sure that only one execution is in-flight for a given key at a
// time. If a duplicate comes in, the duplicate caller waits for the
// original to complete and receives the same results.
// The return value shared indicates whether v was given to multiple callers.
// 
// duplicate caller 会等待在 singleFlight 上,等待最开始的任务执行结束
// 返回的值 shared ,指示是否要将结果共享给其他 caller
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {g.mu.Lock()if g.m == nil {g.m = make(map[string]*call)}if c, ok := g.m[key]; ok {c.dups++g.mu.Unlock()// 等待 waitGroup Donec.wg.Wait()// 此时一定是 waitGroup Done 了// 发生了 panic ,不能吞掉panic错误// 发生了 error if e, ok := c.err.(*panicError); ok {panic(e)} else if c.err == errGoexit {// 优雅地退出 goroutine,防止对上游协程产生干扰runtime.Goexit()}// 返回最终结果return c.val, c.err, true}// 第一次进来的时候,执行这里c := new(call)// waitGroup 计数从 0 -> 1c.wg.Add(1)g.m[key] = cg.mu.Unlock()g.doCall(c, key, fn)return c.val, c.err, c.dups > 0
}// doCall handles the single call for a key.
func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) {normalReturn := falserecovered := false// use double-defer to distinguish panic from runtime.Goexit,// more details see https://golang.org/cl/134395// double-defer 以区分panic 和runtime.Goexitdefer func() {// the given function invoked runtime.Goexit// 把当前的堆栈给记录下来// normalReturn=true,正常结束// normalReturn=false && recovered == true,panic,需要外部还原panic的堆栈// normalReturn=false && recovered == false,go协程主动退出,需要制造一个errif !normalReturn && !recovered {c.err = errGoexit}g.mu.Lock()defer g.mu.Unlock()c.wg.Done()if g.m[key] == c {delete(g.m, key)}if e, ok := c.err.(*panicError); ok {// In order to prevent the waiting channels from being blocked forever,// needs to ensure that this panic cannot be recovered.if len(c.chans) > 0 {// goroutine的崩溃不会影响主goroutine或其他goroutine。go panic(e)// 能让panic爆出来select {} // Keep this goroutine around so that it will appear in the crash dump.} else {panic(e)}} else if c.err == errGoexit {// Already in the process of goexit, no need to call again} else {// Normal returnfor _, ch := range c.chans {ch <- Result{c.val, c.err, c.dups > 0}}}}()func() {defer func() {if !normalReturn {// Ideally, we would wait to take a stack trace until we've determined// whether this is a panic or a runtime.Goexit.// 理想情况下,会等到确定是否是 panic/runtime.Goexit 后才进行堆栈跟踪//// Unfortunately, the only way we can distinguish the two is to see// whether the recover stopped the goroutine from terminating, and by// the time we know that, the part of the stack trace relevant to the// panic has been discarded.// 不幸的是,我们区分两者的唯一方法是查看 recover 是否阻止了 goroutine 终止// 而当我们知道这一点时,与 panic 相关的堆栈跟踪部分已被丢弃。// 把 recover 拦住之后,返回一个 error ,然后在外部再进行放大,杀人于无形,让外部不知道singleFlightif r := recover(); r != nil {c.err = newPanicError(r)}}}()c.val, c.err = fn()normalReturn = true}()if !normalReturn {recovered = true}
}// Forget tells the singleflight to forget about a key.  Future calls
// to Do for this key will call the function rather than waiting for
// an earlier call to complete.
// 如果不想等之前的 singleflight 返回,则在 map[string]*call 中删除之前的 key 
func (g *Group) Forget(key string) {g.mu.Lock()delete(g.m, key)g.mu.Unlock()
}

时序分析
首发请求,先在Do中制造call,然后 c.wg.Add(1),然后将其放到map中

c.wg.Add(1)
g.m[key] = c

首发结束时,在doCall的defer中,先 c.wg.Done(),然后将任务从map中移除:delete(g.m, key)

c.wg.Done()
if g.m[key] == c {delete(g.m, key)
}

首发请求和首发结束都在锁的操作下执行。
所以抢到锁的时候,要么是首发请求执行请求的开始,要么是首发请求执行请求的结束

附录

一石激起千层浪

sync.WaitGroup 反向运用

func TestDemo333(t *testing.T) {var wg sync.WaitGroupwg.Add(1)for i := 1; i <= 3; i++ {go func(taskID int) {fmt.Println(i, "before wait")wg.Wait()fmt.Println(i, "wait finish")}(i)}time.Sleep(4 * time.Second)fmt.Println("main before send done")wg.Done() // 在协程结束时,调用Done方法fmt.Println("main after send done")select {}
}

debug.Stack()

属于 runtime/debug 包
用于获取当前程序的堆栈跟踪(stack trace),通常用于调试和错误处理

当调用 stack := debug.Stack() 时,实际上是在获取当前程序的堆栈信息,并将其存储在一个字符串类型的变量 stack 中。
这个字符串包含了程序在调用 debug.Stack() 时的调用栈信息,包括函数名、文件名和行号等。

package mainimport ("fmt""runtime/debug"
)func main() {stack := debug.Stack()fmt.Println(string(stack))
}func functionA() {functionB()
}func functionB() {stack := debug.Stack()fmt.Println(string(stack))
}

示例中定义两个函数 functionA 和 functionB。
在 functionB 中,调用了 debug.Stack() 并打印了堆栈信息。
当运行这个程序时,你会看到类似以下的输出:

goroutine 1 [running]:
main.functionB()/path/to/your/project/main.go:14 +0x8e
main.functionA()/path/to/your/project/main.go:7 +0x56
main.main()/path/to/your/project/main.go:22 +0x4a
runtime.main()/usr/local/go/src/runtime/proc.go:225 +0x235
runtime.goexit()/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1

这个输出显示了程序在调用 debug.Stack() 时的堆栈跟踪信息。
这对于调试程序和查找错误非常有用。

runtime.Goexit()

属于 runtime 包,用于退出当前的 goroutine。
当调用 runtime.Goexit() 时,当前正在执行的 goroutine 会立即终止,但不会对其他 goroutine 产生影响。

runtime.Goexit() 的使用场景通常包括:
(1) 优雅地退出 goroutine:
在某些情况下,可能需要在满足特定条件时退出 goroutine,而不是等待它自然完成。
使用 runtime.Goexit() 可以实现这一点。
(2) 避免 panic 引起的异常退出:
如果 goroutine 中发生了 panic,它会向上传播并可能影响到其他 goroutine。
在这种情况下,使用 runtime.Goexit() 可以优雅地退出当前 goroutine
避免 panic 对其他 goroutine 的影响
(3) 控制 goroutine 的生命周期:
在某些复杂的并发场景中,可能需要手动控制 goroutine 的生命周期。
通过在适当的时候调用 runtime.Goexit(),可以实现这一点。

package mainimport ("fmt""runtime""time"
)var someCondition = truefunc main() {go func() {for {fmt.Println("Running...")time.Sleep(1 * time.Second)if someCondition {fmt.Println("Exiting...")runtime.Goexit()}}}()time.Sleep(5 * time.Second)fmt.Println("Main function finished.")
}

在这个示例中,启动了一个 goroutine,它会每隔一秒钟打印 “Running…”。
当 someCondition 为 true 时,goroutine 会打印 “Exiting…” 并调用 runtime.Goexit() 退出。
主函数在等待 5 秒钟后结束。

过度使用 runtime.Goexit() 可能会导致代码难以理解和维护。
在大多数情况下,使用 channel 和其他同步机制来控制 goroutine 的生命周期是更好的选择。

DoChan的学习

// DoChan is like Do but returns a channel that will receive the
// results when they are ready.
//
// The returned channel will not be closed.
func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result {ch := make(chan Result, 1)g.mu.Lock()if g.m == nil {g.m = make(map[string]*call)}if c, ok := g.m[key]; ok {c.dups++c.chans = append(c.chans, ch)g.mu.Unlock()return ch}c := &call{chans: []chan<- Result{ch}}c.wg.Add(1)g.m[key] = cg.mu.Unlock()go g.doCall(c, key, fn)return ch
}

相关文章:

go的singleFlight学习

Package singleflight provides a duplicate function call suppression mechanism “golang.org/x/sync/singleflight” 原来底层是 waitGroup&#xff0c;我还以为等待的协程主动让出 cpu 了&#xff0c;没想到 waitGroup.Wait() 阻塞了 doCall 不但返回值是 func 的 val 和…...

高电压技术-冲击高压发生器MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 冲击电压发生器是产生冲击电压波的装置&#xff0c;用于检验电力设备耐受大气过电压和操作过电压的绝缘性能&#xff0c;冲击电压发生器能产生标准雷电冲击电压波形&#xff0c;雷电冲击电压截波,标准操作冲击…...

【STM32】SysTick系统滴答定时器

1.SysTick简介 CM4内核的处理和CM3一样&#xff0c;内部都包含了一个SysTick定时器&#xff0c;SysTick 是一个24 位的倒计数定时器&#xff0c;当计到0 时 &#xff0c;将 从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除&#xf…...

编码遵循五大设计原则创建出更加健壮、可维护和可扩展的软件系统

一、单一职责原则&#xff08;SRP&#xff09; * 定义&#xff1a;一个类应该只有一个引起它变化的原因。 * 解释&#xff1a;意味着一个类应该专注于做一件事情&#xff0c;当需求发生变化时&#xff0c;只影响到一个类。这有助于降低类间的耦合&#xff0c;使得代码更易于理…...

记录一个问题

问题描述 如果一个物料既在A总成零件号下计算为托盘库&#xff0c;在B总成零件号下计算为箱库&#xff0c;则放于箱库。 A中选择排名第21的递补进托盘库。&#xff08;也需要判断递补的是否在其他总成零件中为箱库&#xff0c;是的话继续递补判断&#xff09; 解决思路 为了…...

ONLYOFFICE 8.1版本桌面编辑器测评:重塑办公效率的巅峰之作

在数字化办公日益普及的今天&#xff0c;一款高效、便捷且功能强大的桌面编辑器成为了职场人士不可或缺的工具。ONLYOFFICE 8.1版本桌面编辑器凭借其卓越的性能和丰富的功能&#xff0c;成功吸引了众多用户的目光。今天&#xff0c;我们将对ONLYOFFICE 8.1版本桌面编辑器进行全…...

【shell脚本速成】python安装脚本

文章目录 案例需求应用场景解决问题脚本思路案例代码 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分使然&#xff01;&#x1f60a; &#x1f338;愿您在此停留的每一刻&#xff0c;都沐…...

Redis报错:MISCONF Redis is configured to save RDB snapshots

错误提示内容&#xff1a; 2024-06-25 16:30:49 : Connection: Redis_Server > [runCommand] PING 2024-06-25 16:30:49 : Connection: Redis_Server > Response received : -MISCONF Redis is configured to save RDB snapshots, but it is currently not able to pers…...

关于使用绿联 USB-A转RJ45 2.5G网卡提速的解决问题

问题 网络下载速率低 网线是七类网线&#xff0c;外接的USB网卡驱动 我的自带网卡是 I219v 在嵌入了2.5G网络后一直无法到达1.5G以上。 平均测速300~500M 解决方案 更新了USB的网卡驱动 禁用了 I219-V的驱动。测速即可 USB驱动下载地址 https://download.csdn.net/downlo…...

Qt: QPushButton 按钮实现 上图标下文字

效果如下&#xff1a; 实现有如下几种方式&#xff1a; 1. 使用 QPushButton 设置 setStyleSheet 例&#xff1a; ui->recorder->setStyleSheet("QPushButton{"\"border: 1px solid #00d2ff; "\"min-height: 60px; "\"col…...

使用阿里云效API操作流水线

使用阿里云效&#xff08;Alibaba Cloud DevOps&#xff09;API操作流水线时&#xff0c;需要注意以下几个方面&#xff1a; 认证与授权 确保你已经获取了正确的访问凭证&#xff08;AccessKey ID 和 AccessKey Secret&#xff09;&#xff0c;并且这些凭证具有足够的权限来执行…...

使用命令行创建uniapp+TS项目,使用vscode编辑器

一:如果没有pnpm,先安装pnpm 二:使用npx工具和degit工具从 GitHub 上的 dcloudio/uni-preset-vue 仓库克隆一个名为 vite-ts 的分支,到项目中. 执行完上面命令后,去manifest.json添加appid(自己微信小程序的Id),也可不执行直接下一步,执行pnpm install ,再执行pnpm:dev:mp-weix…...

ABC355 Bingo2

分析&#xff1a; 找出其中一行或列或任意对角线被全部标记&#xff0c;即可输出回合数&#xff0c;否则输出-1 如果x%n0&#xff0c;行是x/n&#xff0c;列是n 如果x%n&#xff01;0&#xff0c;行是x/n1&#xff0c;列是x%n 如果行列或行列n1即为对角线。 标记行列对角线…...

Spring+Vue项目部署

目录 一、需要的资源 二、步骤 1.首先要拥有一个服务器 2.项目准备 vue&#xff1a; 打包: 3.服务器装环境 文件上传 设置application.yml覆盖 添加启动和停止脚本 ​编辑 安装jdk1.8 安装nginx 安装mysql 报错&#xff1a;「ERR」1273-Unknown collation: utf8m…...

【uml期末复习】统一建模语言大纲

前言&#xff1a; 关于uml的期末复习的常考知识点&#xff0c;可能对你们有帮助&#x1f609; 目录 第一部分 概念与基础 第一章 面向对象技术 第二章 统一软件过程 第三章 UML概述 第四章 用例图 第五章 类图 第六章 对象图 第七章 顺序图 第八章 协作图 第九章 状态…...

Linux高级IO

高级IO 1.五种IO模型1.1 阻塞IO1.2 非阻塞IO1.3 信号驱动IO1.4 多路复用/多路转接IO1.5 异步IO1.6 小结 2.高级IO重要概念3.非阻塞IO3.1 实现函数NoBlock3.2 轮询方式读取标准输入 4.I/O多路转接之select4.1 理解select执行过程4.2 select的特点4.3 select缺点4.4 实现 5.I/O多…...

go-admin-ui开源后台管理系统华为云部署

1.华为云开通8000与9527端口 2.编译 编译成功 3.发布到远程服务器 4.登陆华为云终端 5.安装Nginx 6.查看服务启动状态 7.添加网站 添加与修改配置www-data 改为 www 自定义日志输出格式 添加网站配置文件go_admin_ui.conf 添加如下内容: location 下的root指向网站文件夹 修…...

点云入门知识

点云的处理任务 场景语义分割 物体的三维表达方法&#xff08;3D representations&#xff09;&#xff1a; 点云&#xff1a;是由物体表面上许多点数据来表征这个物体。最接近原始传感器数据&#xff0c;且具有丰富的几何信息。 Mesh&#xff1a;用三角形面片和正方形面片拼…...

HTML静态网页成品作业(HTML+CSS+JS)——家乡莆田介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现图片轮播&#xff0c;共有5个页面。 二、作品…...

#### grpc比http性能高的原因 ####

grpc比http性能高的原因 二进制消息格式&#xff1a;gRPC使用Protobuf&#xff08;一种有效的二进制消息格式&#xff09;进行序列化&#xff0c;这种格式在服务器和客户端上的序列化速度非常快&#xff0c;且序列化后的消息体积小&#xff0c;适合带宽有限的场景。 HTTP/2协…...

微软Edge浏览器搜索引擎切换全攻略

微软Edge浏览器作为Windows 10的默认浏览器&#xff0c;提供了丰富的功能和良好的用户体验。其中&#xff0c;搜索引擎的切换功能允许用户根据个人喜好和需求&#xff0c;快速更换搜索引擎&#xff0c;从而获得更加个性化的搜索服务。本文将详细介绍如何在Edge浏览器中进行搜索…...

<Linux> 实现命名管道多进程任务派发

实现命名管道多进程任务派发 common文件 #ifndef _COMMON_H_ #define _COMMON_H_#pragma once #include <iostream> #include <unistd.h> #include <string> #include <sys/types.h> #include <sys/stat.h> #include <wait.h> #include &…...

BigInteger 和 BigDecimal(java)

文章目录 BigInteger(大整数&#xff09;常用构造方法常用方法 BigDecimal(大浮点数&#xff09;常用构造方法常用方法 DecimalFormat(数字格式化) BigInteger(大整数&#xff09; java.math.BigInteger。 父类&#xff1a;Number 常用构造方法 构造方法&#xff1a;BigIntege…...

Linux 进程间通讯

Linux IPC 方式 在Linux系统中&#xff0c;进程间通信&#xff08;IPC&#xff09;是多个运行中的程序或进程之间交换数据和信息的关键机制。Linux提供了多种IPC机制&#xff0c;每种机制都有其特定的用途和优势。以下是Linux上主要的IPC通信方式&#xff1a; 管道&#xff08…...

数据分析三剑客-Matplotlib

数据分析三剑客 数据分析三剑客通常指的是在Python数据分析领域中&#xff0c;三个非常重要的工具和库&#xff1a;Pandas、NumPy和Matplotlib。Pandas主要负责数据处理和分析&#xff0c;NumPy专注于数值计算和数学运算&#xff0c;而Matplotlib则负责数据可视化。这三个库相…...

FastAPI-Body、Field

参考&#xff1a;模式的额外信息 - 例子 - FastAPI 在FastAPI中&#xff0c;Body和Field是两个常用的注解&#xff0c;它们用于定义请求体中的数据或路径参数、查询参数等的处理方式。这两个注解都来自于Pydantic库&#xff0c;用于数据验证和解析&#xff0c;但它们的应用场景…...

软件设计师笔记-操作系统知识(二)

线程 以下是关于线程的一些关键点&#xff1a; 线程是进程中的一个实体&#xff1a;进程是操作系统分配资源&#xff08;如内存空间、文件句柄等&#xff09;的基本单位&#xff0c;而线程是进程中的一个执行单元。多个线程可以共享同一个进程的地址空间和其他资源。线程是CP…...

鸿蒙UI开发快速入门 —— part12: 渲染控制

如果你对鸿蒙开发感兴趣&#xff0c;加入Harmony自习室吧~&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 扫描下面的二维码关注公众号。 1、前言 在声明式描述语句中开发者除了使用系统组件外&#xff0c;还可…...

添加用户页面(Flask+前端+MySQL整合)

首先导入Flask库和pymysql库。Flask用于创建Web应用程序&#xff0c;pymysql用于连接和操作MySQL数据库。 from flask import Flask, render_template, request import pymysql创建一个Flask应用实例。__name__参数告诉Flask使用当前模块作为应用的名称。 app Flask(__name_…...

素数筛(算法篇)

算法之素数筛 素数筛 引言&#xff1a; 素数(质数)&#xff1a;除了1和自己本身之外&#xff0c;没有任何因子的数叫做素数(质数) 朴素筛法(优化版) 概念&#xff1a; 朴素筛法&#xff1a;是直接暴力枚举2到当前判断的数x(不包括)&#xff0c;然后看在这范围内是否存在因…...

迁移Microsoft Edge

如何将Microsoft Edge迁移到d盘&#xff1f;对于Microsoft Edge想必大部分人都不陌生&#xff0c;它是Windows操作系统的默认浏览器&#xff0c;存储用户的个人数据、缓存和设置等信息。有些时候&#xff0c;我们需要对Microsoft Edge中的数据进行数据迁移&#xff0c;以释放c盘…...

Maven高级理解属性

属性 在这一章节内容中&#xff0c;我们将学习两个内容&#xff0c;分别是 属性版本管理 属性中会继续解决分模块开发项目存在的问题&#xff0c;版本管理主要是认识下当前主流的版本定义方式。 4.1 属性 4.1.1 问题分析 讲解内容之前&#xff0c;我们还是先来分析问题: …...

Trilium Notes浏览器插件保存网页内容到docker私有化部署

利用Trilium浏览器插件可以很方便的把网页内容保存到Trilium&#xff0c;需要先在docker部署好trilium&#xff0c;还没有部署的可以先看这篇文章&#xff1a;trilium笔记私有化部署-www.88531.cn资享网 1.下载Trilium浏览器插件&#xff1a;https://www.npspro.cn/33462.html…...

C++ 统计二进制串中0出现的个数

描述 一个32位有符号整数&#xff0c;使用二进制来表示&#xff0c;现在要统计一下二进制串中0的个数。 示例1 输入&#xff1a; 11 返回值&#xff1a; 29 说明&#xff1a; 二进制00000000000000000000000000001011中有29位0 class Solution { public:/*** 代码中的…...

note-网络是怎样连接的6 请求到达服务器,响应返回浏览器

助记提要 服务器程序的结构套接字的指代方式MAC模块的接收过程IP模块的接收过程TCP模块处理连接包TCP模块处理数据包TCP模块的断开操作URI转换为实际文件路径URI调用程序Web服务器访问控制响应内容的类型 6章 请求到达服务器&#xff0c;响应返回浏览器 1 服务器概览 在数据…...

存储过程与函数:封装数据库逻辑的艺术(七)

引言 在上一章《事务处理》中&#xff0c;我们深入探讨了事务的ACID特性以及如何通过事务控制语句和隔离级别来确保数据的一致性和完整性。本章&#xff0c;我们将把焦点转向存储过程与函数&#xff0c;这是数据库系统中用于封装复杂业务逻辑和增强代码复用性的强大工具。通过…...

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】卷积

卷积经常用在信号处理中&#xff0c;用于计算信号的延迟累积。假设一个信号发射器每个时刻 t t t产生一个信号 x t x_t xt​&#xff0c;其信息的衰减率为 w k w_k wk​&#xff0c;即在 k − 1 k-1 k−1个时间步长后&#xff0c;信息为原来的 w k w_k wk​倍&#xff0c;时刻 …...

Trie字符串统计

Trie字符串统计 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 x&#xff1b;Q x 询问一个字符串在集合中出现了多少次。 共有 N个操作&#xff0c;所有输入的字符串总长度不超过 105&#xff0c;字符串仅包含小写英文字母。 输入格式…...

Kali Linux源

中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib阿里云 deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib deb-src http://mirrors.…...

【RT摩拳擦掌】基于RT106L/S语音识别的百度云控制系统

【RT摩拳擦掌】基于RT106L/S语音识别的百度云控制系统 一 文档简介二 平台构建2.1 使用平台2.2 百度智能云2.2.1 物联网核心套件2.2.2 在线语音合成 2.3 playback语音数据准备与烧录2.4 开机语音准备与添加2.5 唤醒词识别词命令准备与添加 三 代码准备3.1 sln-local/2-iot 代码…...

国标GB28181视频汇聚平台EasyCVR设备展示数量和显示条数不符的原因排查与解决

国标GB28181/GA/T1400协议/安防综合管理系统EasyCVR视频汇聚平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。智慧安防/视频存储/视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级…...

FastAPI教程I

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 第一步 import uvicorn from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}if __name__ __main__:uvicorn.run(&quo…...

如何在 HTML 中实现响应式设计以适应不同设备的屏幕尺寸?

要在HTML中实现响应式设计以适应不同设备的屏幕尺寸&#xff0c;可以使用CSS媒体查询和流动布局。 以下是实现响应式设计的一些关键步骤&#xff1a; 使用CSS媒体查询&#xff1a;CSS媒体查询允许根据屏幕尺寸和设备特性应用不同的CSS样式。通过在CSS中使用media规则&#xf…...

【基础篇】第1章 Elasticsearch 引言

1.1 Elasticsearch简介 1.1.1 基本概念 Elasticsearch&#xff0c;一个开源的分布式搜索引擎&#xff0c;以其强大的搜索能力和实时数据分析能力&#xff0c;在大数据时代脱颖而出。它基于Apache Lucene库构建&#xff0c;旨在提供高效、可扩展且易于使用的全文检索解决方案。…...

在区块链技术广泛应用的情况下,C 语言如何在区块链的底层开发中发挥更有效的作用,提高性能和安全性?

C语言在区块链底层开发中发挥着重要的作用&#xff0c;可以提高性能和安全性。具体可以从以下几个方面进行优化&#xff1a; 性能优化&#xff1a;C语言是一种高效的编程语言&#xff0c;可以直接访问内存和硬件资源。在区块链底层开发中&#xff0c;使用C语言可以更好地利用底…...

量化投资 日周月报 2024-06-28

文章 深度学习在量化交易中的应用:在BigQuant量化交易平台的文章中,探讨了深度学习在量化交易中,特别是在因子挖掘方面的应用。文章提到,随着传统线性模型的潜力逐渐枯竭,非线性模型逐渐成为量化交易的主要探索方向。深度学习因其对非线性关系的拟合能力,在量化交易中展现…...

基于 Paimon 的袋鼠云实时湖仓入湖实战剖析

在当今数据驱动的时代&#xff0c;企业对数据的实施性能力提出了前所未有的高要求。为了应对这一挑战&#xff0c;构建高效、灵活且可扩展的实时湖仓成为数字化转型的关键。本文将深入探讨袋鼠云数栈如何通过三大核心实践——ChunJun 融合 Flink CDC、MySQL 一键入湖至 Paimon …...

IPython相关了解

一、什么是 IPython&#xff1f; 1.1 简单理解 IPython IPython 是一种增强的 Python 交互式解释器&#xff0c;它可以让你更方便地编写、调试和运行 Python 代码。你可以把它想象成一个比普通 Python 解释器更聪明、功能更丰富的工具&#xff0c;非常适合用来进行数据探索、…...

华为面试题及答案——机器学习(二)

21. 如何评价分类模型的优劣? (1)模型性能指标 准确率(Accuracy): 定义:正确分类的样本数与总样本数之比。适用:当各类样本的数量相对均衡时。精确率(Precision): 定义:预测为正类的样本中实际为正类的比例。适用:当关注假阳性错误的成本较高时(例如垃圾邮件检测…...

PlatformIO开发环境

PlatformIO是一个开源的生态系统&#xff0c;用于构建物联网应用&#xff0c;它支持多种微控制器&#xff08;MCU&#xff09;和硬件开发板&#xff0c;并且与各种IDE集成良好&#xff0c;如VSCode, Atom等&#xff0c;使得跨平台的固件开发变得更加简单和高效。 ### 平台介绍…...

WIN32核心编程 - 数据类型 错误处理 字符处理

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 数据类型 基本数据类型 Win32基本数据类型 错误处理 C语言中的错误处理 C中的错误处理 Win32中的错误处理 字符处理 C/C WIN32 字符处理 数据类型 基本数据类型 C/C语言定义了一系列…...

解锁分布式云多集群统一监控的云上最佳实践

作者&#xff1a;在峰 引言 在当今数字化转型加速的时代&#xff0c;随着混合云、多云多集群环境等技术被众多企业广泛应用&#xff0c;分布式云架构已成为众多企业和组织推动业务创新、实现弹性扩展的首选&#xff0c;分布式云容器平台 ACK One&#xff08;Distributed Clou…...

Lambda表达式在Java中的应用详解

Lambda表达式在Java中的应用详解 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来深入探讨Lambda表达式在Java中的应用详解。 Lambda表达式简介 Lambda表达式是Java 8引入的一项重要特性&…...

高考假期IT专业预习指南:为梦想启航的IT之旅

随着高考的圆满落幕&#xff0c;许多对未来充满憧憬的考生正站在人生新的十字路口&#xff0c;其中不乏对信息技术&#xff08;IT&#xff09;领域充满好奇与热情的同学们。IT行业作为当今社会最具活力和发展潜力的领域之一&#xff0c;不仅技术日新月异&#xff0c;还提供了广…...

Linux:文件系统与日志分析

一、block与inode 1.1、概述 文件是存储在硬盘上的&#xff0c;硬盘的最小存储单位叫做“扇区”(sector)&#xff0c;每个扇区存储512字节。 一般连续八个扇区组成一个"块”(block)&#xff0c;一个块是4K大小&#xff0c;是文件存取的最小单位。 文件数据包括实际数据…...

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

在卷积神经网络&#xff08;CNN&#xff09;中为什么可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的感受野 flyfish 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的…...

面对6大争议,为什么我认为乐道L60必成爆款?

5月15日,国际家庭日。乐道首场品牌发布会以及首款车型乐道L60正式亮相。预售价格为21.99万元,叠加“2000元抵扣6000元购车款”政策之后,实际预售价为21.59万元。我们就从这个问题出发,又分别列出了以下6个问题,同时我们也采访了蔚来创始人李斌和乐道品牌负责人艾铁成,对于…...

最长续航708公里阿尔法S5足以让Model3汗颜?

近日,极狐阿尔法S5已开启预售,预售价格分别为19.98万元、21.98万元,这款定位中型轿车的纯电是否有让同级竞品——Model 3汗颜的实力呢?据了解,阿尔法S5以电动性能著称,新车采用了豪华纯电车型中才会见到的同步+异步双电机组合,总功率高达390kW,总扭矩达到690Nm,百公里…...

Shell脚本的分支语句,循环语句

分支语句 if 表达式 then 命令表 fi 如果表达式为真&#xff0c;则执行命令表中的命令&#xff0c;否则退出。执行fi后的语句。 给文件权限:chmod 0777 文件名 输出: ./文件名 grep 查找用户名&#xff0c;管道wc -l 统计字符 2.多路分支语句 记得给文件名权限喔&#x…...

Day27

Day27 反射案例 案例一&#xff1a;万能数组扩容 注意&#xff1a;copyOf、toString public class Test01 {/*** 知识点&#xff1a;反射案例 之 万能数组扩容* * 注意&#xff1a;copyOf、toString*/public static void main(String[] args) {String[] ss {"aaa"…...

电脑显示由于找不到msvcr110.dll 无法继续执行如何处理?最简单的修复msvcr110.dll文件方法

电脑显示由于找不到msvcr110.dll 无法继续执行&#xff1f;当你看到这种提示的时候&#xff0c;请不要紧张&#xff0c;这种是属于dll文件丢失&#xff0c;解决起来还是比较简单的&#xff0c;下面会详细的列明多种找不到msvcr110.dll的解决方法。 一.找不到msvcr110.dll是怎么…...

[xx点评完结]——白马点评完整代码+rabbitmq实现异步下单+资料,免费

项目所有功能已测&#xff0c;均可以跑通&#xff0c;Jmeter和RabbitMQ也都测了。 项目源码:dianpinghui: 仿黑马点评项目 资料: https://pan.baidu.com/s/1kTCn9PxgeIey90WgM4KRqA?pwdn66b 对佬有帮助可以给个star哈&#xff0c;感谢&#x1f339;&#x1f339;&#x1f3…...