golang grpc进阶

protobuf

官方文档
基本数据类型

.proto TypeNotesGo Type
doublefloat64
floatfloat32
int32使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代int32
uint32使用变长编码uint32
uint64使用变长编码uint64
sint32使用变长编码,这些编码在负值时比int32高效的多int32
sint64使用变长编码,有符号的整型值。编码时比通常的int64高效。int64
fixed32总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。uint32
fixed64总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。uint64
sfixed32总是4个字节int32
sfixed64总是8个字节int64
boolbool
string一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。string
bytes可能包含任意顺序的字节数据。[]byte
  1. 在java中,无符号32位和64位整型被表示成他们的整型对应形似,最高位被储存在标志位中。
  2. 对于所有的情况,设定值会执行类型检查以确保此值是有效。
  3. 64位或者无符号32位整型在解码时被表示成为ilong,但是在设置时可以使用int型值设定,在所有的情况下,值必须符合其设置其类型的要求。
  4. python中string被表示成在解码时表示成unicode。但是一个ASCIIstring可以被表示成str类型。
  5. Integer在64位的机器上使用,string在32位机器上使用
    当一个消息被解析的时候,如果被编码的信息不包含一个特定的singular元素,被解析的对象锁对应的域被设置位一个默认值,对于不同类型指定如下:
    ● 对于strings,默认是一个空string
    ● 对于bytes,默认是一个空的bytes
    ● 对于bools,默认是false
    ● 对于数值类型,默认是0
    ● 对于枚举,默认是第一个定义的枚举值,必须为0;
    ● 对于消息类型(message),域没有被设置,确切的消息是根据语言确定的,详见generated code guide
    对于可重复域的默认值是空(通常情况下是对应语言中空列表)。
    注:对于标量消息域,一旦消息被解析,就无法判断域释放被设置为默认值(例如,例如boolean值是否被设置为false)还是根本没有被设置。你应该在定义你的消息类型时非常注意。例如,比如你不应该定义boolean的默认值false作为任何行为的触发方式。也应该注意如果一个标量消息域被设置为标志位,这个值不应该被序列化传输。
    查看generated code guide选择你的语言的默认值的工作细节。

proto文件中引入另一个proto文件

1.被引用的proto要先转成go代码
2.使用protobuf提供的proto引用格式与自定义的proto引用格式不同
base.proto

syntax = "proto3";
// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto";
message Empty{}
message Pong{string id=1;
}

转成go代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative base.proto 

hello.proto

syntax = "proto3";
// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto";
import "base.proto";
import "google/protobuf/empty.proto";
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口rpc Ping(google.protobuf.Empty)returns (Pong);
}
message HelloRquest{string name=1;//1是编号不是值string url=2;
}
message HelloReply{string message=1;
}

转成go代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello.proto

message嵌套

目录结构
在这里插入图片描述

hello.proto

syntax = "proto3";
// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto";
import "base.proto";
import "google/protobuf/empty.proto";
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口rpc Ping(google.protobuf.Empty)returns (Pong);
}
message HelloRquest{string name=1;//1是编号不是值string url=2;
}message HelloReply{string message=1;repeated Result data=2;message Result{string name=1;string url=2;}
}

转换

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello.proto

使用

package mainimport "GolangStudy/Introduction/grpc/example4/proto"func main() {_ = proto.HelloReply_Result{}
}

枚举类型

目录结构

在这里插入图片描述
hello2.proto

syntax = "proto3";// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto1";
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口
}
enum Gender{MALE=0;FEMALE=1;
}
message HelloRquest{string name=1;//1是编号不是值Gender g=3;
}
message HelloReply{string message=1;
}

转换

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello2.proto

调用

package mainimport (_ "GolangStudy/Introduction/grpc/example4/proto""GolangStudy/Introduction/grpc/example4/proto1""context""fmt""google.golang.org/grpc"
)func main() {// _ = proto.HelloReply_Result{}conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()c := proto1.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto1.HelloRquest{Name: "bobby",G:    proto1.Gender_FEMALE,})if err != nil {panic(err)}fmt.Println(r.Message)
}

map类型

hello2.proto

syntax = "proto3";// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto1";
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口
}
enum Gender{MALE=0;FEMALE=1;
}
message HelloRquest{string name=1;//1是编号不是值Gender g=2;map<string,string> mp=3;
}
message HelloReply{string message=1;
}

转换

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello2.proto

使用

