概念 建造者模式一种创建型设计模式,它将一个复杂对象的构建过程与其表示分离开来,从而使得同样的构建过程可以创建不同的表示形式。 模式优点: 将对象的构建过程与具体表示分离:建造者模式通过将对象的构建过程与其表示分离开来,使得可以使用相同的构建过程来创建不同的表示形式。这种分离可以提高代……
阅读全文
实现代码 package factory // IRuleConfigParser IRuleConfigParser type IRuleConfigParser interface { Parse(data []byte) } // jsonRuleConfigParser jsonRuleConfigParser type jsonRuleConfigParser struct{} // Parse Parse func (J jsonRuleConfigParser) Parse(data []byte) { panic("implement me") } // yamlRuleConfigParser yamlRuleConfigParser type yamlRuleConfigParser struct{} // Parse Parse func (Y yamlRuleConfigParser) Parse(data []byte) { panic("implement me") } // IRuleConfigParserFactory 工厂方法接口 type IRuleConfigParserFactory interface { CreateParser() IRuleConfigParser } // yamlRuleConfigParserFactory yamlRuleConfigParser 的工厂类 type yamlRuleConfigParserFactory struct{} // CreateParser CreateParser func (y yamlRuleConfigParserFactory) CreateParser() IRuleConfigParser { return yamlRuleConfigParser{} } // jsonRuleConfigParserFactory jsonRuleConfigParser 的工厂类 type jsonRuleConfigParserFactory struct{} // CreateParser CreateParser func (j jsonRuleConfigParserFactory) CreateParser() IRuleConfigParser { return jsonRuleConfigParser{} } // NewIRuleConfigParserFactory 用一个简单工厂封装工厂方法 func NewIRuleConfigParserFactory(t string) IRuleConfigParserFactory { switch t { case "json": return jsonRuleConfigParserFactory{} case "yaml":……
阅读全文
Redis 基础数据结构 String SDS 数据结构,采用空间预分配和惰性空间释放来提升效率,缺点就是耗费内存。 struct sdshdr { int len; //长度 int free; //剩余空间 char buf[]; //字符串数组 } 空间预分配:当一个 SDS 被修改成更长的 buf 时,除了会申请本身需要的内存外,还会额外申请一些空间。 惰性空间:当一个 SDS 被修改成更短的 buf 时,并不会把多余……
阅读全文
代码实现 package prototype import ( "encoding/json" "time" ) // Keyword 搜索关键字 type Keyword struct { word string visit int UpdatedAt *time.Time } // Clone 这里使用序列化与反序列化的方式深拷贝 func (k *Keyword) Clone() *Keyword { var newKeyword Keyword b, _ := json.Marshal(k) json.Unmarshal(b, &newKeyword) return &newKeyword } // Keywords 关键字 map type Keywords map[string]*Keyword // Clone 复制一个新的 keywords // updatedWords: 需要更新的关键词列表,由于从数据库中获取数据常常是数组的方式 func (words Keywords) Clone(updatedWords []*Keyword) Keywords { newKeywords := Keywords{} for k, v := range words { // 这里是浅拷……
阅读全文
Docker 安装 gitlab-ce,第一次登录未提示修改密码 解决方案如下: 进入容器 进入 Gitlab 控制台 修改/确认密码 保存退出 $ docker exec -it gitlab /bin/bash root@66ef80d52eff:/# gitlab-rails console -e production -------------------------------------------------------------------------------- Ruby: ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux] GitLab: 14.6.1 (661d663ab2b) FOSS GitLab Shell: 13.22.1 PostgreSQL: 12.7 -------------------------------------------------------------------------------- Loading production environment (Rails 6.1.4.1) irb(main):001:0> user = User.where(id:1).first => #<User id:1 @root> irb(main):002:0> user.password='123456' => "123456" irb(main):003:0> user.password_confirmation='123456' => "123456" irb(main):004:0> user.save! => true irb(main):005:0> exit root@66ef80d52eff:/# exit exit CI-持续集成 确定 runner 机器上有相应的构建工具(git、no……
阅读全文
LRU 算法和 LFU 算法有什么区别? LFU 内存淘汰算法是 Redis 4.0 之后新增内存淘汰策略,那为什么要新增这个算法?那肯定是为了解决 LRU 算法的问题。 接下来,就看看这两个算法有什么区别?Redis 又是如何实现这两个算法的? 什么是 LRU 算法? LRU 全称是 Least Recently Used 翻译为最近最少使用,会选择淘汰最近最少使用的数据。 传统 LRU 算……
阅读全文
代码实现 package adapter import "fmt" // ICreateServer 创建云主机 type ICreateServer interface { CreateServer(cpu, mem float64) error } // AWSClient aws sdk type AWSClient struct{} // RunInstance 启动实例 func (c *AWSClient) RunInstance(cpu, mem float64) error { fmt.Printf("aws client run success, cpu: %f, mem: %f", cpu, mem) return nil } // AwsClientAdapter 适配器 type AwsClientAdapter struct { Client AWSClient } // CreateServer 启动实例 func (a *AwsClientAdapter) CreateServer(cpu, mem float64) error { a.Client.RunInstance(cpu, mem) return nil } // AliyunClient aliyun sdk type AliyunClient struct{} // CreateServer 启动实例 func (c *AliyunClient) CreateServer(cpu, mem int) error { fmt.Printf("aws client run success, cpu: %d, mem: %d", cpu, mem) return nil } // AliyunClientAdapter 适配器 type AliyunClientAdapter struct { Client AliyunClient……
阅读全文
概念 优点 符合单一职责原则、优秀的扩展性、灵活性 缺点 具体元素对访问者公布细节,违反了迪米特原则 具体元素便跟比较困难 违反了依赖倒置原则,依赖了具体类,没有依赖抽象 应用场景 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作 需要对一个对象结构中的对象进行很多不同的并且不……
阅读全文
概念 外观模式又叫门面模式,是一种常用的封装模式 给一系列具有关联性的子系统的集合提供对外访问的一组接口,调用者不用明确内部具体的业务逻辑,只需要调用这组接口达到目的即可。也就是要求子系统外部与内部不能直接进行通讯,必须通过一个统一的对象进行,而这个统一的对象就是门面。门面模式通过只……
阅读全文
概念 Golang 中没有构造函数,一般使用 NewXXX 或 New() 函数来初始化相关类, 在这个 simple 包中只有 API 接口和 NewGreeting 函数为包外可见,封装了实现细节。 使用场景 工厂类负责创建的对象比较少,客户只知道传入了工厂类的参数,对于始何创建对象(逻辑)不关心。 优点 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实……
阅读全文