怎么写Makefile

基本语法 targets: prerequisites command command command 变量 声明变量 NAME=ClashV BINDIR=bin 使用$()来引用变量 PLATFORM_LIST = \ darwin-amd64 \ darwin-amd64-compatible \ all-arch: $(PLATFORM_LIST) 自动变量 $@: 表示target darwin-amd64: GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ 条件判断 ifeq ($(BRANCH),Alpha) VERSION=alpha-$(shell git rev-parse --short HEAD) else ifeq ($(BRANCH),Beta) VERSION=beta-$(shell git rev-parse --short HEAD) else ifeq ($(BRANCH),) VERSION=$(shell git describe --tags) else VERSION=$(shell git rev-parse --short HEAD) endif 函数 shell BRANCH=$(shell git branch --show-current) 相关链接 Makefile Tutorial

2024-07-01 · 1 分钟

开源项目推荐【持续更新】

react-rough-fiber: 渲染手绘风 SVG 的 React 渲染器,可以轻松把 SVG 转换成手绘风图片

2024-07-01 · 1 分钟

工具推荐【持续更新】

happyhues: 网站颜色搭配神器 cobalt: 视频下载 indiehackers: 独立开发导航站 openalternative: 查找平替软件

2024-07-01 · 1 分钟

缓存驱逐策略

Least Recently Used(LRU): 删除最旧的数据。基本假设是最近访问的数据可能很快会再次被需要。 Most Recently Used(MRU): 与LRU相反,删除最新的数据。常用于流处理或批处理平台,这些平台一旦使用数据就不太可能再次需要。 Least Frequently Used(LFU): 删除使用最少的数据。虽然它是一种比 LRU 更准确的方法,但它需要一种机制来记录数据访问的频率,这增加了复杂性。它通常与 LRU 等策略配合使用,以降低缓存过时数据的风险。 Time-To-Live (TTL):数据在预设的时间段有效。常用在会话数据中。 Two-tiered caching两层缓存提供了一种更复杂的方法。可以在速度和成本之间取得平衡。在此设计中,数据被分为快速、昂贵的层(用于流行数据)和较慢、经济的层(用于较少访问的数据)。 上述五种策略是最流行的缓存方法。还有其他一些策略: 先进先出(FIFO):最旧的数据首先被删除。 随机替换(RR):随机选择要删除的数据。 自适应替换缓存 (ARC):使用自调整算法跟踪新近度和频率来确定首先删除哪些数据。

2024-06-26 · 1 分钟

atomic.Value存储interface的问题

先看这段代码 import ( "io" "net/http" "sync/atomic" ) func main() { var v atomic.Value var err error err = &http.ProtocolError{} v.Store(err) err = io.EOF v.Store(err) } 运行后会报错 panic: sync/atomic: store of inconsistently typed value into Value。 原因是atomic.Value.Store需要类型是一致的。在这里err类型发生了变化,虽然他们都是error接口类型。具体参考Issues#22550 怎么解决?包装一层就能运行了。 type tValue[T any] struct { value T } func main() { var v atomic.Value var err error err = &http.ProtocolError{} v.Store(tValue[error]{err}) err = io.EOF v.Store(tValue[error]{err}) }

2024-06-26 · 1 分钟

MySQL存储与索引原理分享

很早之前做的一次分享,下面是PPT内容 ...

2021-07-30 · 1 分钟

关于Golang GC问题的思考

由于GC复杂,我也没有仔细研究过GC的源码,所以只能站在巨人的肩上学习,如果想了解GC的具体实现请移步文末的参考资料。本文只是记录我在阅读完大佬文章中自己的一些问题与思考,可能有一些不对的地方。欢迎大家一起讨论。 ...

2021-07-27 · 1 分钟

Timer源码阅读分享

这是在小团队里面的一次分享,以下是PPT内容

2021-07-10 · 1 分钟

Timer源码阅读

根据6.3 计时器中的描述,Golang Timer的设计经历了如下阶段: Go 1.9 版本之前,所有的计时器由全局唯一的四叉堆维护; Go 1.10 ~ 1.13,全局使用 64 个四叉堆维护全部的计时器,每个处理器(P)创建的计时器会由对应的四叉堆维护; Go 1.14 版本之后,每个处理器单独管理计时器并通过网络轮询器触发; Go 1.9 版本之前由于使用全局的四叉堆,在多核情况下会出现锁竞争导致性能问题 Go 1.10 ~ 1.13使用了64个四叉堆,有每个P来维护对应的四叉堆,相当于将锁的粒度减小,但是当timer在未到时间和到时间需要执行进行切换的时候,会发生P和M的绑定和解绑,尤其是当timer触发时间间隔比较小的情况下,会导致CPU占用过高,M/P切换的开销增加(TODO 为什么会发生P和M的绑定和解绑) Go 1.14 版本后每个P管理计时器四叉堆,由网络轮询器和调度器进行触发 我使用的是Go 1.16的版本进行分析 ...

2021-04-22 · 18 分钟

Java线程池

线程池是什么? 线程池用于多线程处理中,它可以根据系统的情况,可以有效控制线程执行的数量,优化运行效果。线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕,再从队列中取出任务来执行。 ...

2020-12-16 · 13 分钟