Effective Go-4

Interfaces and other types Interface Sequence这个例子,调用sort package中的方法,对于集合要实现sort的接口:Len(), Less(i,j int) bool 和 Swap(i,j int)。Sequence同时通过String()对集合内容进行格式化。 package sequence_test import ( "fmt" "sort" "testing" ) type Sequence []int func (s Sequence) Len() int { return len(s) } func (s Sequence) Less(i, j int) bool { return s[i] < s[j] } func (s Sequence) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s Sequence) Copy() Sequence { copy := make(Sequence, 0, len(s)) return append(copy, s...) } func (s Sequence) String() string { s = s.Copy() sort.Sort(s) str := "[" for i, elem := range s { if i > 0 { str += " " } str += fmt.Sprint(elem) } return str + "]" } func (s Sequence) Stringsprint() string { s = s.Copy() sort.Sort(s) return fmt.Sprint(s) } func (s Sequence) StringIntSlice() string { s = s.Copy() sort.IntSlice(s).Sort() return fmt.Sprint(s) } func TestSequence(t *testing.T) { var s Sequence = Sequence{100, 12, 83, 34, 59, 86} t.Logf("%#v", s) t.Log(s) t.Log(s.String()) t.Log(s.Stringsprint()) t.Log(s.StringIntSlice()) } === RUN TestSequence f:\GO\go_test\sequence\sequence_test.go:54: sequence_test.Sequence{100, 12, 83, 34, 59, 86} f:\GO\go_test\sequence\sequence_test.go:55: [12 34 59 83 86 100] f:\GO\go_test\sequence\sequence_test.go:56: [12 34 59 83 86 100] f:\GO\go_test\sequence\sequence_test.go:57: [12 34 59 83 86 100] f:\GO\go_test\sequence\sequence_test.go:58: [12 34 59 83 86 100] --- PASS: TestSequence (0.00s) PASS ok loop/sequence 1.996s 类型转换 String()接口通过 “for i, elem := range”方式实现,也可以像Stringsprint直接调用fmt.Sprint处理实现。 ...

2021-04-19 · 4 min · 781 words

Effective Go-3

Data 分配 通过new和make分配空间: new分配空间,返回指针 make可以进行生成slices,maps,channels,返回类型 package data_test import "testing" func TestCreateslices(t *testing.T) { s := make([]string, 3) s[0] = "c" s[1] = "a" s[2] = "o" t.Log(s) } func TestCreatemap(t *testing.T) { m := make(map[string]int) m["k1"] = 1 m["k2"] = 2 t.Log(m) } func TestCreatechannel(t *testing.T) { messages := make(chan string) go func() { messages <- "ping" }() msg := <-messages t.Log(msg) } 数组(Arrays)和切片(Slices) go中更推荐使用切片而不是数组。 数组长度固定 切片可以动态调整容量(cap) package data_test import "testing" func TestCreatearray(t *testing.T) { a := [...]int{1, 2, 3, 4} t.Log(a) s := make([]int, 4) s = a[0:4] t.Log(s) s = append(s, 5) t.Log(a) t.Log(s) } === RUN TestCreatearray f:\GO\go_test\data\data_test.go:29: [1 2 3 4] f:\GO\go_test\data\data_test.go:32: [1 2 3 4] f:\GO\go_test\data\data_test.go:34: [1 2 3 4] f:\GO\go_test\data\data_test.go:35: [1 2 3 4 5] --- PASS: TestCreatearray (0.00s) 二维切片(Two-dimensional Slices) 下面是二位数组和二位切片的示例。 ...

2021-04-15 · 4 min · 670 words

Effective Go-2