package mainimport (_ "GolangStudy/Introduction/grpc/example4/proto""GolangStudy/Introduction/grpc/example4/proto1""context""fmt""google.golang.org/grpc"
)func main() {// _ = proto.HelloReply_Result{}conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()c := proto1.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto1.HelloRquest{Name: "bobby",G:    proto1.Gender_FEMALE,Mp: map[string]string{"name":    "bobby","company": "mooc",},})if err != nil {panic(err)}fmt.Println(r.Message)
}

timestamp类型

hello2.proto

syntax = "proto3";// 生成proto文件所在包路径
package protos;
// 影响go文件生成位置和包名
//.是当前文件夹
option go_package = ".;proto1";
import "google/protobuf/timestamp.proto";
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口
}
enum Gender{MALE=0;FEMALE=1;
}
message HelloRquest{string name=1;//1是编号不是值Gender g=2;map<string,string> mp=3;google.protobuf.Timestamp addTime=4;
}
message HelloReply{string message=1;
}

转换

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello2.proto

使用

package mainimport (_ "GolangStudy/Introduction/grpc/example4/proto""GolangStudy/Introduction/grpc/example4/proto1""context""fmt""time""google.golang.org/grpc""google.golang.org/protobuf/types/known/timestamppb"
)func main() {// _ = proto.HelloReply_Result{}conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()c := proto1.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto1.HelloRquest{Name: "bobby",G:    proto1.Gender_FEMALE,Mp: map[string]string{"name":    "bobby","company": "mooc",},AddTime: timestamppb.New(time.Now()),})if err != nil {panic(err)}fmt.Println(r.Message)
}

grpc

metadata

grpc让我们可以像本地调用一样实现远程调用,对于每一次的RPC调用中,都可能会有一些有用的数据,而这些数据就可以通过metadata来传递。metadata是以key-value的形式存储数据的,其中key是string类型,而value是[]string,即一个字符串数组类型。metadata使得client和server能够为对方提供关于本次调用的一些信息,就像一次http请求的RequestHeader和ResponseHeader一样。http中header的生命周周期是一次http请求,那么metadata的生命周期就是一次rpc调用。
实例化

//第一种方式
md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})
//第二种方式 key不区分大小写,会被统一转成小写。
md := metadata.Pairs("key1", "val1","key1", "val1-2", // "key1" will have map value []string{"val1", "val1-2"}"key2", "val2",
)

使用

//发送md := metadata.Pairs("key", "val")// 新建一个有 metadata 的 context
ctx := metadata.NewOutgoingContext(context.Background(), md)// 单向 RPC
response, err := client.SomeRPC(ctx, someRequest)
//接收
func (s *server) SomeRPC(ctx context.Context, in *pb.SomeRequest) (*pb.SomeResponse, err) {md, ok := metadata.FromIncomingContext(ctx)// do something with metadata
}

使用例子

拦截器

grpc Go支持“拦截器”,即在将请求传递到用户的应用程序逻辑之前在 grpc服务器上执行的中间件,或者在用户调用时在 grpc 客户端上执行的中间件。它是实现常见模式的完美方式:身份验证、日志记录、跟踪、指标、验证、重试、速率限制等,它们可以成为出色的通用构建块,让您轻松构建多个微服务。
实例
目录结构
在这里插入图片描述
hello.proto

syntax = "proto3";
option go_package = ".;proto";
service Greeter {rpc SayHello (HelloRequest) returns (HelloReply);
}
//将 sessionid放入 放入cookie中 http协议
message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}

生成

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello2.proto

server

