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

golang context源码

解析

context结构

Deadline:返回 context 的过期时间;
Done:返回 context 中的 channel;
Err:返回错误;
Value:返回 context 中的对应 key 的值.

type Context interface {Deadline() (deadline time.Time, ok bool)Done() <-chan struct{}Err() errorValue(key any) any
}
//Context包含截止日期、取消信号和其他值
//API边界。
//Context的方法可能会被多个goroutine同时调用。
type Context interface {//Deadline返回代表此上下文完成工作的时间//应该取消。当没有截止日期时,截止日期返回ok==false//集。连续调用Deadline返回相同的结果。Deadline() (deadline time.Time, ok bool)//Done返回一个通道,当代表此完成工作时,该通道将关闭//上下文应该被取消。如果此上下文可以,Done可能会返回nil//永远不会被取消。连续调用Done返回相同的值。//Done通道的关闭可以异步发生,//在取消功能返回后。////WithCancel安排在调用取消时关闭Done;//WithDeadline安排在截止日期前关闭“完成”//到期;WithTimeout安排在超时时关闭“完成”//过去了。////Done用于选择语句://Stream使用DoSomething生成值并将其发送到out直到DoSomething返回错误或ctx。完成已关闭。//func流(ctx context.context,out chan<-值)错误{//for{//v,err:=DoSomething(ctx)//如果错误!=无{//返回错误//  		}//选择{//病例<-ctx。Done()://返回ctx。错误()//case out<-v://  		}//  	}//  }////请参阅https://blog.golang.org/pipelines有关如何使用的更多示例//a取消的完成频道。Done() <-chan struct{}//如果Done尚未关闭,Err将返回nil。//如果Done关闭,Err返回一个非nil错误,解释原因://如果上下文被取消,则取消//或超过上下文的截止日期。//在Err返回非nil错误后,对Err的连续调用将返回相同的错误。Err() error//Value返回与key或nil的上下文关联的值//如果没有值与键相关联。连续调用Value//相同的键返回相同的结果。////仅对传输的请求范围数据使用上下文值//进程和API边界,不用于将可选参数传递到//功能。////键标识上下文中的特定值。希望的功能//在Context中存储值通常会在全局中分配一个键//然后,变量将该键用作上下文的参数。WithValue和//背景。价值。密钥可以是任何支持相等的类型;//包应将密钥定义为未导出类型,以避免//碰撞。////定义Context键的包应提供类型安全的访问器//对于使用该键存储的值://包用户定义了一个存储在上下文中的用户类型。//包用户////导入“上下文”//用户是存储在上下文中的值的类型。//type用户结构{…}//key是此包中定义的密钥的未导出类型。这可以防止与其他包中定义的键发生冲突。//类型键int//userKey是用户的密钥。上下文中的用户值。它是未报告;客户端使用用户。NewContext和用户。从上下文而不是直接使用此键。//var用户密钥//NewContext返回一个携带值u的新Context。//func-NewContext(ctx-context.context,u*User)上下文。背景{//返回上下文。WithValue(ctx、userKey、u)// 	}//FromContext返回存储在ctx中的User值(如果有的话)。//func FromContext(ctx context.context)(*用户,bool){//u,ok:=ctx。值(userKey)。(*用户)//还你,好吗// 	}Value(key any) any
}

自定义一些结构

Error

