golang 数据库事务坑
事件 在做访问量比较高的gin web服务的时候,经常发现莫名的服务器有去无回,查看数据库连接sleep占用比较过高,而且time时间过长,确定了是数据库连接没有及时的回收,或者没有释放,所以根据这块查看到下面类似的代码 tx.Exec("") if(a = 1){ //未进行tx提交或者回滚导致 return err } tx.Commit(...阅读全文
事件 在做访问量比较高的gin web服务的时候,经常发现莫名的服务器有去无回,查看数据库连接sleep占用比较过高,而且time时间过长,确定了是数据库连接没有及时的回收,或者没有释放,所以根据这块查看到下面类似的代码 tx.Exec("") if(a = 1){ //未进行tx提交或者回滚导致 return err } tx.Commit(...阅读全文
想必有很多朋友都有使用过虚拟主机建站的经历。不过在建站之前,大家可能都需要选购虚拟主机,而在选择虚拟主机的时候,我们一般都会在主机配置中看到有“流量”的选项。国内虚拟主机一般是几个G,而国外虚拟主机一般是不限制流量。那么,这里的虚拟主机流量是指什么呢? 对于虚拟主机流量来说,与咱们常常说的网站流量可能不大一样。这里的虚拟主机流量,主要是指用户可以从服务器传输进和输出数据总量(类似咱们用手机上网产生流量)。简而言之,就是当用户在访问网站时,产生数据量的总和。 目前,大多虚拟主机商都是按照月为单位来计算的,比如每月3G,每月5G限制这样的月流量。 为了让大家更直观地理解,这里简单的举个例子:假设一个网站每个网页+图片的大小是20K,当月总共累计被访问了4000次网页,那么网站这个月所需...阅读全文
文章计划分为以下几部分: 1.什么是锁,锁的粒度,一般锁的实现,常见锁的类型 并发下的同步和互斥 原子操作、信号量、互斥量、读写信号量、自旋锁 2.golang锁的设计思想与演进 3.golang锁设计的底层基础简介 4.golang锁的代码实现与一些流程图 5.吐槽~ 参考资料: 设计演进http://www.cnblogs.com/niniwzw/archive/2013/06/24/3153955.html 一、什么是并发锁 高并发下,如何保证并行的多线程同时访问一片共享内存时不出现问题,加锁就是最简单的一种解决方案,通过保证上锁的原子操作来保证对资源访问权限的控制,其余的内存屏障等途径留待后续整理。 锁在不同场景下可以有很多分类,比如,分为乐观锁(读写锁)和悲观锁(互斥锁) 分为自旋...阅读全文
实例 package main import( "fmt" "os" "os/signal" "sync" "syscall" "time" ) func worker(stop <-chan bool) { for { select { case <-stop: fmt.Println("exit") return default: fmt.Println("running...") time.Sleep(3) } } } func main() { stop := make(chan bool) var wg sync.WaitGroup for i := 0; i < 3; i++ { wg.Add(1) go func(stop <-chan bool) { defer wg.Don...阅读全文
目录 为什么需要消息队列 1.异步 :一个下单流程,你需要扣积分,扣优惠卷,发短信等,有些耗时又不需要立即处理的事,可以丢到队列里异步处理。 2.削峰 :按平常的流量,服务器刚好可以正常负载。偶尔推出一个优惠活动时,请求量极速上升。由于服务器 Redis,MySQL 承受能力不一样,如果请求全部接收,服务器负载不了会导致宕机。加机器嘛,需要去调整配置,活动结束后用不到了,即麻烦又浪费。这时可以将请求放到队列里,按照服务器的能力去消费。 3.解耦 :一个订单流程,需要扣积分,优惠券,发短信等调用多个接口,出现问题时不好排查。像发短信有很多地方需要用到, 如果哪天修改了短信接口参数,用到的地方都得修改。这时可以将要发送的内容放到队列里,起一个服务去消费, 统一发送短信。 高吞吐、高可用 MQ 对...阅读全文
# version_cache version_cache是一个分步式一致性缓存解决方案。 原理:job 将数据打包成版本到redis,实例将存在redis的版本load到本地内存并计算最新版本的生效时间,使所有实例的缓存在同一时间生效来达到所有实例数据的一致。 实用场景:数据量少、非及时生效数据、高并发强一致的场景。如:配置服务,门店服务等 优点: 1. 轻松实现水平扩展,服务支持千万并发不是梦 2. 数据强一至性,不论启动多少实例,同一时间的数据绝对是一致的(服务器时间一致情况下) 3. 使用简单,实现数据生成接口后就可以像使用缓存一样方便,轻松实现高性能服务 缺点: 1. 数据按版本生效,变更的数据会延迟生效(原则上数据量越小处理越快) 2. 不适合...阅读全文
课程简介:随着云计算和大数据的快速发展,在企业中需要处理和分析的数据量越来越大,随着Flink社区的快速发展,很多公司采用以Flink为核心技术栈来打造统一的大数据处理平台 ,Flink正变得越来越火,此时学习,正当其时。课程中从核心知识的多语言(Java-Scala)讲解到部署实战,循序渐进,助力系统入门Flink企业级应用适合人群大数据领域从业者或想转型大数据开发的工程师符合技术储备要求即可学习技术储备要求了解Linux基础操作,熟悉Java SE或Scala的基本使用熟悉Hadoop基础应用点击进入资源下...阅读全文
计时器及系统负荷均衡 time包中的 time.Ticker结构体,该对象以指定的时间间隔重复向结构体中的通道C发送时间值,通道C对用户只读,该对象可通过工厂函数 time.NewTicker(dur int64) 创建,dur是指定的时间间隔,单位为纳秒(ns)。在使协程周期性执行任务(打印状态日志,输出等)时使用。调用Stop() 使计时器停止,与 select结合如下: time.Tick()函数声明为 Tick(d Duration) <-chan Time,该函数返回的通道不需要关闭,它以 d为周期给返回的通道发送时间,d是纳秒数。可以通过此函数限制处理频率,如果应对的请求不平稳,可以增加一个带缓冲的可读写通道,从chRate中读取处理时钟,在请求暴增时可以快速处理与缓冲数相等的请...阅读全文
文件读写相关的函数在os包中,因此需要先导入os包。 主要有以下几个函数 func Create(name string) (file *File, err error) 直接通过纹面创建文件 func NewFile(fd uintptr, name string) *File func Open(name string) (file *File, err error) 以只读方式打开一个存在的文件,打开就可以读取了。 func OpenFile(name string, flag int, perm FileMode) (file *File, err error) func Pipe() (r *File, w *File, err error) 管道 func (f *File) C...阅读全文
如题,小弟需要一个TCP服务端接受和处理请求,请求内容是解析redis持久化文件和删除现有Redis内存库的记录,每秒访问量在几十到一两百,自己写的程序在新连接到来开了新协程后容错没处理好,例如新协程打开文件出错整个程序也宕了,例如新协程建立redis连接出错整个程序也宕了。 请各位帮忙推荐有没有现成的框架?先谢谢...阅读全文
微信公众号「后端进阶」,专注后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。 一般来说,选择主从备份实现高可用的架构中,都会具备读写分离机制,比如 MySql 读写分离,客户端可以向主从服务器读取数据,但客户写数据只能通过主服务器。 RocketMQ 的读写分离机制又跟上述描写的不太一致,RocketMQ 有属于自己的一套读写分离逻辑,它会判断主服务器的消息堆积量来决定消费者是否向从服务器拉取消息消费。 决定消费者是否向从服务器拉取消息消费的值存在 GetMessageResult 类中: org.apache.rocketmq.store.GetMessageResult: private boolean suggestPullingFromSlave = f...阅读全文
前言 在k8s资源审计和计费这块,容器和虚机有很大区别。相对虚机来讲,容器不容易实现。资源指标收集可以采用heapster,也可以用prometheus。之前文章有介绍过,prometheus的存储的瓶颈和查询较大数据量,容易oom这两个问题。所以选择了heapster。此外,heapster不仅内部实现了很多aggregator和calculator,做了很多聚合层的工作。而采用prometheus,你需要在查询的时候做聚合。heapster支持诸多metrics输出,称为sink。目前支持的sink如下图: 而我比较倾向于clickhouse数据库,关于clickhouse,其实前面的文章介绍过很多了。所以本文主要讲如何为heapster增加clickhouse sink。 代码分析和实...阅读全文
今天在用golang做数据处理的时候出现了点问题,场景是这样的。 服务端定时去请求远端服务器拉取每日数据,数据量不是很大,在百万级左右。 拉取到的数据再经过简单数据校验和处理之后存入数据库。结果在执行这段代码的时候占用了将近3个G的内存。 在优化代码的时候发现了一个问题就是golang在处理大量string类型的时候并没有Interning,而在操作DB时又经常性的出现重复数据,导致内存没必要的浪费。 string interning(字符串驻留)的概念其实在java里会有接触,可以理解为一个常量池,在新建string的时候会查找有没有相同的unicode,有就把指针指过去。wiki原文中也写到了,在java中interning是一个默认的模式。 for example [String.in...阅读全文
译者 | 豌豆花下猫@Python猫声明 :本翻译基于CC BY-NC-SA 4.0【2】授权协议,内容略有改动,转载请保留原文出处,请勿用于商业或非法用途。异步(async)正风靡一时。异步Python、异步Rust、go、node、.NET,任选一个你最爱的语言生态,它都在使用着一些异步。异步这东西有多好,这在很大程度上取决于语言的生态及其运行时间,但总体而言,它有一些不错的好处。它使得这种事情变得非常简单:等待可能需要一些时间才能完成的操作。它是如此简单,以至于创造了无数新的方法来坑人(blow ones foot off)。我想讨论的一种情况是,直到系统出现超载,你才意识到自己踩到了脚的那一种,这就是背压(back pressure)管理的主题。在协议设计中有一个相关术语是流量控制(...阅读全文
一、什么是集合 集合就是不同对象的无序聚集。那么链表和集合有什么关系呢?我们来变个魔术。如下图是各种颜色组成的链表:下面我们一步步把链表变成集合。第一步砍去链接第二步去掉重复第三步放到一个框里摇一摇就成集合了 可以看出集合有这些特点: 无序:链表去掉链接,就是去掉元素间有序状态。 不重复:去掉重复的玫红色。 虽然说集合是一种数学概念,但在实际生活中无处不透露着集合。比如一个班级的学生是一个集合。班级里的男生又是一个集合。 二、集合的结构大卫哥这里为了简化概念的描述,继续用单链表来表示集合,但是在对集合做计算的时候单链表并不合适,数据量大的时候它的弊端就会显现,在讲到后面的数据结构和算法的时候,我们再回头来完善前面讲的数据接口的实现。 三、接口说明及实现 2、Init初始化集合,本质是初始化链...阅读全文
package main import ( "fmt" "sync" ) func main() { var count int var lock sync.Mutex var arthmatic sync.WaitGroup Increment := func() { lock.Lock() defer lock.Unlock() count++ fmt.Printf("Incrementing: %d\n", count) } Decrement := func() { lock.Lock() defer lock.Unlock() count-- fmt.Printf("Decrementing: %d\n", count) } for i := 0; i < 5; i++ { art...阅读全文
对golang之前的特性也了解了一些,但是做为相对较新的语言,以及1.5之前的gc对于大数据量操作实在是太慢了,所以一直在生产环境中没有使用。但是最近用的开源项目原来越多,发现开发环境和生产环境解决依赖实在是个大问题,c++和python的依赖都是非常麻烦的事情。python的问题在于很多库不是原生的,而是基于开源项目的c库开发的,导致c的依赖在python client安装过程中依然需要,而go的包依赖算是比较轻量级的,所以对于版本升级,包的依赖管理,都是很简单的方式。 2016,本来也打算好好学习一个go,先逐步用go来开发离线和脚本任务吧...阅读全文
前言 前期误操作,导致数据库表删除,虽然数据量不多,但是通过binlog恢复比较麻烦,通过备份文件来恢复,备份文件达36个G打开都是问题; 使用备份文件恢复 大文件编辑器,glogg-latest-x86_64-setup通过该文件打开备份文件,虽然过程稍慢,但是能够打开,且正常读取编辑信息,要恢复的数据量不大时采取是没问题的,但是如果表几十万行,操作起来就比较麻烦了; Golang读取备份文件 采用Golang读取,借助编程语言的优势来读取备份,经过测试读取指定备份文件(约36GB)表,大约需要12min,其实主要就是读取遍历备份文件的过程; ** * @Author: ws * @File: main * @Date: 2019/11/16 0016 14:35 * @Remark: *...阅读全文
一、背景 1、现有的业务使用的是mongo,数据量达到将近2亿条数据,高并发查询与修改达到三分之一,一主两从的mongo架构,读写分离 2、现有二、问题在业务高峰期内mongo已经撑不住了,经常造成查询与修改达到几百ms,甚至有连接数用尽的情况, 未完。。...阅读全文
想做一个自己的蜘蛛。保存信息想用KV数据库。 求 推荐一个KV数据库 最好有容错功能,或带日志。 查询性能要好的。支持多线程 存储可以慢一点。 也查了几个(leveldb、boltdb ) 但从没用过,不知道数据量大了后的性能如何。...阅读全文
如题,请知道的大神帮忙回答一下...阅读全文
package main import ( "fmt" "io" "os" ) func Exists(path string) bool { _, err := os.Stat(path) if err != nil { if os.IsExist(err) { return true } return false } return true } func appendToFile(f *os.File, content string) error { // 以只写的模式,打开文件 // 查找文件末尾的偏移量 n, _ := f.Seek(0, os.SEEK_END) // 从末尾的偏移量开始写入内容 _, err := f.WriteAt([]byte(content), n) ret...阅读全文
Go语言作者之一 Robert Griesemer前几天代表Go语言开发团队的提案审查委员会公布了关于否决一项提案的决定。Robert在「内置的Go错误检查函数,"try"」提案下面的回复中发布了这个公告,并表示基于社区压倒性的反应和由此引起的广泛讨论,团队决定提前拒绝此项提案。关于Go 2的错误处理问题,Robert表示团队去年就已阐述了对此的看法,但当时并没引起足够的注意和讨论。所以关于"try"语句的提案可能是解决此问题的一个很好的解决方案,但对于大多数使用者而言,这可能没解决到什么问题。下面举一个try语句的示例。例如如下代码:f, err := os.Open(filename) if err != nil { return …, err // zero values for ot...阅读全文
各们大神 书上ch:=make(chan chan<-string) 这种写法是不是二级信号(类似二级指针...阅读全文
答案是肯定的: 没有指针运算(哈哈, 别着急慢慢往后面看) func main() { a1 := []int{1, 2, 3} p1 := &a1[0] fmt.Println(reflect.TypeOf(p1)) // *int fmt.Println("p1: ", *p1) // 1 fmt.Printf("p1 address:%p\n", p1) // 0xc00009a000 p1 = p1 + 1 } invalid operation: p1 + 1 (mismatched types *int and int) C或者C++转golang同学就高兴了, 再也不用面试的时候去面对下面这道题了(面试C++的时候, 基本每家公司的笔试题上都会有这道题) #include
Golang 学习摘录 学过C,python,或者Java之类语言再来学习golang应该是无压力,看看语法就能写。语法上比较特殊的如下: 声明变量并赋值使用 := a, b := 1, 2 //声明变量a,b,并且赋值1,2 a = 2 //a赋值2 if 不需要圆括号,并且可以执行表达式.for语句类似 if x:=1; x<2 { } String()函数<同java的toString(),对象的字符串形式>中如果有对自身的"%s"操作,将导致无穷递归调用。因为"%s"会调用String(),将对象转化为字符串形式。 type MyString string func (m MyString) String() string { return fmt.Sprintf("MyString...阅读全文
本文介绍golang 如何做基准性能测试。 编写完代码除了跑必要的单元测试外,还需要考虑代码跑起来的性能如何。性能的衡量其实就是程序运行时候进程的内存分配,CPU消耗情况。 golang 语言在提供了功能测试的基础上,提供了丰富的性能测试功能。 SHOW CODE 首先,从一个例子来讲起。 随便写一个简单的快速排序,然后和系统自带的排序做一个性能比较。 如下为简版快排的代码: package benchmark import "sort" func QSort(data []int) { myqsort(data, 0, len(data)-1) } func myqsort(data []int, s, e int) { if s >= e { return } t := data[s] ...阅读全文
文在此。 ————翻译分隔线———— 编译器(7)-扫描 第一部分:介绍 第二部分:编译、转译和解释 第三部分:编译器设计概览 第四部分:语言设计概述 第五部分:Calc 1 语言规格说明书 第六部分:标识符 现在终于可以开始在扫描器上工作了。 词法分析 那么,从哪里开始呢? 这是最难的一部分,对我来说,扫描看起来应该挺简单的,但是很快我就迷失在细节里。有许多种实现扫描器的方法,我只会向你展示其中的一种。这里是 Rob Pike 在一次演讲中的演示文稿,是关于另外一种很酷的方法:在 Go 中的词法扫描。 扫描器的基本原理就是从顶到底、从左到右、直到源代码的结尾进行检索。每次,发现所需要的元素,就报告词法串被找到,标识符会告诉解析器它是什么,以及找到它的位置。 有限状态机 我现在不会真正深入到...阅读全文
最近在学习go语言,基本语法熟悉之后,想看一些开源项目,于是就找到了NSQ,在看NSQ源码的时候,对signal进行了阅读,一下内容仅供参考。 linux信号量知识点 图中可以看到信号来一共是62个,32和33没有 非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。 1到31号都是不可靠信号 go 语言singnal的源码(部分) type handler struct { mask [(numSig + 31) / 32]uint32 } func (h *handler) want(sig int) bool { return (h.mask[sig/32]>>uint(sig&31))&1 != 0 } func (h *handler) set(sig int...阅读全文
场景 当数据两足够大的时候,一页展示不完的时候,我们经常会需要分页的功能。 方案 方案一,数据不是很大 需要排序 s := globalS.Copy() c := s.DB(db).C(collection) defer s.Close() return c.Find(query).Select(selector).Sort(sort).Skip(100).Limit(20).All(result) 这中情况只适用于数据量比较小的时候,当数据量达到一定量,sort会内存益处报错 方案二,数据比较大 不需要排序 s := globalS.Copy() c := s.DB(db).C(collection) defer s.Close() return c.Find(query).Select(...阅读全文
首先取得命令行參數: 用法如下: root@centos:~/code/go/self$ ./sum 1 2 4 package main import "fmt" import "os" import "strconv" func main() int{ arg_num := len(os.Args) fmt.Printf("the num of input is %d\n",arg_num) fmt.Printf("they are :\n") for i := 0 ; i < arg_num ;i++{ fmt.Println(os.Args[i]) } sum := 0 for i := 1 ; i < arg_num; i++{ curr,err := strconv.Atoi(o...阅读全文
unsafe.Pointer其实就是类似C的void *,在golang中是用于各种指针相互转换的桥梁。uintptr是golang的内置类型,是能存储指针的整型,uintptr的底层类型是int,它和unsafe.Pointer可相互转换。uintptr和unsafe.Pointer的区别就是:unsafe.Pointer只是单纯的通用指针类型,用于转换不同类型指针,它不可以参与指针运算;而uintptr是用于指针运算的,GC 不把 uintptr 当指针,也就是说 uintptr 无法持有对象,uintptr类型的目标会被回收。golang的unsafe包很强大,基本上很少会去用它。它可以像C一样去操作内存,但由于golang不支持直接进行指针运算,所以用起来稍显麻烦。 切入正题。利用u...阅读全文
引言 我们在这个系列第一篇文章中提到过,如果需要消息落地而对存储子系统的选择上,从速度上来说 文件系统>分布式KV(持久化)>分布式文件系统>数据库。而NSQ选择了文件系统作为存储子系统。这篇文章将重点介绍nsq 对于文件的操作。 何时写入文件? 在内存的msg chan buffer 已满的时候,会将msg 写入文件,代码如下: func (c *Channel) put(m *Message) error { select { case c.memoryMsgChan <- m: default: b := bufferPoolGet() err := writeMessageToBackend(b, m, c.backend) bufferPoolPut(b) c.ctx.nsqd.S...阅读全文
摘要: 程序日志(AppLog)有什么特点? * 内容最全:程序日志是由程序员给出,在重要的地点、变量数值以及异常都会有记录,可以说线上90%以上Bug都是依靠程序日志输出定位到 * 格式比较随意:代码往往经过不同人开发,每个程序员都有自己爱好的格式,一般非常难进行统一,并且引入的一些第三方库的 程序日志(AppLog)有什么特点? 内容最全:程序日志是由程序员给出,在重要的地点、变量数值以及异常都会有记录,可以说线上90%以上Bug都是依靠程序日志输出定位到 格式比较随意:代码往往经过不同人开发,每个程序员都有自己爱好的格式,一般非常难进行统一,并且引入的一些第三方库的日志风格也不太一样 有一定共性:虽然格式随意,但一般都会有一些共性的地方,例如对Log4J日志而言...阅读全文
unsafe 包简单说明 unsafe,顾名思义,是不安全的,Go定义这个包名也是这个意思,让我们尽可能的不要使用它,如果你使用它,看到了这个名字,也会想到尽可能的不要使用它,或者更小心的使用它。 使用unsafe包的同时也放弃了Go语言保证与未来版本的兼容性的承诺,因为它必然会有意无意中使用很多非公开的实现细节,而这些实现的细节在未来的Go语言中很可能会被改变。 unsafe包被广泛地用于比较低级的包, 例如runtime、os、syscall还有net包等,因为它们需要和操作系统密切配合,但是对于普通的程序一般是不需要使用unsafe包的。 虽然这个包不安全,但是它也有它的优势,那就是可以绕过Go的内存安全机制,直接对内存进行读写,所以有时候因为性能的需要,会冒一些风险使用该包,对内存进...阅读全文
RWMutex:是基于Mutex实现的读写互斥锁,一个goroutine可以持有多个读锁或者一个写锁,同一时刻只能持有读锁或者写锁 数据结构设计: type RWMutex struct { w Mutex // 互斥锁 writerSem uint32 // 写锁信号量 readerSem uint32 // 读锁信号量 readerCount int32 // 读锁计数器 readerWait int32 // 获取写锁时需要等待的读锁释放数量 } // 获取写锁 func (rw *RWMutex) Lock() { if race.Enabled { _ = rw.w.state race.Disable() } // 先获取一把互斥锁 rw.w.Lock() // 减去...阅读全文
是什么? snowflake ID 算法是 twitter 使用的唯一 ID 生成算法,为了满足 Twitter 每秒上万条消息的请求,使每条消息有唯一、有一定顺序的 ID ,且支持分布式生成。 主要解决了高并发时 ID 生成不重复的问题 结构 snowflake ID 的结构是一个 64 bit 的 int 型数据。 如图所示 : 1 bit:不使用,可以是 1 或 0 41 bit:记录时间戳 (当前时间戳减去用户设置的初始时间,毫秒表示),可记录最多 69 年的时间戳数据 10 bit:用来记录分布式节点 ID,一般每台机器一个唯一 ID,也可以多进程每个进程一个唯一 ID,最大可部署 1024 个节点 12 bit:序列号,用来记录不同 ID 同一毫秒时的序列号,最多可生成 4096...阅读全文
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) /* redis操作之 string exists 检查是否存在某个key set key value ex time 键 值 过期模式 时间 eg: 127.0.0.1:6379> set a 444 ex 10 setnx key value 只有key不存在的情况下,将key的值设置为value eg: 127.0.0.1:6379> setnx a 333 (integer) 1 127.0.0.1:6379> get a "333" setex key seconds value 将key的值设置为value 并将key的生存时间设置为seconds秒 ...阅读全文
在Go指南中,最后一节的练习是一个WEB爬虫。刚开始看目录以为真的是要写一个爬虫,直到仔细阅读了代码才发现,只是让利用channel和mutex模拟一个爬虫的代码。 初始状态如下 package main import ( "fmt" ) type Fetcher interface { // Fetch 返回 URL 的 body 内容,并且将在这个页面上找到的 URL 放到一个 slice 中。 Fetch(url string) (body string, urls []string, err error) } // Crawl 使用 fetcher 从某个 URL 开始递归的爬取页面,直到达到最大深度。 func Crawl(url string, depth int, fetche...阅读全文
摘要: 面对繁杂机械重复的测试工作,面对测试精度、难度极高的大数据量校验、单元测试、统计测试覆盖率等工作,面对多线程的并发测试,如何使用软件或工具,帮助减少重复机械工作,将繁杂工作流程化、自动化,提高测试的准确性和测试人员的积极性。 面对繁杂机械重复的测试工作,面对测试精度、难度极高的大数据量校验、单元测试、统计测试覆盖率等工作,面对多线程的并发测试,如何使用软件或工具,帮助减少重复机械工作,将繁杂工作流程化、自动化,提高测试的准确性和测试人员的积极性。 RDC提供了完备的Pipeline, 在整个研发过程开发代码提交后自动触发单元测试, 静态代码扫描。应用发布打包,部署, 自动触发集成测试, 构成了开发和测试共同参与的一套流水线. 在持续交付的实践中, 这样的做法可以有效的加快...阅读全文
天气:小雨 任务清单 验证go-swaager 使用cookie 转发 编写新用户系统的yaml 不同域名使用swagger 进行 cookie传递 习惯养成类:日更800+字 && writingTime >=1h 习惯养成类:单词 30个,复习优先,你的目的是为了记住单词,而不是看到更多的单词。 周目标·完成进度 golang 1K 众病之王---癌症治疗的认知升级(总结2000字+) 梁宁的产品思维30讲(写总结2000字+) 学有所得 烟草的发现: 今天听吴伯凡老师的认知方法论,里面写到烟草产生与美洲人在丛林中,燃烧烟草可以驱蚊,为了使烟草不至于熄灭,会经常吸一吸,不断的反复,就让人的大脑产生了对烟草的依赖性和某种快感,后来即便他们不在丛林中的时候,也会对这种气味产生一种不可遏制的欲...阅读全文
在开发过程中,我们总是在设计不同的数据结构和不同的算法对数据进行组织和存取,有些场合我们可以用硬编码或者代码生成器来生成一组函数按条件返回数据,另外一些场合我们可以把数据存储在slice当中,需要查找时就遍历查找,又或者有的场合我们可以用map存储数据,用key来索引数据。这几种数据存取方式在不同数据量的情况下,性能消耗是怎么样的呢?下面做个对比实验。 我们知道go的map数据量不管大小都能保证固定的读取时间,而slice和硬编码肯定无法应对大数据量,所以这里不做大数据量的实验,只做小数据量的实验。 实验代码(github): package labs06 import "testing" type BigStruct struct { C01 int C02 int C03 int C04...阅读全文
在大部分场景中,工程师可以用cad进行汇报,避免去做PPT,浪费时间,ppt一般都是用一次就丢弃。而工程师对于设计的中间汇报,或三维bim汇报,评审汇报,展示汇报等,都可以直接用cad软件,方法是用视图进行汇报。 视图是个神奇的东西,它支持不同的视图,采用不同的图层搭配,不同的视觉样式(简单渲染),比如线框,隐藏,着色等模式。 cad还提供幻灯片vslide,但是想象一下,每个汇报的页面存成幻灯片,还要整理顺序,也是用后即丢。 而cad自己带的视图播放(视图切换)工具不是很好用。 设计一款专门用于汇报的视图汇报工具,类似ppt那样,按一下就切换到下一个视图,可以用鼠标进行任何操作——缩放啊,量尺寸啊……,不影响下一个视图。 每个视图对应不同的图层,如果在汇报过程中来操作图层的开关,会手忙脚乱...阅读全文
# version_cache version_cache是一个分布式一致性缓存解决方案。 原理:job 将数据打包成版本到redis,实例将存在redis的版本load到本地内存并计算最新版本的生效时间,使所有实例的缓存在同一时间生效来达到所有实例数据的一致。 实用场景:数据量少、非及时生效数据、高并发强一致的场景。如:配置服务,门店服务等 优点: 1. 轻松实现水平扩展,实现千万并发的服务不是梦 2. 数据强一至性,不论启动多少实例,同一时间的数据绝对是一致的(服务器时间一致情况下) 3. 使用简单,实现数据生成接口后就可以像使用缓存一样方便,轻松实现高性能服务 缺点: 1. 数据按版本生效,变更的数据会延迟生效(原则上数据量越小处理越快) 2. 不适...阅读全文
信号量 dispatch_semaphore_create(long value); value: 信号量的起始值。 传递小于零的值将导致返回NULL。 des: 当两个线程需要协调特定事件的完成时,为值传递零是有用的。 传递大于零的值对于管理有限的资源池非常有用,其中池大小等于该值。 returned: 新创建的信号量,或失败时为NULL。 dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); desema: 信号量。 在此参数中传递NULL的结果是未定义的。 timeout: 何时超时(请参阅dispatch_time)。 为方便起见,有DISPATCH_TIME_NOW和DISPATC...阅读全文
golang 的指针 Go语言是个强类型语言。也就是说Go对类型要求严格,不同类型不能进行赋值操作。指针也是具有明确类型的对象,进行严格类型检查 package main import ( "fmt" ) func main() { u := string(32) i := int32(1) fmt.Println(&u, &i) // 打印出地址 p := &i // p 的类型是 *int32 p := &u // &u的类型是 *string,于 p 的类型不同,不能赋值 会报错 p := (*string)(&u) // 这种类型强制转换也是无效的 会报错 fmt.Println(p) } 针对刚刚的问题,我们可以采用 unsafe 标准库来解决。在官方的诠释中,有如下概述: 围绕 ...阅读全文
源自 Plan9 汇编实现。 保存在 .s 文件中,编译器自动编译、链接。本文内容基于 amd64 架构。指令指令参数长度。MOVB: 1-byte MOVW: 2 MOVL: 4 MOVQ: 8 数据移动方向:从左往右。 ADD R1, R2 // R2 += R1 SUB R3, R4 // R4 -= R3 SUB R3, R4, R5 // R5 = R4 - R3 MUL $7, R6 // R6 *= 7 内存访问。 MOV (R1), R2 // R2 = *R1 MOV 8(R1), R2 // R2 = *(8 + R2) MOV 16(R1)(R2*2), R3 // R3 = *(16 + R1 + R2*2) MOV runtime·x(SB), R2 // R2 =...阅读全文
需要导出的sql 表 image.png 代码 需要用到 "github.com/360EntSecGroup-Skylar/excelize" 请自行下载 此代码只限制 A到Z列,只限于一个sheet,数据量太大 建议修改 func SQL2XLSX(autoField []string,fileName string){ f:= excelize.NewFile() //写入自定义字段 for i:=0;i
写在前面 开发 hashset 常用的套路: map[int]int8 map[int]bool 我们一般只用 map 的键来保存数据,值是没有用的。所以来缓存集合数据会造成内存浪费。 空对象 空对象是个神奇的东西。它指的是没有字段的结构类型。 type Q struct{} 它牛逼的地方在于: 可以和普通结构一样操作 var a = []struct{}{struct{}{}} fmt.Println(len(a)) // prints 1 不占用空间 var s struct{} fmt.Println(unsafe.Sizeof(s)) // prints 0 声明两个空对象,它们指向同一个地址 type A struct{} a := A{} b := A{} fmt.Println...阅读全文