package mainimport ("context""fmt""net""google.golang.org/grpc""GolangStudy/Introduction/grpc/interpretor/proto"
)type Server struct{}func (s *Server) SayHello(ctx context.Context, request *proto.HelloRequest) (*proto.HelloReply,error) {return &proto.HelloReply{Message: "hello " + request.Name,}, nil
}func main() {var interceptor grpc.UnaryServerInterceptorinterceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {// 继续处理请求fmt.Println("接收到新请求")res, err := handler(ctx, req)fmt.Println("请求处理完成")return res, err}var opts []grpc.ServerOptionopts = append(opts, grpc.UnaryInterceptor(interceptor))g := grpc.NewServer(opts...)proto.RegisterGreeterServer(g, &Server{})lis, err := net.Listen("tcp", "0.0.0.0:50051")if err != nil {panic("failed to listen:" + err.Error())}err = g.Serve(lis)if err != nil {panic("failed to start grpc:" + err.Error())}
}

client

package mainimport ("context""fmt""time""google.golang.org/grpc""GolangStudy/Introduction/grpc/interpretor/proto"
)func interceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {start := time.Now()err := invoker(ctx, method, req, reply, cc, opts...)fmt.Printf("method=%s req=%v rep=%v duration=%s error=%v\n", method, req, reply, time.Since(start), err)return err
}func main() {//streamvar opts []grpc.DialOptionopts = append(opts, grpc.WithInsecure())// 指定客户端interceptoropts = append(opts, grpc.WithUnaryInterceptor(interceptor))conn, err := grpc.Dial("localhost:50051", opts...)if err != nil {panic(err)}defer conn.Close()c := proto.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: "bobby"})if err != nil {panic(err)}fmt.Println(r.Message)
}

拦截器框架

auth认证

hello.proto

syntax = "proto3";
option go_package = ".;proto";
service Greeter {rpc SayHello (HelloRequest) returns (HelloReply);
}message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}

生成

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative hello2.proto

server

