Temp

7805 bookmarks
Custom sorting
Home
Home
包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读,读书笔记, 开源项目...
·pdai.tech·
Home
Golang代码优化15-AOP(面向切面编程)
Golang代码优化15-AOP(面向切面编程)
因为某些原因,触发了我要深入了解下AOP。 什么是AOP 核心概念 Go实现AOP 什么是AOP AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。扩展功能不修改源代码实现。 主要应用场景:日志记录,性能统计,安全控制,事务处理,异常处理等等。 核心概念 JoinPoint:连
·hongker.github.io·
Golang代码优化15-AOP(面向切面编程)
Go语言没有动态代理? 本来想用AOP写框架,怎么实现才好 - Go语言中文网 - Golang中文社区
Go语言没有动态代理? 本来想用AOP写框架,怎么实现才好 - Go语言中文网 - Golang中文社区
java有AOP机制。 go 我看了看反射机制。好像没有实现动态代理。 如果是这样我感觉能超过JAVA简直不可能, 离开了AOP 代码会越来越臃肿。 各位大神,GO怎么实现动态代理。来切入式编程呢?
·studygolang.com·
Go语言没有动态代理? 本来想用AOP写框架,怎么实现才好 - Go语言中文网 - Golang中文社区
Go1.18 快讯:constraints 包被移除标准库
Go1.18 快讯:constraints 包被移除标准库
大家好,我是 polarisxu。 Go1.18 已经发布 Beta2 版本了,正式版本预计 3 月份发布。Go1.18 最重要的特性莫过于泛型,之前写过几篇相关文章: Go泛型系列:提前掌握Go泛型的基本使用 Go泛型系列:Go1.18 类型约束那些事 Go 泛型入门教程 其中提到一个标准库新包:constraints,相关提案见:https://github.com/golang/go/issues/
·polarisxu.studygolang.com·
Go1.18 快讯:constraints 包被移除标准库
深入理解 Go Comparable Type | SORCERERXW
深入理解 Go Comparable Type | SORCERERXW
在 Go reflect 包里面对 Type 有一个 Comparable 的定义: package reflect type Type interface { // Comparable reports whether values of this type are comparable. Comparable() bool } 正如字面意思,Comparable 表示一个类型是否可以直接使用运算符比较。Go spec 罗列了所有可比较的类型,其中将可比较性划分为两个维度(如果不符合要求,会直接在编译期报错): Comparable:可以使用 == 和 != 比较,非黑即白 Ordered:可以使用 = ==? equal func(unsafe.Pointer, unsafe.Pointer) bool } func (t *rtype) Comparable() bool { return t.equal != nil } 很简单,其实就是为每一个类型配备了一个 equal 比较函数,如果有这个函数则是 comparable。 上面的 rtype 结构就包含在所有类型的内存头部: // emptyInterface is the header for an interface{} value. type emptyInterface struct { typ *rtype word unsafe.Pointer } 所以如果希望知道某一个类型的 equal 需要翻阅对应类型源码。通过编译 SSA 可以找到对应类型的比较函数。 比如在 go/src/runtime/alg.go 下可以看到 interface 的 equal 函数的具体实现: func efaceeq(t *_type, x, y unsafe.Pointer) bool { if t == nil { return true } eq := t.equal if eq == nil { panic(errorString("comparing uncomparable type " + t.string())) } if isDirectIface(t) { // t.kind == kindDirectIface // Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof. // Maps and funcs are not comparable, so they can't reach here. // Ptrs, chans, and single-element items can be compared directly using ==. return x == y } return eq(x, y) } 在知道上面的设定之后,可以理解很多我们在开发当中碰到的错误。 我们常常在模块内定义错误时,会定义出如下类型: type CustomError struct { Metadata map[string]string Message string } func (c CustomError) Error() string { return c.Message } var ( ErrorA = CustomError{Message:"A", Matadata: map[string]string{"Reason":""}} ErrorB = CustomError{Message:"B"} ) func DoSomething() error { return ErrorA } 而我们在外部接收到错误之后常常会使用 errors.Is 来判断错误类型: err:=DoSomething() if errors.Is(err, ErrorA) { // handle err } 但是会发现上面这个判断无论如何都是 false。研究一下 errors.Is 的源码: func Is(err, target error) bool { if target == nil { return err == target } isComparable := reflect.TypeOf(target).Comparable() for { if isComparable && err == target { return true } if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { return true } if err = errors.Unwrap(err); err == nil { return false } } } 可以看到这是一个在 error tree 上递归的流程,真值的终结条件是 err==target ,但是前提是 target 本身得是 comparable 的。 如上描述,如果不加上这一段约束,会引发 panic。 所以如果我们把一个 map 放入了 error struct,就导致这个 error 变为 incomparable,永远无法成功比较。 解决方案也很简单,就是将 Error 定义指针类型: var ( ErrorA = &CustomError{Message:"A", Matadata: map[string]string{"Reason":""}} ErrorB = &CustomError{Message:"B"} ) 指针类型比较只需要是否检查是否指向同一个对象,这样就能顺利比较了。 这是 Go FAQ 的其中一条: func returnsError() error { var p *MyError = nil if bad() { p = ErrBad } return p // Will always return a non-nil error. } 上面返回的 p 永远不会与 nil 相等。 这是为什么呢,因为 error 是一个 interface,从上面可以知道,interface 之间比较需要保证两者的 Type 和 Value 两两相等: 语言内的 nil 可以理解为一个 Type 和 Value 均为空的 interface 代码里面返回的 p 虽然 Value 为空,但是 Type 是 *MyError 所以 p!=nil 。 正确的代码应该是这样的: func returnsError() error { if bad() { return ErrBad } return nil } 这个问题不仅仅是抛出错误的时候会出现,任何返回 interface 的场景都需要注意。 Go 的 Context 可以存取一些全局变量,其存储方式是一个树状结构,每一次取值的时候就会从当前节点一路遍历到根节点,查找是否有对应的 Key: func (c *valueCtx) Value(key interface{}) interface{} { if c.key == key { return c.val } return c.Context.Value(key) } 那么就可能会出现因为子节点的 Key 与其中一个父节点的 Key 相同,导致 Value 被错误地覆盖。比如: ctx = Context.Background() ctx = context.WithValue(ctx, "key", "123") ctx = context.WithValue(ctx, "key", "456") ctx.Value("key") // 456 因为 Context 是全链路透传的,谁都没法保证一个 Key 是否会被其中某一层覆盖。这个问题本质上是:当Key 的类型为 Integer/Float/String/Complex 时,"伪造"一个值相同的 Key 太容易了。那么我们可以运用 Go Comparable 的特性,选择无法被"伪造"的类型作为 Key。推荐两种比较优雅的方式: 指针类型 var key = byte(0) ctx = context.WithValue(ctx, &key, "123") ctx.Value(&key) 这样一来,除了包内函数,没有其他代码还能构造出相同的指针了。 Struct 类型 从上文可以知道,strcut 只要类型相同,内部的值相等,就能直接使用 == 判断相等,那么我们可以直接使用 struct 作为 Key。 type key struct {} ctx = context.WithValue(ctx, key{}, "123") ctx.Value(key{}) 同样的,我们把 struct 定义为私有类似,包外也无法构造出相同的 key。 我们知道空 struct 是不占用内存的,这么做相比指针类型的 Key,可以减少内存开销。
·sorcererxw.com·
深入理解 Go Comparable Type | SORCERERXW
Go泛型介绍[译] | Tony Bai
Go泛型介绍[译] | Tony Bai
本文永久链接 - https://tonybai.com/2022/03/25/intro-generics Go核心团队在官博上发布了一篇名为《An Introduction To Generics》的文章,该文章基于Robert Griesemer和Ian Lance Taylor在2021年GopherCon大会
·tonybai.com·
Go泛型介绍[译] | Tony Bai
总结一下 Go 语言中的反射 - 古明地盆 - 博客园
总结一下 Go 语言中的反射 - 古明地盆 - 博客园
什么是反射 反射:用大白话解释就是,程序在运行期间可以动态地查看某个变量的值的类型、并且还能够动态调用、修改自身的行为。Python应该是反射机制最为彪悍的语言了,当然查看自身类型更是不在话下,这一点
·cnblogs.com·
总结一下 Go 语言中的反射 - 古明地盆 - 博客园
Unity中文课堂
Unity中文课堂
Unity中文课堂是Unity官方搭建的线上学习平台,提供官方免费教程,以及三方讲师原创的Unity付费课程,帮助中国Unity开发者获得开发游戏、动画、VR、AR等项目所必需的实时3D开发技术。
·learn.u3d.cn·
Unity中文课堂
How to check for an empty struct?
How to check for an empty struct?
I define a struct ... type Session struct { playerId string beehive string timestamp time.Time } Sometimes I assign an empty session to it (because nil is not possible) session = Ses...
·stackoverflow.com·
How to check for an empty struct?
原码, 反码, 补码 详解 - ziqiu.zhang - 博客园
原码, 反码, 补码 详解 - ziqiu.zhang - 博客园
本篇文章包含了讲解了机器的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用补码的加法计算原码的减法. 其中的很多资料也是在网上收集的, 并且加入了更深层
·cnblogs.com·
原码, 反码, 补码 详解 - ziqiu.zhang - 博客园
我们为什么要选择小众语言Rust来实现TiKV?
我们为什么要选择小众语言Rust来实现TiKV?
本文是 InfoQ 策划的语言专题其中的 Rust 篇。Rust 对于国内大多数开发者来说会显得比较陌生,但是已经在世界范围内作为公认的 C/C++ 的有希望的挑战者。从长远来看,在对内存安全性和性能有严苛要求的场景,将会有广阔空间。
·mp.weixin.qq.com·
我们为什么要选择小众语言Rust来实现TiKV?
TiDB 架构的演进和开发哲学
TiDB 架构的演进和开发哲学
对于一个从零开始的数据库来说:选择什么语言,整体架构怎么做,要不要开源,如何去测试…太多的问题需要去考量。
·mp.weixin.qq.com·
TiDB 架构的演进和开发哲学
微信公众号文章URL的种类与结构
微信公众号文章URL的种类与结构
微信公众号是微信围墙花园的一部分。外界想访问其中内容时,往往需要面对一个很长的URL——其过分的长度与不甚清晰的含义给使用者带来了不小的困扰,有时携带的跟踪参数还会给分享者带来泄露身份的风险。本文将对微信公众号文章URL的三种类型进行简单的描述,并记录相关的发现。
·soaked.in·
微信公众号文章URL的种类与结构
搜狗微信公众号文章临时链接转为永久链接
搜狗微信公众号文章临时链接转为永久链接
1. 搜狗,微信搜狗可以搜索微信是很早的事情了,我们可以搜索公众号,公众号文章等。也可以显示某公众号最近十条群发消息。消息列表中,所有的链接都形如: 1http://mp.weixin.qq.com/s?timestamp=1483613949&src=3&ver=1&signature=8Fa-25FTMqsFu7Wv3TOhjT6dEcjzgNpkQNe8ysGeozg
·blog.smoker.cc·
搜狗微信公众号文章临时链接转为永久链接
微信图文临时转永久链接_微信公众号临时链接转永久链接_临时链接多久失效_速排小蚂蚁微信编辑器
微信图文临时转永久链接_微信公众号临时链接转永久链接_临时链接多久失效_速排小蚂蚁微信编辑器
速排小蚂蚁编辑器提供各种新媒体助手工具大全,其中包括微信图文视频提取,微信超链接,微信短网址,微信一键关注页面等,利用小工具往往能够达到事半功倍的效果,能大幅度提高微信图文的编辑排版效率!
·xmyeditor.com·
微信图文临时转永久链接_微信公众号临时链接转永久链接_临时链接多久失效_速排小蚂蚁微信编辑器