Go语言中文网 为您找到相关结果 412

redis初探

Redis 的业务应用范围非常广泛,让我们梳理一下,看看 Red is 可以用在哪些地方。1. 记录帖子的点赞数、评论数和点击数( hash )。2 . 记录用户的帖子 ID 列表(排序〉,便于快速显示用户的帖子列表( zset )。3. 记录帖子的标题、摘要、作者和封面信息 , 用于列表页展示( hash )。4 . 记录帖子的点赞用户 ID 列表,评论 ID 列表,用于显示和去重计数( zset )。5 . 缓存近期热帖内容(帖子内窑的空间占用比较大〉,减少数据库压力( hash )。6 . 记录帖子的相关文章 ID ,根据内容推荐相关帖子 Clist )。7 . 如果帖子 ID 是整数自增的,可以使用 Redi s 来分配帖子 ID C 计数器)。8. 收藏集和帖子之间的关系( zs ...阅读全文

博文 2019-08-21 17:32:48 愤怒的老猫占用

Golang源码 container 系列二 list链表

关于ring,可以参考Golang源码 container 系列一 ring环形链表,list也是个链表,但是稍有差别。 参考【Go】笔记五 | container包中的list与ring 一、源码对比 type Ring struct { next, prev *Ring Value interface{} } // Element is an element of a linked list. type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is ...阅读全文

博文 2019-03-18 18:34:44 懒皮

Golang 深入理解 Slice

参考链接: https://github.com/lvgithub/go_blog/blob/master/Books/slice.md 介绍 slice 是对数组的抽象,是对array的扩展,array的长度不可变,在特定场景中不太适用 slice 主要特点是不需要为它的容量担心,可以追加元素,在追加时可能使切片的容量增大 slice 扩容 s := []int{1,2,3,4,5,6} s = append(s, 6) 如果新的slice大小是当前大小2倍以上,则大小增长为新大小 如果当前slice cap 小于1024,按每次2倍增长,否则每次按当前大小1/4增长。直到增长的大小超过或等于新大小 append的实现是在内存中将slice的array值赋值到新申请的array 性能 通过...阅读全文

博文 2019-10-17 16:33:03 aside section ._1OhGeD

leetcode 206 反转链表

题目描述 反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶: 你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 解题思路 详见代码 代码实现 // ListNode Definition for singly-linked list. type ListNode struct { Val int Next *ListNode } func reverseList(head *ListNode) *ListNode { if head == nil || head.Next == nil { return head } var prev *ListNode cur := head for cur != nil...阅读全文

博文 2018-10-23 14:34:45 TomorrowWu

简易跳跃表 - php代码

php代码 /** * 数据链表节点 * / class skipListNode { public $d = null; public $mem = null; public $pre = null; public $level = 0; public $levelNode = array(); } /** * 层链表节点 * / class skipListLevelNode { public $node = null; public $next = null; public $cur_level = 0; public $next_step = 0; } /** * 跳跃表 */ class skipList { private $max_level = 1; private $hea...阅读全文

博文 2019-03-08 10:49:09 lobo

C++服务端面试准备(3)数据结构与算法相关

声明:本文内容纯属博主自己查找和归纳的个人所需的知识点,仅作参考,如有错误,博主强烈希望您指出。如果您是某个知识点的原创博主,如有需要,可联系本人加上链接。本文内容会根据博主所需进行更新,希望大家多多关照。 你所知道的数据结构 数组 (Array)、栈 (Stack)、队列 (Queue)、链表 (Linked List) 树: 堆(heap)、(B-树、B+树、)二叉查找树、AVL树、红黑树、二叉树、哈夫曼树 图 (Graph) 散列表 (Hash) 数组:有序的元素序列,固定大小 栈:是一种运算受限的线性表,先进后出 队列:一种操作受限制的线性表,先进先出 链表:非连续、非顺序的存储结构,逻辑顺序是通过链表中的指针实现的 1.头插法:新插入的数据的指针指向最后的数据 2.尾插法:最后的数...阅读全文

博文 2020-04-08 10:32:46 DX3906

自己动手用golang实现双向链表

双向链表主要有链表跟节点2个结构体type Dnode struct { data interface{} prev *Dnode next *Dnode } type DList struct { head *Dnode tail *Dnode size int }特点:1、除头部、尾部2个节点外,其他任意节点都通过prev / next 分别指向前置后置节点2、头部节点前置节点为空,同理尾部节点后置节点为空主要实现的API如下:1、查询查询链表长度查询任意节点2、添加从开头插入节点从尾部插入节点从任意位置插入节点3、删除删除任意节点4、其他打印链表初始化链表具体实现如下:package main import "fmt" type Dnode struct { data interfac...阅读全文

博文 2019-12-16 02:33:41 筑梦攻城狮

Go 语言内存分配器的实现原理

本文节选自 Go 语言设计与实现的 7.1 节。阅读全书:https://draveness.me/golang/ 程序中的数据和变量都会被分配到程序所在的虚拟内存中,内存空间包含两个重要区域 — 栈区(Stack)和堆区(Heap)。函数调用的参数、返回值以及局部变量大都会被分配到栈上,这部分内存会由编译器进行管理;不同编程语言使用不同的方法管理堆区的内存,C++ 等编程语言会由工程师主动申请和释放内存,Go 以及 Java 等编程语言会由工程师和编译器共同管理,堆中的对象由内存分配器分配并由垃圾收集器回收。 不同的编程语言会选择不同的方式管理内存,本节会介绍 Go 语言内存分配器,详细分析内存分配的过程以及其背后的设计与实现原理。 7.1.1 设计原理 内存管理一般包含三个不同的组件,分...阅读全文

博文 2020-03-08 15:32:47 draveness

【GoLang那点事】链表-删除排序链表中的重复元素,你能想到几种解法?

#### 问题 > 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字 #### 示例1 > 输入: 1->2->3->3->4->4->5 > 输出: 1->2->5 #### 示例二 > 输入: 1->1->1->2->3 > 输出: 2->3 #### 解法一 * 提取问题关键字,有序链表,删除重复,因为是有序的,所以重复的元素一定相邻的,不会出现(2->3-2)这种情况的,最简单的办法,遍历链表,利用数据结构map,key是链表节点的值,value是值在链表中出现的次数,最终次数大于1的就是重复的,等于1的就是不重复的,但是map元素是无序的,所以我们对剩余的元素排序,最后转化为链表。 * 麻烦吗? 我觉得很麻烦,也没人这么实现。看到上面给的算法我就...阅读全文

博文 2019-08-02 09:26:14 SunPengWei

[leetcode in golang]83、删除排序链表中的重复元素

/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func deleteDuplicates(head *ListNode) *ListNode{ if head==nil||head.Next==nil{ return nil } for head!=nil&&head.Next!=nil{ if head.Val==head.Next.Val{ head.Next=head.Next.Next }else{ head=head.Next } return head } return nil /** * Definition for sing...阅读全文

博文 2019-09-25 00:32:50 aside section ._1OhGeD

golang 容器数据类型

container 包实现了三个复杂的数据结构:堆,链表,环(heap、list 和 ring)。当我们需要使用这些数据结构时可以直接使用而不必自己去实现一遍相关算法。 1. 堆 堆使用的数据结构是最小二叉树,即根节点比左边子树和右边子树的所有值都小。 go的堆包只是实现了一个接口,看下它的定义: type Interface interface { sort.Interface Push(x interface{}) // add x as element Len() Pop() interface{} // remove and return element Len() - 1. } 可以看出,这个堆组合了 sort 包的 sort.Interface, 回顾下 sort.Interfa...阅读全文

go-内存机制(3)

go的内存分配 Golang有一套自己的内存管理机制,自主的去完成内存分配、垃圾回收、内存管理等过程,从而避免频繁的向操作系统申请、释放内存,有效的提升go语言的处理性能。 Golang的内存管理是基于tcmalloc模型设计,但又有些差异,局部缓存并不是分配给进程或者线程,而是分配给P(Processor);Golang的GC是stop the world,并不是每个进程单独进行GC;golang语言对span的管理更有效率。 基本概念 1.Span span是golang内存管理的基本单位,每个span管理指定规格(以page为单位)的内存块,内存池分配出不同规格的内存块就是通过span体现出来的,应用程序创建对象就是通过找到对应规格的span来存储的, 下面我们看一下mspan的结构。...阅读全文

博文 2020-03-28 03:32:49 GGBond_8488

groupcache 源码系列三 LRU

关于LRU,可以参考LRU LFU FIFO LRU全称是Least Recently Used,即最近最久未使用的意思。如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。而用什么数据结构来实现LRU算法呢? 可能大多数人都会想到:用一个数组来存储数据,给每一个数据项标记一个访问时间戳,每次插入新数据项的时候,先把数组中存在的数据项的时间戳自增,并将新数据项的时间戳置为0并插入到数组中。每次访问数组中的数据项的时候,将被访问的数据项的时间戳置为0。当数组空间已满时,将时间戳最大的数据项淘汰。这种实现思路很简单,但是有什么缺陷呢?需要不停地维护数据项的访问时间戳,另外,在插入数据、删除数据以及访问数据...阅读全文

博文 2019-03-18 18:34:42 懒皮

leetcode 24. 两两交换链表中的节点

题目描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 说明: 你的算法只能使用常数的额外空间。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 代码实现 // ListNode Definition for singly-linked list. type ListNode struct { Val int Next *ListNode } func swapPairs(head *ListNode) *ListNode { if head == nil || head.Next == nil { return head } var prev *ListNode cur := head ...阅读全文

博文 2018-10-26 14:35:17 TomorrowWu

Go内存模型

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 Go的内存管理话题很大,一边学习,一边记录,持续更新。 提纲挈领和C、C++不同,一般来说,Go程序员无需关心变量是在堆上还是在栈上。 Go语言中内存分配大致有3种模式:Stack、Heap、Fixed Size Segment。 栈栈的概念类似传统Linux下C、C++的概念,即通过栈顶指针移动来分配内存。一般用来存储局部变量、函数参数等。每个Goroutine都有自己的执行栈,互相独立,无需加锁。Goroutine的栈是从Heap中分配的,如果运行中栈需要扩展,会使用连续栈技术进行扩展(通过Heap的操作---- allocate new,copy old to new,free old)。 Goroutin...阅读全文

博文 2019-09-20 11:32:45 链客

阿里Redis最全面试全攻略,读完这个就可以和阿里面试官好好聊聊

什么是Redis及其重要性?Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久化的高性能键值对数据库。Redis的之父是来自意大利的西西里岛的Salvatore Sanfilippo,Github网名antirez,笔者找了作者的一些简要信息并翻译了一下,如图: 从2009年第一个版本起Redis已经走过了10个年头,目前Redis仍然是最流行的key-value型内存数据库的之一。优秀的开源项目离不开大公司的支持,在2013年5月之前,其开发由VMware赞助,而2013年5月至2015年6月期间,其开发由毕威拓赞助,从2015年6月开始,Redis的开发由Redis Labs赞助。 笔者也使用过一些其他的NoSQL,有的支持的value类型非常单一,因此很多操作都必...阅读全文

博文 2020-05-06 19:33:00 Java高级架构

从golang的垃圾回收说起(上篇)

本文来自网易云社区1 垃圾回收中的重要概念1.1 定义In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program. Garbage collection was invented by John McCarthy around 1959 to simplify manual memory manage...阅读全文

博文 2018-08-28 18:34:58 网易云社区

数据结构和算法(Golang实现)(25)排序算法-快速排序

快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊。 注:ACM = Association for Computing Machinery,国际计算机学会,世界性的计算机从业员专业组织,创立于1947年,是世界上第一个科学性及教育性计算机学会。 快速排序是对冒泡排序的一种改进,也属于交换类的排序算法。 一、算法介绍 快速排序通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 步骤如下: 先从数列中取出一个...阅读全文

博文 2020-04-07 16:32:45 陈星星

让我们一起啃算法----合并两个有序链表

合并两个有序链表(Merge-Two-Sorted-Lists) 题干如下: 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4来源:力扣 这个题目和 两数相加 相似,都是考察对链表的操作。其实具体实现方式也差不多啦。 解题思路 根据题干我们知道,给定的两个链表是有序的。假设 l1 指向其中一个链表的头部,l2 指向另一个链表的头部,并初始化 head 和 current,使它们指向一个默认的节点。我们比较 l1 指向节点的值 V(l1) 与 l2 指向节点的值 V(l2) 的大小,如果 V(l1) 的值小于 V(l2) 的值,则使 current.next 指向...阅读全文

博文 2020-04-30 11:32:48 三斤和他的朋友们

golang实现常用集合原理介绍

# golang实现常用集合原理介绍 ## [ArraySort排序数组](https://github.com/chentaihan/container/blob/master/array/arraySort.go) ArraySort使用数组保存数据,新增的时候通过类似二分查找找到插入位置,插入位置后面的数据往后移动一位,插入新元素,查找就是二分查找,删除就是通过二分查找找到对应的元素,之后的元素都向前移动一位。时间复杂度如下: | 功能 | 时间复杂度 | | :--- | :--- | | 新增 | **O**\(n\) | | 删除 | **O**\(n\) | | 查找 | **O**\(logn\) | ## [LinkList单链表](https://github.com/c...阅读全文

博文 2020-04-21 09:32:22 chentaihan

[译]Go: 理解Sync.Pool的设计思想

文:medium.com/a-journey-w… 这篇文章基于Go1.12和1.13,我们来看看这两个版本间sync/pool.go的革命性变化。 Sync包提供了强大的可被重复利用实例池,为了降低垃圾回收的压力。在使用这个包之前,需要将你的应用跑出使用pool之前与之后的benchmark数据,因为在一些情况下使用如果你不清楚pool内部原理的话,反而会让应用的性能下降。 pool的局限性 我们先来看看一些基础的例子,来看看他在一个相当简单情况下(分配1K内存)是如何工作的: type Small struct { a int } var pool = sync.Pool{ New: func() interface{} { return new(Small) }, } //go:noi...阅读全文

博文 2019-12-03 19:34:26 野生程序元

go实现双向链表并使用iterater遍历

package main import ( "strings" "strconv" "fmt" ) /** 双向链表 */ type DoubleLinkedList struct { //链表头节点 head *Node //链表尾部节点 tail *Node //长度 size int } /** 遍历器接口 */ type Interater interface{ /** 是否还有下一个 */ hasNext() bool /** 下一个节点 */ next() *Node } /** 遍历器 */ type ListInterater struct { list *DoubleLinkedList currentNode *Node } /** 遍历器是否还有下一个节点 */ fun...阅读全文

博文 2019-12-17 11:33:14 wx5df0ffef01962

Golang Map 实现(三)map 的数据访问

本文在golang map 数据结构的基础上,学习map 数据是如何访问的。 map 创建示例 在golang 中,访问 map 的方式有两种,例子如下: val := example1Map[key1] val, ok := example1Map[key1] 第一种方式不判断是否存在key值,直接返回val (可能是空值)第二种方式会返回一个bool 值,判断是否存在key 键值。(是不是和redis 的空值判断很类似) 那访问map 时,底层做了什么,我们一起来探究 对于不同的访问方式,会使用不同的方法,下面是内部提供的几种方法,我们一起来学习: // 迭代器中使用 func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (un...阅读全文

博文 2020-04-30 10:32:41 搬砖程序员带你飞

想提高用户访问的响应速度和成功率还不赶快学习CDN

课程介绍 CDN可以将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。 产品详情:https://www.aliyun.com/product/cdn 课时列表 • 课时1:CDN开通和计费 • 课时2:CDN添加加速域名 • 课时3:CDN加速域名的管理 • 课时4:CDN缓存设置 • 课时5:CDN防盗链设置 开始学习:http://click.aliyun.com/m/27844/ ...阅读全文

兄弟连区块链技术培训分享Go语言之源码解读之map

互联网二十多年,已到十字路口。区块链出现前的互联网被称为古典互联网,而应用区块链技术的互联网才进入了后互联网时代。作为一项新兴的技术,区块链无疑正处于风口浪尖之上,其发展前景于普通大众而言也终将是利好。但目前由于区块链技术处于发展早期阶段,存在技术成熟度、落地应用场景有限等问题,兄弟连教育建议用户在选择专业Go语言+区块链培训机构前应进行仔细考量与辨别。在iterate整个map的时候,使用delete是安全的。这跟c++是不一样的,c++在delete的时候,会导致整棵树发生变化,所以不能在迭代的时候删除元素。那为什么golang的map是安全的呢,从源码来看,golang的map使用了桶的概念,元素是被hash到桶存储,每个桶预设是存储八个kv,而且在头部有一个uint8 tophash...阅读全文

博文 2018-08-27 16:35:56 兄弟连区块链培训

图解Go语言内存分配

目录 基础概念 内存管理单元 内存管理组件 mcache mcentral mheap 内存分配流程 总结 参考资料 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。 Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的TCMalloc算法,全称Thread-Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。 基础概...阅读全文

博文 2019-03-13 10:51:27 qcrao-2018

golang中的panic,recover执行过程?

上篇文章golang中defer的执行过程是怎样的?介绍了一下defer的执行过程,本篇是上一篇的引申,主要介绍panic、recover的底层分析,如果没有读过上一篇文章,可以先去读一下在看这篇。 总共分3部分讲解: 1 panic 2 defer panic 3 defer panic recover 环境:go version go1.12.5 linux/amd64 1 panic golang中的异常总共分为4中: 编译器捕获的 直接手动panic golang捕获的 系统捕获的 编译器捕获的 1/0 我们知道被除数是不能等于0的,所以这种错误是编译不过去的,会提示: ./main.go:7:8: division by zero 直接手动panic 示例代码: package m...阅读全文

博文 2019-07-25 15:12:09 XITEHIP

深入理解go的slice和到底什么时候该用slice

前言 用过go语言的亲们都知道,slice(中文翻译为切片)在编程中经常用到,它代表变长的序列,序列中每个元素都有相同的类型,类似一个动态数组,利用append可以实现动态增长,利用slice的特性可以很容易的切割slice,它们是怎么实现这些特性的呢?现在我们来探究一下这些特性的本质是什么。 先了解一下slice的特性 定义一个slice: s := []int{1,2,3,4,5} fmt.Println(s) // [1 2 3 4 5] 一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。 slice的扩容: s := []int{1,2,3,4,5} s = append(s, 6) fmt.Println(s) /...阅读全文

博文 2017-02-09 08:25:49 sheepbao

深入理解Go-runtime.SetFinalizer原理剖析

finalizer是与对象关联的一个函数,通过runtime.SetFinalizer 来设置,它在对象被GC的时候,这个finalizer会被调用,以完成对象生命中最后一程。由于finalizer的存在,导致了对象在三色标记中,不可能被标为白色对象,也就是垃圾,所以,这个对象的生命也会得以延续一个GC周期。正如defer一样,我们也可以通过 Finalizer 完成一些类似于资源释放的操作 1. 结构概览 1.1. heap type mspan struct { // 当前span上所有对象的special串成链表 // special中有个offset,就是数据对象在span上的offset,通过offset,将数据对象和special关联起来 specials *special //...阅读全文

博文 2019-09-09 01:34:30 tyloafer

golang双端链表list remove nil问题

我这个场景是做优先级的任务派发的,因为有几十个厂商,每个厂商还有不同的业务,每个业务也有10个优先级,这样算来整个任务缓冲池里最少又要几百个队列。 这里没用channel,因为channel通道太多,没法很好的做输出。 优先级肯定是有调度器主动去pop数据,这里选择了使用container/list提供的双端列表。 我的服务主要体现在Push, Pop 类似的操作上,container/list都可以O(1)的时间复杂度。 该文章后续会有更新, 原文地址, http://xiaorui.cc/?p=4809 话题说 list 有个 remove的问题… 你遍历整个链表会发现只会删除第一个,当再次迭代的时候,e.Next() == nil 空值,跳出循环。。。 for e := l.Front...阅读全文

博文 2019-06-03 19:55:02 rfyiamcool

兄弟连区块链教程eth源码解析区块数据结构

在区块链中,区块是存储有价值信息的块。这是任何一种加密货币的本质。除此之外,区块还包含一些技术信息,比如它的版本、当前时间戳和前一区块的散列值(哈希值)Block(区块)是Ethereum的核心数据结构之一 所有账户的相关活动,以交易(Transaction)的格式存储,每个Block有一个交易对象的列表 每个交易的执行结果,由一个Receipt对象与其包含的一组Log对象记录 所有交易执行完后生成的Receipt列表,存储在Block中(经过压缩加密) 不同Block之间,通过前向指针ParentHash一个一个串联起来成为一个单向链表,BlockChain 结构体管理着这个链表 Block结构体基本可分为Header和Body两个部分 Block: 表示以太坊区块链中的一个完整块type...阅读全文

博文 2018-10-16 17:34:39 兄弟连区块链培训

双向链表与LRU缓存淘汰机制

双向链表 双向链表作为在日常开发中最常用的数据结构之一,应用十分广泛,在诸多著名开源项目中如redis的list结构, groupcache的lru中均是核心实现。在设计此类数据集合的时候,外面看上去链表似乎与数组相似,但链表是一个非连续性内存的存储方案,提供了高效的节点重排能力与顺序访问方式,对比与操作数组,只需知道给定项的地址和位置的链接就能在内存中找到它,并且可以通过增减节点的方式来灵活的调整长度。反而数组,比如插入一个新的元素,那么该位置后的元素都要往后移动一位。 标准的双向链表实现 redis 中的双向链表golang 中的双向链表 其结构如图 在双向链表中头结点的前指针为空,尾节点的后指针为空, 对头尾的操作十分简单, 插入头节点只需要将新节点的next设置为当前链表的头节点, ...阅读全文

博文 2019-01-08 13:34:44 薛薛薛

【golang】HashMap原理和实现

理 我们都知道怎么使用goLang中的map来存储键值对类型的数据,但是它的内部实现是怎么样的? 其实map是一种HashMap,表面上看它只有键值对结构,实际上在存储键值对的过程中涉及到了数组和链表。HashMap之所以高效,是因为其结合了顺序存储(数组)和链式存储(链表)两种存储结构。数组是HashMap的主干,在数组下有有一个类型为链表的元素。 这是一个简单的HashMap的结构图: image 当我们存储一个键值对时,HashMap会首先通过一个哈希函数将key转换为数组下标,真正的key-value是存储在该数组对应的链表里。 HashMap的数组往往是有限的,那当要存储的键值对很多数组不够或者两个键值对哈希运算后的值相同时,不就会有不同的键值对存储在同一个数组下吗?是的,这个就叫...阅读全文

博文 2019-04-10 23:34:42 柳浪闻笛

[译]Go:内存管理与内存分配

文:medium.com/a-journey-w… 这篇文章是基于Go 1.13的。 当内存不再被使用时,标准库就会自动执行Go内存管理,即从内存分配到Go自己的集合中(from allocation of the memory to its collection)。 虽然开发人员不用去和这些打交道,但是Go的内存管理做了很多优化以及有很多有趣的概念,所以也值得我们去探讨与学习。 堆上的分配 Allocation on the heap 内存管理是在高并发环境以及集成了垃圾回收功能上所设计的。我们来演示一些简单的例子: package main type smallStruct struct { a, b int64 c, d float64 } func main() { smallAll...阅读全文

博文 2019-11-26 18:34:24 野生程序元

GoLang-内存管理

一、tcmalloc介绍<参考资源> go的内存管理和tcmalloc(thread-caching malloc)很像,先看一下tcmalloc的实现。 1.1 简介 tcmalloc是google推出的一种内存分配器,常见的内存分配器还有glibc的ptmalloc和google的jemalloc。相比于ptmalloc,tcmalloc性能更好,特别适用于高并发场景。 1.2 tcmalloc算法策略 tcmalloc分配的内存主要来自两个地方:全局缓存堆和进程的私有缓存。对于一些小容量的内存申请使用进程的私有缓存,私有缓存不足的时候可以再从全局缓存申请一部分作为私有缓存。对于大容量的内存申请则需要从全局缓存中进行申请。而大小容量的边界就是32k。缓存的组织方式是一个单链表数组,数组的...阅读全文

博文 2020-02-03 03:32:41 帘外五更风

Go学习笔记-Channel最佳实践之基本规则【译】

channel[通道]是golang的一种重要特性,正是因为channel的存在才使得golang不同于其它语言。channel使得并发编程变得简单容易有趣。 channel的概念和语法 一个channel可以理解为一个先进先出的消息队列。channel用来在协程[goroutine]之间传递数据,准确的说,是用来传递数据的所有权。一个设计良好的程序应该确保同一时刻channel里面的数据只会被同一个协程拥有,这样就可以避免并发带来的数据不安全问题[data races]。 channel的类型 像数组、切片和字典一样,channel类型是一种组合类型,每一种channel类型都对应着一种简单的数据类型。比如元素的类型是string,那么对应的channel类型就是chan string,进...阅读全文

博文 2019-05-31 13:34:42 赵客缦胡缨v吴钩霜雪明

leetcode 25. k个一组翻转链表

题目描述 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。 示例: 给定这个链表:1->2->3->4->5 当 k = 2 时,应当返回: 2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5 说明: 你的算法只能使用常数的额外空间。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 解题思路 1. 取链表的前K个节点,如果够K个节点,就截断后进行反转,不够K个节点,说明处理完了,return 2. 反转完前K个节点后,使用递归,处理后面的链表 代码实现 // ListNode Definition for singl...阅读全文

博文 2018-10-27 09:34:41 TomorrowWu

golang中container/ring包

ring包实现了环形双向链表的功能。 type Ring func New(n int) *Ring func (r *Ring) Do(f func(interface{})) func (r *Ring) Len() int func (r *Ring) Link(s *Ring) *Ring func (r *Ring) Move(n int) *Ring func (r *Ring) Next() *Ring func (r *Ring) Prev() *Ring func (r *Ring) Unlink(n int) *Ring 结构体: type Ring // 环形双向链表 type Ring struct { next, prev *Ring Value interface...阅读全文

博文 2018-12-08 13:34:43 laijh

Go实现双向链表

本文介绍什么是链表,常见的链表有哪些,然后介绍链表这种数据结构会在哪些地方可以用到,以及 Redis 队列是底层的实现,通过一个小实例来演示 Redis 队列有哪些功能,最后通过 Go 实现一个双向链表。 目录 1、链表 1.1 说明 1.2 单向链表 1.3 循环链表 1.4 双向链表 2、redis队列 2.1 说明 2.2 应用场景 2.3 演示 3、Go双向链表 3.1 说明 3.2 实现 4、总结 5、参考文献 1、链表 1.1 说明 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多...阅读全文

博文 2019-09-20 10:02:43 link1st

关于切片

运行结果的第一行表示的是什么?还有,通过append函数赋值后,slice[0][0]和slice[0][1]的地址发生了改变,这样我对slice进行搜索时间不会变慢吗?slice是如何知道silce[1][0]的位置的,还是说slice其实是一个链表? ![TIM图片20171024233230.png](https://static.studygolang.com/171024/fa6e75d6ab3f01c617ea106dae17779b.png...阅读全文

兄弟连区块链培训教程分享Go语言golang单链表实现

目前而言区块链是一门新兴前沿行业,但也是一门综合复杂性强的学科,学习区块链需要有一定的学习能力与知识基础。然而很多线下培训机构却只顾收取高额报名费用,将用户的实际情况置若罔闻,不设报名门槛,不对报名人员进行甄别筛选,实则是一种不负责任的态度。 兄弟连教育Go全栈与区块链培训课程已从多层面颠覆传统培训机构运营思维,区块链课程的开设在一定程度上加大了大众对这一专业领域的认知,其构建起的区块链世界也必将在未来为我们呈现更加高效的生活方式。package main//链表实现import ( "fmt" "os")//定义错误常量const ( ERROR = -1000000001)//定义元素类型type Element int64//定义节点type LinkNode struct {Data...阅读全文

博文 2018-08-31 15:37:29 兄弟连区块链培训

Golang 内存管理源码剖析

Golang 的内存管理基于 tcmalloc,可以说起点挺高的。但是 Golang 在实现的时候还做了很多优化,我们下面通过源码来看一下 Golang 的内存管理实现。下面的源码分析基于 go1.8rc3。 1.tcmalloc 介绍 关于 tcmalloc 可以参考这篇文章 tcmalloc 介绍,原始论文可以参考 TCMalloc : Thread-Caching Malloc。 2. Golang 内存管理 0. 准备知识 这里先简单介绍一下 Golang 运行调度。在 Golang 里面有三个基本的概念:G, M, P。 G: Goroutine 执行的上下文环境。 M: 操作系统线程。 P: Processer。进程调度的关键,调度器,也可以认为约等于 CPU。 一个 Gorou...阅读全文

博文 2018-06-04 11:33:05 万建宁

深入理解 Go defer

深入理解 Go defer 在上一章节 《深入理解 Go panic and recover》 中,我们发现了 defer 与其关联性极大,还是觉得非常有必要深入一下。希望通过本章节大家可以对 defer 关键字有一个深刻的理解,那么我们开始吧。你先等等,请排好队,我们这儿采取后进先出 LIFO 的出站方式... 特性 我们简单的过一下 defer 关键字的基础使用,让大家先有一个基础的认知 一、延迟调用 func main() { defer log.Println("EDDYCJY.") log.Println("end.") } 输出结果: $ go run main.go 2019/05/19 21:15:02 end. 2019/05/19 21:15:02 EDDYCJY. 二、...阅读全文

博文 2019-06-16 16:59:49 EDDYCJY

兄弟连区块链教程eth源码解析区块数据结构

兄弟连区块链教程eth源码解析区块数据结构,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。在区块链中,区块是存储有价值信息的块。这是任何一种加密货币的本质。除此之外,区块还包含一些技术信息,比如它的版本、当前时间戳和前一区块的散列值(哈希值)Block(区块)是Ethereum的核心数据结构之一* 所有账户的相关活动,以交易(Transaction)的格式存储,每个Block有一个交易对象的列表* 每个交易的执行结果,由一个Receipt对象与其包含的一组Log对象记录* 所有交易执行完后生成的Receipt列表,存储在Block中(经过压缩加密)* 不同Bl...阅读全文

博文 2018-10-16 18:34:41 兄弟连区块链培训

Go cond 源码学习

概述 cond是go语言sync提供的条件变量,通过cond可以让一系列的goroutine在触发某个条件时才被唤醒。每一个cond结构体都包含一个锁L。cond提供了三个方法: Signal:调用Signal之后可以唤醒单个goroutine。 Broadcast:唤醒等待队列中所有的goroutine。 Wait:会把当前goroutine放入到队列中等待获取通知,调用此方法必须先Lock,不然方法里会调用Unlock()报错。 简单使用 创建40个goroutine都wait阻塞住。调用Signal则唤醒第一个goroutine。调用Broadcast则唤醒所有等待的goroutine。 package main import ( "fmt" "sync" "time" ) var l...阅读全文

博文 2019-08-02 18:02:48 大二小的宝

面试:从尾到头打印链表

题目:从尾到头打印链表 要求:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 题解1:递归法 因为是从尾到头返回每一个节点的值,所以很容易想到如果从最后的节点将值放入数组中,然后再往前逐步将数据放入数组,最后回到头节点返回即可,可以想到递归就能轻松做到,只要注意递归函数的结束条件即可。 /** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func reversePrint(head *ListNode) []int...阅读全文

博文 2020-02-28 16:32:40 若鱼治水

Go基础系列:struct和嵌套struct

struct struct定义结构,结构由字段(field)组成,每个field都有所属数据类型,在一个struct中,每个字段名都必须唯一。 说白了就是拿来存储数据的,只不过可自定义化的程度很高,用法很灵活,Go中不少功能依赖于结构,就这样一个角色。 Go中不支持面向对象,面向对象中描述事物的类的重担由struct来挑。比如面向对象中的继承,可以使用组合(composite)来实现:struct中嵌套一个(或多个)类型。面向对象中父类与子类、类与对象的关系是is a的关系,例如Horse is a Animal,Go中的组合则是外部struct与内部struct的关系、struct实例与struct的关系,它们是has a的关系。Go中通过struct的composite,可以"模仿"很多...阅读全文

博文 2018-11-23 09:11:24 f-ck-need-u

leetcode 25. k个一组翻转链表

题目描述 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。 示例: 给定这个链表:1->2->3->4->5 当 k = 2 时,应当返回: 2->1->4->3->5 当 k = 3 时,应当返回: 3->2->1->4->5 说明: 你的算法只能使用常数的额外空间。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 解题思路 1. 取链表的前K个节点,如果够K个节点,就截断后进行反转,不够K个节点,说明处理完了,return 2. 反转完前K个节点后,使用递归,处理后面的链表 代码实现 // ListNode Definition for singl...阅读全文

博文 2018-10-27 09:34:38 tomorrowwu

golang优化日记

内存优化 1.1小对象合并成结构体一次分配,减少内存分配次数 c++里面,小对象在对上频繁申请,会出现内存碎片,导致大的对象时无法申请到连续的内存空间,一般建议使用内存池; go runtime底层使用内存池,但每个span大小为4k,同时维护一个cache;cache分为0到n的list数组,每个单元挂载一个链表,链表上每个节点的内存块大小是相等的;不同链表的大小块是不等的,当cache不够时再向spanalloc申请; 例如:小对象合并为结构体一次分配 for k,v := range m{ k,v := k,v go func(){ //using k,v }() } 替换为 for k,v := range m{ x := struct {k , v string} {k, v} g...阅读全文

博文 2020-05-06 11:34:27 安静的皮蛋

Go map原理剖析

在使用map的过程中,有两个问题是经常会遇到的:读写冲突和遍历无序性。为什么会这样呢,底层是怎么实现的呢?带着这两个问题,我简单的了解了一下map的增删改查及遍历的实现。 结构 hmap type hmap struct { // Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go. // Make sure this stays in sync with the compiler's definition. count int // 有效数据的长度# live cells == size of map. Must be first (used by len() builtin)...阅读全文

博文 2019-10-08 18:32:54 tyloafer