package mainimport ("context""fmt""net""google.golang.org/grpc""google.golang.org/grpc/codes""google.golang.org/grpc/metadata""google.golang.org/grpc/status""GolangStudy/Introduction/grpc/token_auth/proto"
)type Server struct{}func (s *Server) SayHello(ctx context.Context, request *proto.HelloRequest) (*proto.HelloReply,error) {return &proto.HelloReply{Message: "hello " + request.Name,}, nil
}func main() {var interceptor grpc.UnaryServerInterceptorinterceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {// 继续处理请求fmt.Println("接收到新请求")md, ok := metadata.FromIncomingContext(ctx)if !ok {return resp, status.Error(codes.Unauthenticated, "无token认证信息")}var (appid  stringappkey string)if va1, ok := md["appid"]; ok {appid = va1[0]}if va1, ok := md["appkey"]; ok {appkey = va1[0]}fmt.Println(appid, appkey)if appid != "101010" || appkey != "i am key" {return resp, status.Error(codes.Unauthenticated, "无token认证信息")}res, err := handler(ctx, req)fmt.Println("请求处理完成")return res, err}var opts []grpc.ServerOptionopts = append(opts, grpc.UnaryInterceptor(interceptor))g := grpc.NewServer(opts...)proto.RegisterGreeterServer(g, &Server{})lis, err := net.Listen("tcp", "0.0.0.0:50051")if err != nil {panic("failed to listen:" + err.Error())}err = g.Serve(lis)if err != nil {panic("failed to start grpc:" + err.Error())}
}

client

package mainimport ("context""fmt""GolangStudy/Introduction/grpc/token_auth/proto""google.golang.org/grpc"
)type customCredential struct{}func (cc *customCredential) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {return map[string]string{"appid":  "101010","appkey": "i am key",}, nil
}// RequireTransportSecurity indicates whether the credentials requires
// transport security.
func (cc *customCredential) RequireTransportSecurity() bool {return false
}
func main() {// interceptor := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {// 	start := time.Now()// 	md := metadata.New(map[string]string{// 		"appid":  "101010",// 		"appkey": "i am key",// 	})// 	ctx = metadata.NewOutgoingContext(context.Background(), md)// 	err := invoker(ctx, method, req, reply, cc, opts...)// 	fmt.Printf("method=%s req=%v rep=%v duration=%s error=%v\n", method, req, reply, time.Since(start), err)// 	return err// }//streamvar opts []grpc.DialOptionopts = append(opts, grpc.WithInsecure())// 指定客户端interceptoropts = append(opts, grpc.WithPerRPCCredentials(&customCredential{}))conn, err := grpc.Dial("127.0.0.1:50051", opts...)if err != nil {panic(err)}defer conn.Close()c := proto.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: "bobby"})if err != nil {panic(err)}fmt.Println(r.Message)
}

验证器

实例
Protocol Buffer Validation
使用的mac电脑,使用官网的第二种第三种都试过了不可以,第二种在$GOPATH:bin找不到protoc-gen-validate文件,第三种能找到但是将proto转换成go文件时会一直报如下错误,最后使用了第一种才成功。

protoc-gen-validate: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--validate_out: protoc-gen-validate: Plugin failed with status code 1.
//第一种
go install github.com/envoyproxy/protoc-gen-validate@latest//第二种
go get -d github.com/envoyproxy/protoc-gen-validate//第三种
git clone https://github.com/bufbuild/protoc-gen-validate.git
cd $GOPATH/bin
cd protoc-gen-validate 
make build

hello.proto

syntax = "proto3";option go_package=".;proto";
import "validate.proto";service Greeter {rpc SayHello (Person) returns (Person);
}message Person {uint64 id    = 1 [(validate.rules).uint64.gt    = 999];string email = 2 [(validate.rules).string.email = true];string mobile  = 3 [(validate.rules).string = {pattern:  "^1[3456789]\\d{9}$"}];}

转换

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative  --validate_out="lang=go:." hello.proto

client

package mainimport ("GolangStudy/Introduction/grpc/validate/proto""context""fmt""google.golang.org/grpc"
)type customCredential struct{}func main() {var opts []grpc.DialOption//opts = append(opts, grpc.WithUnaryInterceptor(interceptor))opts = append(opts, grpc.WithInsecure())conn, err := grpc.Dial("localhost:50051", opts...)if err != nil {panic(err)}defer conn.Close()c := proto.NewGreeterClient(conn)//rsp, _ := c.Search(context.Background(), &empty.Empty{})rsp, err := c.SayHello(context.Background(), &proto.Person{Id:     9999,Email:  "bobby@qq.com",Mobile: "19999999999",})if err != nil {panic(err)}fmt.Println(rsp.Id)
}

server

package mainimport ("context""net""google.golang.org/grpc/codes""google.golang.org/grpc/status""google.golang.org/grpc""GolangStudy/Introduction/grpc/validate/proto"
)type Server struct{}func (s *Server) SayHello(ctx context.Context, request *proto.Person) (*proto.Person,error) {return &proto.Person{Id: 32,}, nil
}type Validator interface {Validate() error
}func main() {var interceptor grpc.UnaryServerInterceptorinterceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {// 继续处理请求if r, ok := req.(Validator); ok {if err := r.Validate(); err != nil {return nil, status.Error(codes.InvalidArgument, err.Error())}}return handler(ctx, req)}var opts []grpc.ServerOptionopts = append(opts, grpc.UnaryInterceptor(interceptor))g := grpc.NewServer(opts...)proto.RegisterGreeterServer(g, &Server{})lis, err := net.Listen("tcp", "0.0.0.0:50051")if err != nil {panic("failed to listen:" + err.Error())}err = g.Serve(lis)if err != nil {panic("failed to start grpc:" + err.Error())}
}

错误码

CodeNumberDescription
OK0Not an error; returned on success.
CANCELLED1操作被取消,通常是由调用者取消的。
UNKNOWN2未知错误。例如,当从另一个地址空间接收到的状态值属于该地址空间中未知的错误空间时,可能会返回此错误。此外,由未返回足够错误信息的 API 引发的错误也可能会转换为此错误。
INVALID_ARGUMENT3客户端指定了无效参数。请注意,这与 FAILED_PRECONDITION 不同。
DEADLINE_EXCEEDED4操作完成之前截止日期已过。对于更改系统状态的操作,即使操作已成功完成,也可能会返回此错误。例如,服务器的成功响应可能会延迟很长时间
NOT_FOUND5未找到某些请求的实体(例如文件或目录)。服务器开发人员请注意:如果整个用户类别的请求被拒绝,例如逐步推出功能或未记录的许可名单,则可以使用 NOT_FOUND。如果拒绝一类用户中的某些用户的请求,例如基于用户的访问控制,则必须使用 PERMISSION_DENIED。
ALREADY_EXISTS6客户端尝试创建的实体(例如文件或目录)已存在
PERMISSION_DENIED7调用者没有执行指定操作的权限。 PERMISSION_DENIED 不得用于因耗尽某些资源而导致的拒绝(对于这些错误,请使用 RESOURCE_EXHAUSTED 代替)。如果无法识别调用者,则不得使用 PERMISSION_DENIED(对于这些错误,请使用 UNAUTHENTICATED)。此错误代码并不意味着请求有效或请求的实体存在或满足其他先决条件
RESOURCE_EXHAUSTED8某些资源已耗尽,可能是每个用户的配额,或者可能是整个文件系统空间不足。
FAILED_PRECONDITION9操作被拒绝,因为系统未处于操作执行所需的状态。例如,要删除的目录非空、rmdir 操作应用于非目录等。服务实现者可以使用以下准则来决定 FAILED_PRECONDITION、ABORTED 和 UNAVAILABLE: (a) 如果客户端可以仅重试失败的调用。 (b) 如果客户端应在更高级别重试(例如,当客户端指定的测试和设置失败时,指示客户端应重新启动读取-修改-写入序列),则使用 ABORTED。 © 如果客户端在系统状态明确修复之前不应重试,则使用 FAILED_PRECONDITION。例如,如果“rmdir”由于目录非空而失败,则应返回 FAILED_PRECONDITION,因为除非从目录中删除文件,否则客户端不应重试。
ABORTED10操作被中止,通常是由于并发问题,例如定序器检查失败或事务中止。请参阅上面的指南来决定 FAILED_PRECONDITION、ABORTED 和 UNAVAILABLE。
OUT_OF_RANGE11尝试的操作超出了有效范围。例如,查找或读取文件末尾之后的内容。与 INVALID_ARGUMENT 不同,此错误指示如果系统状态发生更改则可以修复的问题。例如,如果要求读取不在 [0,2^32-1] 范围内的偏移量,32 位文件系统将生成 INVALID_ARGUMENT,但如果要求读取超过当前偏移量的偏移量,则会生成 OUT_OF_RANGE文件大小。 FAILED_PRECONDITION 和 OUT_OF_RANGE 之间有相当多的重叠。我们建议在应用时使用 OUT_OF_RANGE(更具体的错误),以便迭代空间的调用者可以轻松查找 OUT_OF_RANGE 错误以检测何时完成。
UNIMPLEMENTED12此服务未实现或不支持/启用该操作。
INTERNAL13内部错误。这意味着底层系统所期望的一些不变量已经被打破。该错误代码是为严重错误保留的。
UNAVAILABLE14该服务目前不可用。这很可能是一种瞬态情况,可以通过后退重试来纠正。请注意,重试非幂等操作并不总是安全的。
DATA_LOSS15不可恢复的数据丢失或损坏。
UNAUTHENTICATED16该请求没有该操作的有效身份验证凭据

实例
服务端

status.New(codes.InvalidArgument, "invalid username")

客户端

st, ok := status.FromError(err)
if !ok {// Error was not a status error
}
st.Message()
st.Code()

grpc的超时机制

ctx, cancel := context.WithTimeout(context.TODO(), time.Second*3)
defer cancel()r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})