//Canceled是取消上下文时[Context.Err]返回的错误。
var Canceled = errors.New("context canceled")//DeadlineExceded是[Context.Err]在上下文发生错误时返回的错误
// deadline passes.
var DeadlineExceeded error = deadlineExceededError{}type deadlineExceededError struct{}func (deadlineExceededError) Error() string   { return "context deadline exceeded" }
func (deadlineExceededError) Timeout() bool   { return true }
func (deadlineExceededError) Temporary() bool { return true }
//当满足以下条件时,stopCtx用作cancelCtx的父上下文
//AfterFunc已向父级注册。
//它包含用于注销AfterFunc的stop函数。
type stopCtx struct {Contextstop func() bool
}
//goroutines统计曾经创建的goroutines的数量;用于测试。
var goroutines atomic.Int32
//&cancelCtxKey是cancelCtx返回自己的密钥。
var cancelCtxKey int//parentCancelCtx返回父级的基础*cancelCtx。
//它通过查找父母来做到这一点。要查找的值(&cancelCtxKey)
//最里面的封闭*cancelCtx,然后检查是否
//父母。Done()与*cancelCtx匹配。(如果没有,*cancelCtx
//已被封装在自定义实现中,提供
//不同的完成渠道,在这种情况下,我们不应该绕过它。)
func parentCancelCtx(parent Context) (*cancelCtx, bool) {done := parent.Done()if done == closedchan || done == nil {return nil, false}p, ok := parent.Value(&cancelCtxKey).(*cancelCtx)if !ok {return nil, false}pdone, _ := p.done.Load().(chan struct{})if pdone != done {return nil, false}return p, true
}//removeChild从其父级删除上下文。
func removeChild(parent Context, child canceler) {if s, ok := parent.(stopCtx); ok {s.stop()return}p, ok := parentCancelCtx(parent)if !ok {return}p.mu.Lock()if p.children != nil {delete(p.children, child)}p.mu.Unlock()
}//canceler是一种可以直接取消的上下文类型。这个
//实现是*cancelCtx和*timerCtx。
type canceler interface {cancel(removeFromParent bool, err, cause error)Done() <-chan struct{}
}//closedchan是一种可重复使用的封闭通道。
var closedchan = make(chan struct{})func init() {close(closedchan)
}

四种Context

emptyCtx

//emptyCtx永远不会被取消,没有值,也没有截止日期。
//它是背景Ctx和todoCtx的共同基础。
type emptyCtx struct{}
func (emptyCtx) Deadline() (deadline time.Time, ok bool) {return
}
func (emptyCtx) Done() <-chan struct{} {return nil
}
func (emptyCtx) Err() error {return nil
}
func (emptyCtx) Value(key any) any {return nil
}

type backgroundCtx struct{ emptyCtx }func (backgroundCtx) String() string {return "context.Background"
}type todoCtx struct{ emptyCtx }func (todoCtx) String() string {return "context.TODO"
}//Background返回一个非nil的空[Context]。它从未被取消,没有
//值,并且没有截止日期。它通常由主功能使用,
//初始化和测试,并作为传入的顶级上下文请求:
func Background() Context {return backgroundCtx{}
}//TODO返回一个非nil的空[Context]。代码应该使用上下文。TODO何时
//不清楚使用哪个上下文,或者它还不可用(因为
//周围函数尚未扩展为接受上下文
//参数)。
func TODO() Context {return todoCtx{}
}

cancelCtx

embed 了一个 context 作为其父 context. 可见,cancelCtx 必然为某个 context 的子 context;
内置了一把锁,用以协调并发场景下的资源获取;
done:实际类型为 chan struct{},即用以反映 cancelCtx 生命周期的通道;
children:一个 set,指向 cancelCtx 的所有子 context;
err:记录了当前 cancelCtx 的错误. 必然为某个 context 的子 context;

