如何使用 Markdown
是不是写markdown的时候经常想着这么写比较好看但忘了语法是啥,笔者专门把常用语法汇总方便大家当然主要是方便自己查找,还有一些流程图甘特图的高级用法很好用大家可以看看。
标题的书写h1 到 h6 的标题分别是从大到小一个到六个#
h1 标题h2 标题h3 标题h4 标题h5 标题h6 标题几种字体斜体文字
斜体文本
粗体文本
粗体文本
斜体粗体文本
斜体粗体文本
对应语法:
1234567891011*斜体文字*_斜体文本_**粗体文本**__粗体文本__***斜体粗体文本***___斜体粗体文本___
分割线
对应语法:
1234567891011___*************************************___________________
删除线删除这段文本
对应语法:
1~~删除这段文本~~
下划线给这段文本加上下划线
对应语法:
1<u>给这段文本加上下划线</u>
注脚这是一段需要注释的说明[^注释]
对应语法:
1这是一段需要注释的说明[^注释]
无序列表
第一项
第二项
...
go 并发中的锁
go 并发中的锁数据存储模型go 并发中最常见的就是锁,全局锁,读写锁,以及原子操作其实都是为了解决数据竞争的问题,如果不上锁多个 go 程处理同一数据时经常会出现数据错乱,那么你搞清楚为什么会数据错乱了吗?
我一开始的理解是并发时 CPU 被竞争,赋值和读取的操作执行顺序错位导致了数据错乱,其实并不是这么简单。
用户写下的代码,先要编译成汇编代码,也就是各种指令,包括读写内存的指令。CPU 的设计者们,为了榨干 CPU 的性能,无所不用其极,各种手段都用上了,你可能听过不少,像流水线、分支预测等等。其中,为了提高读写内存的效率,会对读写指令进行重新排列,这就是所谓的 内存重排,英文为 MemoryReordering。这一部分说的是 CPU 重排,其实还有编译器重排。编译重拍这里不详解,主要说说内存重排。
我们看一下下面三张图,Thread1 和 Thread2 是并发的两个 goroutine,交叉赋值打印,并发时CPU处理顺序是变化的,但我们假设他是按照(1)(2)(3)(4)的顺序执行的,那么你觉的打印的是什么,Thread1打印的B是0,Thread2打印的A是1。其实并不是 ...
死锁
死锁什么是死锁死锁一般发生在多线程的情况下,因为资源争夺会造成线程之间的相互等待,在没有外力的作用下某些线程会一直等待无法工作。
例如:
线程A在获取资源1的情况下期望获取资源2,线程B在获取资源2的情况下期望获取资源1,这样线程A和B就处于了相互等待的状态。
死锁产生的四个必要条件互斥条件多个线程无法共享同一个资源,线程A持有的资源无法再由线程B获取。
持有并等待条件线程A持有资源1但是又去请求资源2,此时资源2被线程C持有,那么线程A处于持有并等待状态,此时线程B期望获取资源1,B也进入了持有并等待状态。
不可剥夺条件线程A在持有资源1后,资源1不可由线程B抢占。
环路等待条件在发生死锁时必然存在一个线程间的环形等待链。
如:线程A在获取资源1的情况下期望获取资源2,线程B在获取资源2的情况下期望获取资源1,此时形成环路等待。
如何避免死锁其实只要破坏上述条件的一环死锁都不会产生,一般我们使用资源有序分配方法来避免环路等待条件的产生。
上述例子:线程A在获取资源1的情况下期望获取资源2,线程B在获取资源2的情况下期望获取资源1。就不是一个有序使用资源的例子
修改成线程A先尝试获取资 ...
聊聊 MySQL 索引
聊聊 MySQL 索引为什么使用索引不同于redis 和 memorycache 等内存数据库,MySQL 数据库中数据表的数据记录是以存储引擎规定的特定数据格式存储在物理磁盘上的。所以执行 sql 语句最耗时的阶段就是磁盘的 IO 阶段。
有效减少磁盘 IO 阶段的查询时间可使查询效率大幅提升,那么我们如何减少 IO 阶段的查询时间呢?
假设有一张数据表表中的数据条数为N,在不使用索引的情况下查询数据表中的一条记录理论上时间复杂度是O(N),即顺序遍历。那么使用索引是否可以大幅度提升效率?
MySQL中主要的是BTREE索引:
B-Tree 是一种平衡搜索树,它具备以下特性:
平衡性,含有 n 个结点的 B-Tree 的高度为 O(logN) 。它的严格高度可能比红黑树(不严格的平衡二叉树)的高度要小许多,这是因为它的分支因子,也就是表示高度的对数的底数可以非常大。
排序性,结点的排列方式类似于二叉搜索树,可以有序的遍历输出结点。
使用索引查询时每层树高都会进行一次I/O,所以索引大大提高了磁盘IO效率O(logN),如何做到建立有效高效的索引呢?以下是几条建议:
索引建议
在 ...
聊聊go的错误处理
Go语言错误处理方式错误定义方式1. Sentinel errors 在很多包中甚至标准库中都会见到以errors.New() 方法获取一个错误并把它赋值为一个包级别的常量,如io.EOF , 这种特定的错误是API在某些场景下需要返回一个特定的错误interface 即使有更具描述性的错误可以返回。
这样做会使包之间的源代码产生依赖关系,如检查错误是否是io.EOF, 项目必须导入io包。这样做很常见但是如果你的项目中很多包都要导出错误值,那么其他包必须依赖这些错误值才能做特定的错误检查,代码极度耦合。
所以尽量避免出现这样错误处理
2. Error types 把error处理成自定义的Type,这样做可以在error中添加一些上下文信息,以及更多的描述性信息。
12345678910111213type MyError struct{ Msg string File string Line int}func (m *MyError)Error()string{ return fmt.Spr ...
Goroutine 生命周期
Goroutine 生命周期管好goroutine的生命周期每次起一个goroutine 都该问自己两个问题,1.它什么时候该结束,2. 我怎么结束它
一般我们起程序的时候都会在监听应用程序端口的同时,起一个debug的监听比如pprof,这个但是有没有想过,如果go出去的debug监听挂了我们如何知道以及做些什么操作呢。下面这个例子可以在某个监听挂掉后同时结束另一个监听,从而实现go程生命周期的处理。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354// debug 服务func serveDebug(stop <-chan struct{})error{ return serve(":6060",nil,stop)}// app 服务func serveAPP(stop <-chan struct{})error{ return se ...
以太猫
以太猫 Cryptokitties 的ERC-721 token合约以太猫带火了ERC-721 token合约 12月流行的 以太猫 (Cryptokitties), 竟然造成了以太坊的拥堵,现在讲解以太猫带火的ERC-721 token合约是什么?在github 里cryptokitties-bounty程序代码提到,用 ERC-721 token 合约来定义每只以太猫:“CryptoKitties are non-fungible tokens (see ERC #721) that are indivisible and unique.”以太猫是非同质代币,不可分割且独一无二。
02 -ERC-721 token合约简要一种针对非同质代币的标准接口。摘要本标准提出的用于智能合约内非同质代币(non-fungible tokens,以下简称 “NFTs”),操作标准API的实现方法。另外,本标准还提供了用于跟踪和所有权转移的基本功能。动机一个标准的接口允许任何非功能性测试Ethereum由通用的应用程序。 特别是,它将允许非功能性测试跟踪在标准化的钱包和交易所交易。
03 -ER ...
给小白的git说明
#给小白的git说明书
1. 建立代码仓1.1本地新建同步远程
git 其实就是一个远程文件管理工具,使用仓库概念来进行不同功能代码的分割
建立一个代码仓库是使用git的先决条件。
1.2 创建一个代码仓:
1234$ mkdir learngit$ cd learngit$ pwd/Users/michael/learngit
1.3 通过git init 来把这个目录变成git可以管理的仓库
123$ git init// 命令后跟着你要创建仓库的目录地址加.git目录 /xxxx/xxxx/xxxx/.git/Initialized empty Git repository in {xxx/xxxx/xxxx}
你的git仓库就建好了,这是目录下多了.git目录,用来跟踪管理版本库的,不要去试图改动,你可以使用ls -ah来看他
1.4 以上步骤建立了一个本地的代码仓,接下来如何关联远程的代码仓从而把代码推上去呢?
1.4.1 首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库
1.4.2 ...