实例

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

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

相关文章

Linux:无法为立即文档创建临时文件: 设备上没有空间

虚拟机磁盘空间不足解决记录 1、问题描述2、问题解决 1、问题描述 在命令行输入命令按Tab键时出现如下报错&#xff1a; 很明显&#xff0c;设备上没有空间&#xff0c;即磁盘空间不足。通过命令查看具体情况如下&#xff1a; df -h2、问题解决 首先想到的是虚拟机扩容。关机虚…

每日学习一个数据结构-树

文章目录 树的相关概念一、树的定义二、树的基本术语三、树的分类四、特殊类型的树五、树的遍历六、树的应用场景 树的遍历一、前序遍历二、中序遍历三、后序遍历使用java代码实现遍历总结 树的相关概念 树是一种重要的非线性数据结构&#xff0c;在计算机科学中有着广泛的应用…

C++IO流

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 CIO流 收录于专栏 [C进阶学习] 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. C语言的输入与输出 2. 流是什…

(PyTorch) 深度学习框架-介绍篇

前言 在当今科技飞速发展的时代&#xff0c;人工智能尤其是深度学习领域正以惊人的速度改变着我们的世界。从图像识别、语音处理到自然语言处理&#xff0c;深度学习技术在各个领域都取得了显著的成就&#xff0c;为解决复杂的现实问题提供了强大的工具和方法。 PyTorch 是一个…

C语言基础(7)之操作符(1)(详解)

目录 1. 各种操作符介绍 1.1 操作符汇总表 2. 移位操作符 2.1 移位操作符知识拓展 —— 原码、反码、补码 2.2 移位操作符讲解 2.2.1 右移操作符 ( >> ) 2.2.2 左移操作符 ( << ) 3. 位操作符 3.1 & (按位与) 3.2 | (按位或) 3.3 ^ (按位异或) 3.4…