//cancelCtx可以取消。取消后,它也会取消任何孩子
// that implement canceler.
type cancelCtx struct {Contextmu       sync.Mutex            //保护以下字段done     atomic.Value          //chan-struct{},延迟创建,由第一个cancel调用关闭children map[canceler]struct{} //在第一次取消呼叫时设置为nilerr      error                 //在第一次取消调用时设置为非nilcause    error                 //在第一次取消调用时设置为非nil
}func (c *cancelCtx) Value(key any) any {if key == &cancelCtxKey {return c}return value(c.Context, key)
}func (c *cancelCtx) Done() <-chan struct{} {d := c.done.Load()if d != nil {return d.(chan struct{})}c.mu.Lock()defer c.mu.Unlock()d = c.done.Load()if d == nil {d = make(chan struct{})c.done.Store(d)}return d.(chan struct{})
}func (c *cancelCtx) Err() error {c.mu.Lock()err := c.errc.mu.Unlock()return err
}//propagateCancel安排在父级为时取消子级。
//它设置cancelCtx的父上下文。
func (c *cancelCtx) propagateCancel(parent Context, child canceler) {c.Context = parentdone := parent.Done()if done == nil {return //家长永远不会被取消}select {case <-done:
//家长已取消child.cancel(false, parent.Err(), Cause(parent))returndefault:}if p, ok := parentCancelCtx(parent); ok {
//parent是一个*cancelCtx,或从其派生而来。p.mu.Lock()if p.err != nil {
//家长已被取消child.cancel(false, p.err, p.cause)} else {if p.children == nil {p.children = make(map[canceler]struct{})}p.children[child] = struct{}{}}p.mu.Unlock()return}if a, ok := parent.(afterFuncer); ok {
//parent实现了AfterFunc方法。c.mu.Lock()stop := a.AfterFunc(func() {child.cancel(false, parent.Err(), Cause(parent))})c.Context = stopCtx{Context: parent,stop:    stop,}c.mu.Unlock()return}goroutines.Add(1)go func() {select {case <-parent.Done():child.cancel(false, parent.Err(), Cause(parent))case <-child.Done():}}()
}type stringer interface {String() string
}func contextName(c Context) string {if s, ok := c.(stringer); ok {return s.String()}return reflectlite.TypeOf(c).String()
}func (c *cancelCtx) String() string {return contextName(c.Context) + ".WithCancel"
}//cancel关闭c.done,取消c的每个孩子,如果
//removeFromParent为true,从其父级的子级中删除c。
//如果这是第一次取消c,则设置c。
func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) {if err == nil {panic("context: internal error: missing cancel error")}if cause == nil {cause = err}c.mu.Lock()if c.err != nil {c.mu.Unlock()return // already canceled}c.err = errc.cause = caused, _ := c.done.Load().(chan struct{})if d == nil {c.done.Store(closedchan)} else {close(d)}for child := range c.children {//注意:在持有父母锁的同时获取孩子的锁。child.cancel(false, err, cause)}c.children = nilc.mu.Unlock()if removeFromParent {removeChild(c.Context, c)}
}//WithoutCancel返回父级的副本,当父级被取消时,该副本不会被取消。
//返回的上下文不返回Deadline或Err,其Done通道为nil。
//对返回的上下文调用[Cause]返回nil。
func WithoutCancel(parent Context) Context {if parent == nil {panic("cannot create context from nil parent")}return withoutCancelCtx{parent}
}type withoutCancelCtx struct {c Context
}func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {return
}func (withoutCancelCtx) Done() <-chan struct{} {return nil
}func (withoutCancelCtx) Err() error {return nil
}func (c withoutCancelCtx) Value(key any) any {return value(c, key)
}func (c withoutCancelCtx) String() string {return contextName(c.c) + ".WithoutCancel"
}//WithDeadline返回父上下文的副本,并调整了截止日期
//如果家长的截止日期已经早于d,
//WithDeadline(parent,d)在语义上等同于parent。回归
//[Context.Done]通道在截止日期到期时关闭,当返回
//cancel函数被调用,或者当父上下文的Done通道为
//关闭,以先发生者为准。
//
//取消此上下文会释放与其关联的资源,因此代码应该
//一旦在此[Context]中运行的操作完成,就调用cancel。
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {return WithDeadlineCause(parent, d, nil)
}//WithDeadlineCause的行为类似于[WithDeadline],但也设置了
//超过截止日期时返回上下文。返回的[CancelFunc]
//不确定原因。
func WithDeadlineCause(parent Context, d time.Time, cause error) (Context, CancelFunc) {if parent == nil {panic("cannot create context from nil parent")}if cur, ok := parent.Deadline(); ok && cur.Before(d) {// The current deadline is already sooner than the new one.return WithCancel(parent)}c := &timerCtx{deadline: d,}c.cancelCtx.propagateCancel(parent, c)dur := time.Until(d)if dur <= 0 {c.cancel(true, DeadlineExceeded, cause) // deadline has already passedreturn c, func() { c.cancel(false, Canceled, nil) }}c.mu.Lock()defer c.mu.Unlock()if c.err == nil {c.timer = time.AfterFunc(dur, func() {c.cancel(true, DeadlineExceeded, cause)})}return c, func() { c.cancel(true, Canceled, nil) }
}

timerCtx

timerCtx 在 cancelCtx 基础上又做了一层封装,除了继承 cancelCtx 的能力之外,新增了一个 time.Timer 用于定时终止 context;另外新增了一个 deadline 字段用于字段 timerCtx 的过期时间.


//timerCtx包含计时器和截止日期。它嵌入了cancelCtx
//实现完成和错误。它通过停止计时器来实现取消
//委托取消Ctx.cancel。
type timerCtx struct {cancelCtxtimer *time.Timer // Under cancelCtx.mu.deadline time.Time
}func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {return c.deadline, true
}func (c *timerCtx) String() string {return contextName(c.cancelCtx.Context) + ".WithDeadline(" +c.deadline.String() + " [" +time.Until(c.deadline).String() + "])"
}func (c *timerCtx) cancel(removeFromParent bool, err, cause error) {c.cancelCtx.cancel(false, err, cause)if removeFromParent {// Remove this timerCtx from its parent cancelCtx's children.removeChild(c.cancelCtx.Context, c)}c.mu.Lock()if c.timer != nil {c.timer.Stop()c.timer = nil}c.mu.Unlock()
}// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this [Context] complete:
//
//	func slowOperationWithTimeout(ctx context.Context) (Result, error) {
//		ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
//		defer cancel()  // releases resources if slowOperation completes before timeout elapses
//		return slowOperation(ctx)
//	}
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {return WithDeadline(parent, time.Now().Add(timeout))
}// WithTimeoutCause behaves like [WithTimeout] but also sets the cause of the
// returned Context when the timeout expires. The returned [CancelFunc] does
// not set the cause.
func WithTimeoutCause(parent Context, timeout time.Duration, cause error) (Context, CancelFunc) {return WithDeadlineCause(parent, time.Now().Add(timeout), cause)
}

valueCtx


//WithValue返回父项的副本,其中与键关联的值为
//瓦尔。
//
//仅对传输进程和进程的请求范围数据使用上下文值
//API,不用于向函数传递可选参数。
//
//提供的密钥必须具有可比性,并且不应为同一类型
//string或任何其他内置类型,以避免它们之间的冲突
//使用上下文的包。WithValue的用户应该定义自己的
//按键类型。为了避免在分配时进行分配
//接口{},上下文键通常具有具体类型
//结构{}。或者,导出上下文键变量的静态
//类型应该是指针或接口。
func WithValue(parent Context, key, val any) Context {if parent == nil {panic("cannot create context from nil parent")}if key == nil {panic("nil key")}if !reflectlite.TypeOf(key).Comparable() {panic("key is not comparable")}return &valueCtx{parent, key, val}
}//valueCtx包含一个键值对。它为该键实现了Value
//将所有其他调用委托给嵌入式Context。
type valueCtx struct {Contextkey, val any
}//stringify尝试在不使用fmt的情况下对v进行字符串化,因为我们没有
//希望上下文取决于unicode表。这仅用于
//*valueCtx。String()。
func stringify(v any) string {switch s := v.(type) {case stringer:return s.String()case string:return scase nil:return "<nil>"}return reflectlite.TypeOf(v).String()
}func (c *valueCtx) String() string {return contextName(c.Context) + ".WithValue(" +stringify(c.key) + ", " +stringify(c.val) + ")"
}func (c *valueCtx) Value(key any) any {if c.key == key {return c.val}return value(c.Context, key)
}func value(c Context, key any) any {for {switch ctx := c.(type) {case *valueCtx:if key == ctx.key {return ctx.val}c = ctx.Contextcase *cancelCtx:if key == &cancelCtxKey {return c}c = ctx.Contextcase withoutCancelCtx:if key == &cancelCtxKey {//这实现了Cause(ctx)==nil
//当使用WithoutCancel创建ctx时。return nil}c = ctx.ccase *timerCtx:if key == &cancelCtxKey {return &ctx.cancelCtx}c = ctx.Contextcase backgroundCtx, todoCtx:return nildefault:return c.Value(key)}}
}

其他

函数

CancelFunc

//CancelFunc告诉一个操作放弃它的工作。
//CancelFunc不会等待工作停止。
//CancelFunc可以被多个goroutines同时调用。
//在第一次调用之后,对CancelFunc的后续调用什么也不做。
type CancelFunc func()//WithCancel返回一个父级的副本,其中包含一个新的“完成”频道。回归
//当调用返回的cancel函数时,上下文的Done通道关闭
//或者当父上下文的“完成”通道关闭时,以先发生者为准。
//
//取消此上下文会释放与其关联的资源,因此代码应该
//一旦在此[Context]中运行的操作完成,就调用cancel。
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {c := withCancel(parent)return c, func() { c.cancel(true, Canceled, nil) }
}

CancelCauseFunc


//CancelCauseFunc的行为类似于[CancelFunc],但还会设置取消原因。
//可以通过在取消的上下文或上调用[cause]来检索此原因
//其衍生的任何上下文。
//
//如果上下文已被取消,CancelCauseFunc不会设置原因。
//例如,如果childContext派生自parentContext:
//-如果parentContext在childContext被cause 2取消之前被cause 1取消,
//那么原因(parentContext)==原因(childContext)==Cause 1
//-如果childContext在parentContext被cause 1取消之前被cause 2取消,
//那么原因(parentContext)==原因1和原因(childContext)==s原因2
type CancelCauseFunc func(cause error)//WithCancelCause的行为类似于[WithCancel],但返回的是[CancelCauseFunc]而不是[CancelFunc]。
//调用带有非nil错误(“cause”)的cancel会在ctx中记录该错误;
//然后可以使用Cause(ctx)检索它。
//使用nil调用cancel会将原因设置为Canceled。
//
//示例用法:
//
//ctx,取消:=上下文。取消原因(父)
//取消(myError)
//ctx。Err()//返回上下文。被取消
//背景。Cause(ctx)//返回myError
func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc) {c := withCancel(parent)return c, func(cause error) { c.cancel(true, Canceled, cause) }
}func withCancel(parent Context) *cancelCtx {if parent == nil {panic("cannot create context from nil parent")}c := &cancelCtx{}c.propagateCancel(parent, c)return c
}//Cause返回一个非nil错误,解释为什么c被取消。
//c或其父项之一的首次取消确定了原因。
//如果取消是通过调用CancelCauseFunc(err)发生的,
//则[Cause]返回err。
//否则,Cause(c)返回与c.Err()相同的值。
//如果c尚未取消,则Cause返回nil。
func Cause(c Context) error {if cc, ok := c.Value(&cancelCtxKey).(*cancelCtx); ok {cc.mu.Lock()defer cc.mu.Unlock()return cc.cause}//没有cancelCtxKey值,所以我们知道c是//不是WithCancelCause创建的某些上下文的后代。//因此,没有具体的返回原因。//如果这不是标准上下文类型之一,//即使没有原因,它也可能仍然有错误。return c.Err()
}

AfterFunc

//AfterFunc安排在ctx完成后在自己的goroutine中调用f
//(已取消或超时)。
//如果ctx已经完成,AfterFunc会立即在自己的goroutine中调用f。
//
//在一个上下文中对AfterFunc的多个调用独立操作;
//一个不能取代另一个。
//
//调用返回的stop函数停止ctx与f的关联。
//如果调用停止f的运行,则返回true。
//如果stop返回false,
//要么上下文已经完成,f已经在自己的goroutine中启动;
//或者f已经停止了。
//stop函数在返回之前不会等待f完成。
//如果呼叫者需要知道f是否完成,
//它必须与f显式协调。
//
//如果ctx有一个“AfterFunction(func)func(bool)”方法,
//AfterFunc将使用它来安排通话。
func AfterFunc(ctx Context, f func()) (stop func() bool) {a := &afterFuncCtx{f: f,}a.cancelCtx.propagateCancel(ctx, a)return func() bool {stopped := falsea.once.Do(func() {stopped = true})if stopped {a.cancel(true, Canceled, nil)}return stopped}
}

afterFuncer

type afterFuncer interface {AfterFunc(func()) func() bool
}type afterFuncCtx struct {cancelCtxonce sync.Once //要么开始运行f,要么停止运行ff    func()
}func (a *afterFuncCtx) cancel(removeFromParent bool, err, cause error) {a.cancelCtx.cancel(false, err, cause)if removeFromParent {removeChild(a.Context, a)}a.once.Do(func() {go a.f()})
}

相关文章:

golang context源码

解析 context结构 Deadline&#xff1a;返回 context 的过期时间&#xff1b; Done&#xff1a;返回 context 中的 channel&#xff1b; Err&#xff1a;返回错误&#xff1b; Value&#xff1a;返回 context 中的对应 key 的值. type Context interface {Deadline() (deadl…...

【MySQL】MySQL的基础语法及其语句的介绍

1、基础语法 mysql -h【主机名】 -u【用户名】 -p //登录MySQL exit或quit; //退出MySQL show database; //查看MySQL下的所有数据库 use 【数据库名】; //进入数据库 show tables; //查看数据库下的所有表名 *MySQL的启动和关闭 &am…...

大模型应用开发自学笔记

理论学习地址&#xff1a; https://zh.d2l.ai/chapter_linear-networks/index.html autodl学术加速&#xff1a; source /etc/network_turboconda常见操作: 删除&#xff1a; conda remove --name myenv --all -y导出&#xff1a; conda env export > environment.yml…...

Spring能够有效地解决单例Bean之间的循环依赖问题

在Spring框架中&#xff0c;earlySingletonObjects和singletonObjects是两个与Bean实例化过程密切相关的概念&#xff0c;它们都存储在DefaultSingletonBeanRegistry类中。这两个概念主要用于Spring的依赖注入机制&#xff0c;特别是针对单例Bean的创建过程。 singletonObject…...

【计算机视觉】三维视觉项目 - Colmap二维图像重建三维场景

COLMAP 3D重建 项目概述项目功能项目运行方式1. 环境准备2. 编译 COLMAP3. 数据准备4. 运行 COLMAP 常见问题及解决方法1. **编译问题**2. **运行问题**3. **数据问题** 项目实战建议项目参考文献 项目概述 COLMAP 是一个开源的三维重建软件&#xff0c;专注于 Structure-from…...

Linux 离线部署 Docker 18.06.3 终极指南(附一键安装卸载脚本)

Linux 离线部署 Docker 18.06.3 终极指南&#xff08;附一键安装/卸载脚本&#xff09; 摘要&#xff1a;本文针对无外网环境的 Linux 服务器&#xff0c;提供基于二进制包的 Docker 18.06.3 离线安装全流程指南。包含自动化脚本设计、服务配置优化及安全卸载方案&#xff0c;…...

ALSA架构学习2(驱动MAX98357A)

1 前言和环境 之前其实写过两篇&#xff0c;一篇是讲ALSA&#xff0c;一篇是I2S。 ALSA架构学习1&#xff08;框架&#xff09;_alsa框架学习-CSDN博客 总线学习5--I2S_max98357接喇叭教程-CSDN博客 在ALSA那篇的结尾&#xff0c;也提了几个小练习。比如&#xff1a; ### 4…...

数据结构*集合框架顺序表-ArrayList

集合框架 常见的集合框架 什么是顺序表 顺序表是一种线性表数据结构&#xff0c;它借助一组连续的存储单元来依次存储线性表中的数据元素。一般情况下采用数组存储。 在数组上完成数据的增删查改。 自定义简易版的顺序表 代码展示&#xff1a; public interface IArray…...

VMware Workstation 保姆级 Linux(CentOS) 创建教程(附 iso)

文章目录 一、下载二、创建 一、下载 CentOS-7.9-x86_64-DVD-2009.iso 二、创建 VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包) VMware Workstation 保姆级安装教程(附安装包)...

51、项⽬中的权限管理怎么实现的

答&#xff1a;权限管理有三个很重要的模块&#xff1b; (1)⽤⼾模块&#xff1a;可以给⽤⼾分配不同的⻆⾊ (2)⻆⾊模块&#xff1a;可以授于⽤⼾不同的⻆⾊&#xff0c;不同的⻆⾊有不同权限 (3)权限模块&#xff1a;⽤于管理系统中的权限接⼝&#xff0c;为⻆⾊提供对…...

软考-信息系统项目管理师-2 信息技术发展

总结思维导图 云计算(掌握) (3)多租户和访问控制管理访问控制管理是云计算应用的核心问题之一云计算访问控制的研究主要集中在云计算访问控制模型、基于ABE密码体制的云计算访问控制、云中多租户及虚拟化访问控制研究云中多租户及虚拟化访问控制是云计算的典型特征。 大数据(…...

Spring Boot JPA 开发之Not an entity血案

项目状况介绍 项目环境 JDK 21Spring Boot 3.4.3Hibernate: 6.6.13.Final项目描述 因为是微服务架构,项目层级如下 project-parent project-com project-A … project-X 其中: project-parent定义依赖库的版本project-com 定义了一些公用的方法和配置,包括持久层的配置。…...

HTMLCSS实现轮播图效果

这段代码实现了一个具有自动轮播、手动切换功能的图片轮播图&#xff0c;并且配有指示器&#xff08;小圆点&#xff09;来显示当前图片位置。轮播图可通过左右箭头按钮进行手动切换&#xff0c;也能自动定时切换&#xff0c;当鼠标悬停在轮播图上时&#xff0c;自动轮播会暂停…...

嵌入式学习——opencv图像库编程

环境配置 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和图像处理库&#xff0c;广泛用于各种计算机视觉任务&#xff0c;如图像处理、视频分析、人脸识别、物体检测、机器学习等。它提供了丰富的函数和工具&#xff0c;用于处理…...

【每日八股】复习 MySQL Day1:事务

文章目录 复习 MySQL Day1&#xff1a;事务MySQL 事务的四大特性&#xff1f;并发事务会出现什么问题&#xff1f;MySQL 事务的隔离级别&#xff1f;不同事务隔离级别下会发生什么问题&#xff1f;MVCC 的实现原理&#xff1f;核心数据结构版本链构建示例可见性判断算法MVCC 可…...

java 设计模式之代理模式

简介 代理模式&#xff1a;使用代理类来增强目标类的功能。在代码结构上&#xff0c;代理对象持有目标对象&#xff0c;通过代理对象访问目标对象&#xff0c;这样可以在不改变目标对象的前提下增加额外的功能&#xff0c;如权限校验、缓存等 代理模式内部的角色&#xff1a;…...

外接键盘与笔记本命令键键位不同解决方案(MacOS)

文章目录 修改键位第一步&#xff1a;打开设置第二步&#xff1a;进入键盘快捷键第三步&#xff1a;修改修饰键设置第四步&#xff1a;调整键位第五步&#xff1a;保存设置tips ikbc c87键盘win键盘没反应的解决亲测的方法这是百度的答案标题常规组合键尝试‌&#xff1a;型号差…...

python爬虫复习

requests模块 爬虫的分类 通用爬虫&#xff1a;将一整张页面进行数据采集聚焦爬虫&#xff1a;可以将页面中局部或指定的数据进行采集 聚焦爬虫是需要建立在通用的基础上来实现 功能爬虫&#xff1a;基于selenium实现的浏览器自动化的操作分布式爬虫&#xff1a;使用分布式机群…...

kotlin知识体系(五) :Android 协程全解析,从作用域到异常处理的全面指南

1. 什么是协程 协程(Coroutine)是轻量级的线程&#xff0c;支持挂起和恢复&#xff0c;从而避免阻塞线程。 2. 协程的优势 协程通过结构化并发和简洁的语法&#xff0c;显著提升了异步编程的效率与代码质量。 2.1 资源占用低&#xff08;一个线程可运行多个协程&#xff09;…...

vscode stm32 variable uint32_t is not a type name 问题修复

问题 在使用vscodekeil开发stm32程序时&#xff0c;发现有时候vscode的自动补全功能失效&#xff0c;且problem窗口一直在报错。variable “uint32_t” is not a type name uint32_t 定义位置 uint32_t 实际是在D:/Keil_v5/ARM/ARMCC/include/stdint.h中定义的。将D:/Keil_v5…...

Formality:Bug记录

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 本文记录博主在使用Synopsys的形式验证工具Formality中遇到的一个Bug。 Bug复现 情况一 // 例1 module dff (input clk, input d_in, output d_out …...

在ubuntu20.04+系统部署VUE及Django项目的过程记录——以腾讯云为例

目录 1. 需求2. 项目准备3. VUE CLI项目部署3.1 部署前的准备3.1.1 后端通信路由修改3.1.2 导航修改 3.2 构建项目3.3 配置nginx代理 4. 后端配置4.1 其他依赖项4.2 单次执行测试4.3 创建Systemd 服务文件4.4 配置 Nginx 作为反向代理 5. 其他注意事项 1. 需求 近期做一些简单…...

回归,git 分支开发操作命令

核心分支说明 主分支&#xff08;master/production&#xff09;存放随时可部署到生产环境的稳定代码&#xff0c;仅接受通过测试的合并请求。 开发分支&#xff08;develop&#xff09;集成所有功能开发的稳定版本&#xff0c;日常开发的基础分支&#xff0c;从该分支创建特性…...

【java+Mysql】学生信息管理系统

学生信息管理系统是一种用于管理学生信息的软件系统&#xff0c;旨在提高学校管理效率和服务质量。本课程设计报告旨在介绍设计和实现学生信息管理系统的过程。报告首先分析了系统的需求&#xff0c;包括学生基本信息管理、成绩管理等功能。接着介绍了系统的设计方案&#xff0…...

小白从0学习网站搭建的关键事项和避坑指南(2)

以下是针对小白从零学习网站搭建的 进阶注意事项和避坑指南&#xff08;第二期&#xff09;&#xff0c;覆盖开发中的高阶技巧、常见陷阱及解决方案&#xff0c;帮助你在实战中提升效率和质量&#xff1a; 一、进阶技术选型避坑 1. 前端框架选择 误区&#xff1a;盲目追求最新…...

Windows 10 上安装 Spring Boot CLI详细步骤

在 Windows 10 上安装 Spring Boot CLI 可以通过以下几种方式完成。以下是详细的步骤说明&#xff1a; 1. 手动安装&#xff08;推荐&#xff09; 步骤 1&#xff1a;下载 Spring Boot CLI 访问 Spring Boot CLI 官方发布页面。下载最新版本的 .zip 文件&#xff08;例如 sp…...

spring boot -- 配置文件application.properties 换成 application.yml

在Spring Boot项目中,application.properties和application.yml是两种常用的配置文件格式,它们各自具有不同的特点和适用场景2。以下是它们之间的主要差异2: 性能差异 4: 加载机制 2: application.properties文件会被加载到内存中,并且只加载一次,之后直接从内存中读取…...

Spring Boot实战:基于策略模式+代理模式手写幂等性注解组件

一、为什么需要幂等性&#xff1f; 核心定义&#xff1a;在分布式系统中&#xff0c;一个操作无论执行一次还是多次&#xff0c;最终结果都保持一致。 典型场景&#xff1a; 用户重复点击提交按钮网络抖动导致的请求重试消息队列的重复消费支付系统的回调通知 不处理幂等的风…...

【Rust 精进之路之第14篇-结构体 Struct】定义、实例化与方法:封装数据与行为

系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 作者: 码觉客 发布日期: 2025-04-20 引言:超越元组,给数据赋予意义 在之前的学习中,我们了解了 Rust 的基本数据类型(标量)以及两种基础的复合类型:元组 (Tuple) 和数组 (Array)。元组允许我们将不同类型的值组合…...

postgres 数据库信息解读 与 sqlshell常用指令介绍

数据库信息: sqlshell Server [localhost]: 192.168.30.101 Database [postgres]: Port [5432]: 5432 Username [postgres]: 用户 postgres 的口令: psql (15.12, 服务器 16.8 (Debian 16.8-1.pgdg120+1)) 警告:psql 主版本15,服务器主版本为16.一些psql功能可能无法正常使…...