分号 若在一行最后一个标识符为以下类型 数字 字符串常量 特殊标识符号;break continue fallthrough return ++ – ) } 词法分析器会在标识符后添加分号, 与C不同GO很多地方都省略分号。 另在在if for switch select控制结构后要接 “{”, 例如: if i < f() { g() } 而不要写成 if i < f() { g() } 控制结构 if/switch/for If switch语句中可以接受初始化语句 if err := file.Chmod(0664); err != nil { log.Print(err) return err } For 遍历数组,切片,字符串或者map时,可以使用range子句 for key, value := range oldMap { newMap[key] = value } Switch中有两个比较特殊的地方, break跳出指定一个标签范围: Loop: for n := 0; n < len(src); n += size { switch { case src[n] < sizeOne: if validateOnly { break } size = 1 update(src[n]) case src[n] < sizeTwo: if n+1 >= len(src) { err = errShortInput break Loop } if validateOnly { break } size = 2 update(src[n] + src[n+1]<<shift) } } 与C不同他不仅支持整数,枚举还支持类型判断 ...

2021-04-07 · 2 min · 301 words

LeetCode-Palindrome Pairs Solution

问题 Given a list of unique words, return all the pairs of the distinct indices (i, j) in the given list, so that the concatenation of the two words words[i] + words[j] is a palindrome. Example 1: Input: words = ["abcd","dcba","lls","s","sssll"] Output: [[0,1],[1,0],[3,2],[2,4]] Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"] Example 2: Input: words = ["bat","tab","cat"] Output: [[0,1],[1,0]] Explanation: The palindromes are ["battab","tabbat"] Example 3: Input: words = ["a",""] Output: [[0,1],[1,0]] Constraints: ...

2021-04-01 · 2 min · 383 words

查询和清除文件系统缓存

为了减少磁盘I/O,加快读写速度,Linux内核使用文件系统的Cache,Page Cache。 下面通过一个实验验证一下,查看Cache分配使用情况。 # free -w total used free shared buffers cache available Mem: 344756 106244 186612 1540 76 51824 226956 Swap: 2097148 30464 2066684 free 从/proc/meminfo 中获取信息进行展示,这里的Page Cache主要是 cache + buffers 这两个项目项目。 page cache是针对 file systems , buffer是针对 block devices 两者是在不同时期不同场景下涉及的缓存机制,kernel2.4版本之前是分开的,并存的。之后版本进行了融合。free默认不加-w参数,可以看到输出cache和buffer合计在一起 # dd if=/dev/random of=/root/data_file count=1400000 # du data_file -sh 103M data_file 使用读取两次文件观察下执行时间 # free -w total used free shared buffers cache available Mem: 344756 106244 186612 1540 76 51824 226956 Swap: 2097148 30464 2066684 # time cat data_file > /dev/null real 0m0.273s user 0m0.000s sys 0m0.064s # free -w total used free shared buffers cache available Mem: 344756 106240 81072 1540 76 157368 227012 Swap: 2097148 30464 2066684 # time cat data_file > /dev/null real 0m0.031s user 0m0.002s sys 0m0.026s 可以看到第二次执行时间比第一次明显减少,清理一下page cache ...

2021-03-30 · 2 min · 228 words

视频的版权识别与管理

昨天正在听一位老师的英语的直播课, 当时她正在用影片的片段讲解英文听力课,讲到一半的时候,直播中断了。 显示“​stream suspended for policy violations” 后来查了下资料才知道, 平台通过Connent ID系统的运作方式来识别和管理上传的视频和音频版权。 千亿美金的YouTube:收购后的13年里 Google做了什么?这篇文章比较详细的介绍了Google收购YouTube后, 对其版权管理和内容变现盈利模式做的一些工作。 Youtube的成功离不开 Google 长远的眼光,而“ Google的生态数据、广告销售体系和Google Cloud的支持,也放大了YouTube的商业价值。” Content ID系统 Google收购Youtube后为解决其版权问题,建立一个能识别版权内容的Content ID系统。 版权所有者可以向YouTube上传自己的音频或视频文件,Content ID数据库根据这些文件来创建内容“指纹”。 如果发现有翻拍或模仿的内容,平台会给版权所有者三个选择: 禁播:禁止用户观看整个视频 获利:通过在视频中投放广告来利用视频获利;有时可以与上传者分享收益 跟踪:跟踪视频的观看情况统计信息 官网的一个视频介绍 实现思路及相关知识点整理 关于Content ID系统闭源实现, 目前没找到相关资料, 个人理解应该涉及三个方面。 视频识别 处理流程 服务整合 视频识别 视频识别主要涉及计算机视觉技术**(Computer Vision, CV),**涉及计算机视觉的基础模型,特征提取,近几年都受到深度学习的影响,出现了基于深度学习计算机视觉模型。 计算机视觉 概念 计算机视觉通过模仿人类的视觉系统,从照相机,摄影机等视频采集设备中获取原始信息,通过这些原始信息,进行语义(Semantic)解释或者逻辑理解。比如我们使用的电脑,我们需要识别显示器, 键盘,鼠标,并在头脑中形成这些物体的概念。 领域特点 **跨学科领域:**计算机视觉涉及多个领域 生物学领域:人眼及视觉神经系统,理解人脑的处理机制 物理学领域:设备越精密,越能完整的额捕获外界信息,主要涉及光学领域的研究。 计算机科学:信息检索,计算机体系结构,机器学习。 相关难题: 图像信息与语义之间巨大鸿沟。例如:如何将一个200*200RGB图像,对应12万数字组成的矩阵与具体的事物关联起来。 识别速度。实验表明,一副普通场景图片,人类需要150毫秒,人类在理解图片时,依靠过去的记忆、经验、外界知识来对图像中物体进行判断。这些都是计算机系统难以企及的。 **实现方式。**是模仿人类视觉系统还是需要开辟其他研究道路。 应用: 视频识别已经在人脸识别,光学字符识别,电影特效,视觉搜索,自动驾驶,无人商店,虚拟现实,增强现实等方面有了广泛应用。 基础模型及操作: 像素表达: 根据不同的图像类型像素表达也不同. 黑白图像:转化0或1的二元矩阵 灰度图像:每一个像素代表灰度的“强度”Intensity 范围在0-255 彩色图像:比较流行的RGB,三种颜色叠加,RGB代表三种不同的通道,每一个通道都是一个矩阵表达,每个像素代表0-255,彩色图像是一个**张量(Tensor),**也就是三个矩阵叠加一起的结果。 像素本身是真实世界中的“采样”,连续的信号采样到离散像素,难免会有失真的情况,不同分辨率会有不同程度的像素表达。 关键字 Pixel 过滤器: 移动平均(Moving Average) 这个过滤器的本质就是针对每个像素点对周围的9个像素点,计算其平均值,并形成心得矩阵。然后对新像素点视觉化。 ...

2021-03-24 · 1 min · 166 words

Effective Go - 1

格式化 为了减少格式化问题带来的争议, 可以使用 gofmt程序对源码进行格式化。 gofmt -w .\src\ch1\main\hello_world.go 注释 每个包都应有一个_P_ackage comment 包注释, 对于多文件程序包,程序包注释仅需要出现在一个文件中,任何一个都可以。 注释中应介绍介绍并包整体功能及有关的信息。 _Doc comment_文档注释最好作为完整的句子使用,它可以进行各种各样的自动演示。 第一句应为单句摘要,以声明的名称开头。 go doc 工具会从 Go 程序和包文件中提取注释以并生成相关文档。 godoc 可以启动本地web服务 godoc -http=:12345 -goroot f:\\go\\gotest 浏览器输入http://127.0.0.1:12345, 即可查看本地f:\go\gotest由注释生成的文档。 命名 _包名;_当一个包被导入后,包名就会成了内容的访问器。按照惯例, 包应当以小写单词来命名,且不应使用下划线或驼峰记法。如 import “bytes”, 如果包名发生冲突可以使用别名方式来解决 另外就是包名应为其_源码目录_的名称。如:src/pkg/encoding/base64 中的包应作为 “encoding/base64” 包的导入者可_通过包名来引用其内容_,避免冲突,bufio.Reader 不会与 io.Reader 发生冲突 Getters go不自动支持getter和setter, 有个名为 owner 的字段,其getter应当名为 Owner(大写,可导出)而非 GetOwner, sett而没有这方面约定 owner := obj.Owner() if owner != user { obj.SetOwner(user) } 接口, 包含一个方法的接口应当以该方法的名称加上 -er 后缀来命名,如 Reader、Writer、 Formatter、CloseNotifier 等。不要用Read、Write、Close、Flush、 String 等请不要用这些名称为自己的方法命名。 书写格式, MixedCaps or mixedCaps 首字母大写或小写的驼峰记法,而不是用下划线链接。 ...

2021-03-07 · 1 min · 81 words

LeetCode-Word Search II Solution

问题: Given an m x n board of characters and a list of strings words, return all words on the board. Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. Example 1: Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"] Output: ["eat","oath"] Example 2: Input: board = [["a","b"],["c","d"]], words = ["abcb"] Output: ...

2021-03-07 · 2 min · 270 words

Linux跨文件系统的文件夹和文件映射关系

VFS(Virtual File System) Everything is a file 是Unix的设计理念,由其派生的Linux也如此。 Unix系统I/O模型最为显著的特征之一就是I/O通用性,也就是同一套系统调用open(), read(),write(),close()所执行的I/O操作,可以在所有文件类型上被执行。 文件系统有很多种实现。 Linux系统中通过VFS(Virtual File System),定义一系列通用接口。所有与文件交互程序都会按照接口进行操作。 每种文件系统都会提供VFS接口实现。 依赖倒置原则(DIP):高层的模块不依赖底层, 而依赖高层的抽象。 文件模型 主要由以下对象模型组成: Superblock object:存放文件系统信息。 inode object:存放具体文件一般信息, 文件控制信息,唯一标识一个文件。 file object:存放文件与进程间交互信息。 dentry object:存放dentry与文件相关信息,便于文件检索。 图片来在《Understanding The Linux Kernel》 可以看到在inode object和superblock object和实际的文件系统有直接关系的, 而file object和dentry object与文件系统是没有映射的,其中,dentry object起到了中间纽带的作用。 文件使用 每一个进程将打开的文件的描述符(file descriptor)保存在一个数组中, 当调用open()时,系统调用返回文件描述符,供后续read(),write()等使用, 这些系统调用获取file的数据结构后,通过VFS函数的调用,实现相关功能。 下图展示了相关数据结构之间的关系。 图片来自 https://myaut.github.io/dtrace-stap-book/kernel/fs.html 从上图可以看到, 进程通过task_struct中的files可以获得file object,包括文件打开方式f_mode,如O_RDONLY、O_RDWR, 文件偏移位置f_pos,如seek函数使用到, 文件相关的系统调用都可以通过file object对文件进行操作。 每一个文件可以通过inode object和dentry object进行标识, inode object包含一些文件本身的一些信息, 如权限信息,比如i_uid,i_gid, dentry object包含文件的目录结构信息,方便通过文件名进行查找。 虽然dentry和inode标识文件系统的文件, 但是系统在不同位置可以安装多个文件系统, 这个位置就是mountpoint, linux中通过vfsmount 结构的mnt_sb指向标识文件系统super_block, 通过mnt_root指向安装点, 就可以方便跨文件系统的文件管理。 文件映射 下面用调试工具看下跨文件系统映射关系 ...

2021-03-06 · 2 min · 403 words

mount操作导致磁盘数据丢失

环境: cenos7(X86_64) + openssh 问题现象: 重新编译内容,使用linux调试工具后, 终端忽然中断, 再重启机器后。启动后显示。 Failed to switch root on boot 解决思路: 通过报错查找命令解决 搜索到一下链接 Problem with CentOS: Failed to switch root on boot 。。。 mount -o remount,rw /sysroot cd /sysroot/etc echo "" >os-release mount -o remount,ro /sysroot reboot 。。。 当时也没仔细看, 直接按照里面操作执行了下。 通过安装新操作系统挂载原有磁盘: 看了下简单操作无法回复,添加了一块硬盘,下载镜像安装,调整启动磁盘顺序 [root@localhost ~]# pvdisplay --- Physical volume --- PV Name /dev/sdc2 VG Name centos00 PV Size <19.00 GiB / not usable 3.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 4863 Free PE 1 Allocated PE 4862 PV UUID 。。。 --- Physical volume --- PV Name /dev/sda3 VG Name centos PV Size 59.00 GiB / not usable 4.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 15104 Free PE 0 Allocated PE 15104 PV UUID 。。。 看了之前的硬盘, 查看一下分区 ...

2021-03-02 · 2 min · 254 words