深度学习每周学习总结J1(ResNet-50算法实战与解析 - 鸟类识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&#xff0c;学习率&a…

Python 解析 html

一、场景分析 假设有如下 html 文档&#xff1a; 写一段 python 脚本&#xff0c;解析出里面的数据&#xff0c;包括经度维度。 <div classstorelist><ul><li lng"100.111111" lat"10.111111"><h4>联盟店1</h4><p>…

【C语言】数组练习

【C语言】数组练习 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚练习2、二分查找 练习1&#xff1a;多个字符从两端移动&#xff0c;向中间汇聚 编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 练习2、二分查找 在⼀个升序的数组中查找指…

--- java数据结构 map set ---

java中map 和 set的底层实现是通过搜索树和哈希函桶来实现 搜索树 二叉搜索树有叫二叉排序树 他具有以下的特点 若存在左节点&#xff0c;那么他左节点的值一定小于根节点 若存在右节点&#xff0c;那么他右节点的值一定大于根节点 它的左右子树也是搜索树 对他进行中序…

Oracle架构之物理存储中各种文件详解

文章目录 1 物理存储1.1 简介1.2 数据文件&#xff08;data files&#xff09;1.2.1 定义1.2.2 分类1.2.2.1 系统数据文件1.2.2.2 撤销数据文件1.2.2.3 用户数据文件1.2.2.4 临时数据文件 1.3 控制文件&#xff08;Control files&#xff09;1.3.1 定义1.3.2 查看控制文件1.3.3…

大数据与人工智能:基础与应用的多维思考

大数据与人工智能&#xff1a;基础与应用的多维思考 前言一、时代定位与发展方向二、人工智能的本质与学科融合三、大数据和人工智能的构成要素与大众需求四、计算机系统结构与基础软件的重要性五、研究途径与领域知识的作用六、发展的态度与责任 前言 当下&#xff0c;大数据…

分布式学习02-CAP理论

文章目录 CAP三指标一致性可用性分区容错性 CAP不可能三角P存在的必要性CP理论AP理论 CAP理论对分布式系统的特性做了高度抽象&#xff0c;将其抽象为一致性、可用性、分区容错性。 并对特征间的冲突做了总结&#xff1a;CAP不可能三角。 CAP三指标 一致性&#xff08;Consis…

Windows环境Apache httpd 2.4 web服务器加载PHP8:Hello,world!

Windows环境Apache httpd 2.4 web服务器加载PHP8&#xff1a;Hello&#xff0c;world&#xff01; &#xff08;1&#xff09;首先需要安装apache httpd 2.4 web服务器&#xff1a; Windows安装启动apache httpd 2.4 web服务器-CSDN博客文章浏览阅读222次&#xff0c;点赞5次&…

Git 下载及安装超详教程(2024)

操作环境&#xff1a;Win 10、全程联网 一、什么是Git&#xff1f; Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 创立&#xff0c;用于有效、高速地处理从小到大的项目版本管理。Git 是目前世界上最流行的版本控制系统&#xff0c;被广泛用于软件开发中…

ECCV 2024 | 融合跨模态先验与扩散模型,快手处理大模型让视频画面更清晰!

计算机视觉领域顶级会议 European Conference on Computer Vision&#xff08;ECCV 2024&#xff09;将于9月29日至10月4日在意大利米兰召开&#xff0c;快手音视频技术部联合清华大学所发表的题为《XPSR: Cross-modal Priors for Diffusion-based Image Super-Resolution》——…

安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?

视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为…

基于Zynq SDIO WiFi移植三(支持2.4/5G)

应用问题-WIFI作为AP-hostapd多次连接 设备作为WIFI热点时&#xff0c;连接出现了下述问题&#xff1a; 1 手机连接需要三次&#xff0c;三次都需要输入密码&#xff1b; 2 平板连接需要三次&#xff0c;三次都需要输入密码&#xff1b; 3 电脑连接需要一次&#xff0c;无感…

计算机视觉——图像修复综述篇

目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …

YOLOv11改进 | Conv篇 | YOLOv11引入SKConv

1. SKConv介绍 1.1 摘要:在标准卷积神经网络(CNN)中,每层中阿尔蒂神经元的感受野被设计为共享相同的大小。在神经科学界众所周知,视觉皮层神经元的感受野大小受到刺激的调制,这在构建CNN时很少考虑。我们在CNN中提出了一种动态选择机制,允许每个神经元根据输入信息的多…

[深度学习][python]yolov11+deepsort+pyqt5实现目标追踪

【算法介绍】 YOLOv11、DeepSORT和PyQt5的组合为实现高效目标追踪提供了一个强大的解决方案。 YOLOv11是YOLO系列的最新版本&#xff0c;它在保持高检测速度的同时&#xff0c;通过改进网络结构、优化损失函数等方式&#xff0c;提高了检测精度&#xff0c;能够同时处理多个尺…