装饰器模式
装饰器模式#
装饰器模式可以在不修改原有对象的基础上,通过创建一个包装对象来扩展其功能。这种模式创建了一个装饰类,用来包装原有类,并在保持原类方法签名完整性的前提下提供了额外的功能。
装饰器模式的优点:
扩展性:可以在不修改原有对象代码的情况下,通过装饰类来扩展其功能。
灵活性:可以动态地为对象添加功能。
符合开闭原则:对扩展开放,对修改封闭。
引入#现在我们有这么一个代码:
1234567891011121314151617181920212223func HelloWorld(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("Hello, world!"))}func HowAreYour(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]by ...
函数选项模式
函数选项模式#
函数选项模式是一种在Go语言中常用的设计模式,它允许函数调用者通过一系列可选参数来配置对象。这种模式特别适用于初始化时需要大量配置参数的情况,它避免了长参数列表的问题,并提供了一种更清晰、更灵活的方式来设置对象的状态。
优点:
减少参数列表:避免函数参数过多,提高代码的可读性。
提供默认值:可以为对象提供一组合理的默认值。
灵活性:调用者可以只提供他们关心的配置项。
可扩展性:可以轻松添加新的配置选项,而不影响现有代码。
引入#一般我们初始化函数的时候:
12345678910111213141516171819202122type Server struct { Addr string Port int ReadTimeout time.Duration WriteTimeout time.Duration Timeout time.Duration}func NewServer(addr string, port int, readTimeout, writeTimeout, timeout ti ...
泛型
引言#很久之前就听到过泛型的声音了,但是对于泛型我一直处于没碰到也懒得碰的状态,但是今天偶然看了一下 roadMap ,因此我打算开始碰一下我的泛型了,也就是基础学习一下,感觉没有需求不大会写的样子
泛型#现在有个函数:
1234567891011121314func head(slice []int) (*int, bool) { if len(slice) > 0 { return &slice[0], true } return nil, false}func main(){ slice := int[]{1,2,3,4,5} a , ok := head(slice) if ok { fmt.println(a) }}
以上代码可以看出特别简单
那么如果我们还要再实现一个 func head(slice []string) (*string, bool) { 呢?
这个时候就需要应用泛型了:
12345678910111213141516171819 ...
单调队列
写了一道 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
1234567891011输入:nums = [1,3,-1,-3,5,3,6,7], k = 3输出:[3,3,5,5,6,7]解释:滑动窗口的位置 最大值--------------- -----[1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
12输入:nums = [1], k = 1输出:[1]
单调队列
使用双向队列来实现,同时这 ...
前缀和
碰到了一道题,用到了前缀和,记录一下
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
12输入:nums = [1,1,1], k = 2输出:2
示例 2:
12输入:nums = [1,2,3], k = 3输出:2
我的超级烂写法(AC):
123456789101112131415func subarraySum(nums []int, k int) int { count := 0 for i := 0; i < len(nums); i++ { sum := 0 for j := i; j < len(nums); j++ { sum += nums[j] if sum == k { count++ } } } return count}
前缀树
请务必记住下面这个定义:
我们使用一个叫做“前缀和”的概念。对于数组中的任何位置 j,前缀和 pre[ ...
IdeaVim
感觉用vim挺装逼的,所以特此来学习一下
normal#
方向键
H
J
K
L
左
上
下
右
复制粘贴
YY
P
复制
粘贴
删除
D = 删除
一般会搭配 v K D 来使用,表明删除选中的行
实现块级删除
1“aaaaaaa”
如果需要删除引号中的内容
输入:di", 如果删除完后就进入插入模式: ci"
如果需要删除引号中的内容以及引号
输入:ca" , 如果删除完后就进入插入模式: ca"
如果是 括号,大括号之类的也一样
INSERT#
插入位置选择:
a 在光标后,进入插入模式;
A 在本行结尾,进入插入模式;
i 在光标前,进入插入模式;
I 在本行开头,进入插入模式
新增一行
o 在本行之后新增一行,并进入插入模式;
O 在本行之前新增一行,并进入插入模式;
删除当前字符并进入插入模式
s 删除当前字符,并进入插入模式;
S 删除当前行中的所有文本,并进入插入模式;
JUMP#
跳转最后一行或者第一行
...
sql必知必会
看了SQL必知必会学了点之前不注意的东西
子查询:#
子查询常用于 WHERE 子 句的 IN 操作符中,以及用来填充计算列。
放在 where 里面
12345SELECT cust_id FROM Orders WHERE order_num IN (SELECT order_num FROM OrderItems WHERE prod_id = 'RGAN01');
放在 select from 之间
1234567SELECT cust_name, cust_state, (SELECT COUNT(*) FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name;
例题:
使用子查询,返回购买价格为 10 美元或以上产品的顾客列表。你需 要使用 OrderItems 表查找匹配的订单号(order_num),然后使用 Order 表检索这些匹配订单的顾客 ID(cust_id)
1234567SELECT ...
http标准库
小徐先生的编程世界
引言#本篇文章是学习了小徐先生的编程世界中的http底层原理实现公众号,想要记录学习一下
学习的内容更多是为了更加清晰http底层的流程实现,而不是源码解读
过于底层的源码解读我也读不懂,同时他包装地太过于深入让我难以理解
但是,清晰了http的流程让我受益匪浅
CS架构#http实现的是cs架构,也就是客户端和服务端架构
但是在理解http标准库的时候,我更愿意把cs架构理解为端到端的联系,也就是 端 + conn + 端
的组合,至于客户端和服务端的差别,也就仅仅只是职责的差距,导致的代码上的差距而已
Server#
数据结构
Server
server是服务端最核心的类,下面的两个字段简洁地表示出了Server的功能
从 Addr 匹配路径到具体的 Handler 进行实现功能
如果 Handler 没有显示声明,则会从 DefaultServerMux 中兜底
1234567type Server struct { // server 的地址 Addr string // 路由处理器. Handler Handler / ...
单测架构分析
小徐先生的单测经历 的学习笔记,视频真干货!
引言#1234567891011func LearnGO(){ // step 1 // step 2 http.Post("..","..",nil) // step 3 // step 4 return }
在我们写代码的过程中经常会迷茫怎么写单测,为什么单测难写
单测逻辑的不确定性
第三方依赖的复杂性导致单测结果的不稳定性
下面讲的所有内容都是针对第二点而言,看上面的代码,我们发现当我们使用http.post的时候,我们是不知道我们所要访问的网站是怎么样的,会返回什么值,网站的状态好坏,这些都会影响到我们单测的值,而我们在单测的时候,肯定会希望对功能的前提条件外界因素进行打桩,来判断最终结果是否满足我们的需求
这个时候我们肯定会寻求一些mock来模拟这些外界条件,可看上面这个代码,我们似乎很难通过mock来模拟,因为http.post嵌入在代码之中,具有强耦合性
所以我们需要思考我们应该如何书写代码架构来解决单测问题
面向对象和面向过程#面向对象和面向过程谁都明 ...
gomod
一般来说,正常书写代码是不会遇到所谓的依赖管理的问题
但是,意外就是我改了一下module的名字,然后我就开始了解了一下golang的mod管理
首先我看了一下我本地的目录:
src
这里存放的是源代码的目录,但是真实情况是,我们写真实的项目并不会像java一样永远只是在src下创建新的项目,而是可以在另外的目录下创建项目,因此个人感觉这个项目是没什么用的,特别是使用了gomod的管理模式以后
pkg
用于存放编译后的包文件,随着Go模块(Go Modules)的普及,依赖管理变得更加简单,pkg目录的使用也在逐渐减少,因为Go Modules会直接下载依赖到~/go/pkg/mod目录下。
bin
这个目录用来存放编译后的可执行文件,这个目录不是Go模块系统的一部分,而是项目构建过程中可能产生的输出目录。
SDK
软件开发工具包,这个其实就是包,对这么理解通俗易懂
我们可以在go官网下载sdk或者在goland上下载settings->goroot->➕
然后我们基本上会有这么几个名词
goroot#寻找sdk的路径,goland需要寻找sdk存在在哪里, ...