go要点2

interface

nterface就是一组抽象方法的集合,它必须由其他非interface类型实现,而不能自我实现, Go通过interface实现了duck-typing:即”当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子”。

type Stringer interface {
     String() string
}
package main
import (
    "fmt"
    "strconv"
)

type Human struct {
    name string
    age int
    phone string
}

// 通过这个方法 Human 实现了 fmt.Stringer
func (h Human) String() string {
    return "❰"+h.name+" - "+strconv.Itoa(h.age)+" years -  ✆ " +h.phone+"❱"
}

func main() {
    Bob := Human{"Bob", 39, "000-7777-XXX"}
    fmt.Println("This Human is : ", Bob)
}
  • Comma-ok断言
    Go语言里面有一个语法,可以直接判断是否是该类型的变量: value, ok = element.(T),这里value就是变量的值,ok是一个bool类型,element是interface变量,T是断言的类型。如果element里面确实存储了T类型的数值,那么ok返回true,否则返回false。
  • switch测试
    element.(type)语法不能在switch外的任何逻辑里面使用,如果你要在switch外面判断一个类型就使用comma-ok
for index, element := range list{
            switch value := element.(type) {
                case int:
                    fmt.Printf("list[%d] is an int and its value is %d\n", index, value)
                case string:
                    fmt.Printf("list[%d] is a string and its value is %s\n", index, value)
                case Person:
                    fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)
                default:
                    fmt.Println("list[%d] is of a different type", index)
            }
        }
  • 嵌入interface
type Interface interface {
    sort.Interface //嵌入字段sort.Interface
    Push(x interface{}) //a Push method to push elements into the heap
    Pop() interface{} //a Pop elements that pops elements from the heap
}
  • reflect 反射机制
    https://blog.golang.org/laws-of-reflection

关键字

break    default      func    interface    select
case     defer        go      map          struct
chan     else         goto    package      switch
const    fallthrough  if      range        type
continue for          import  return       var
  • func 用于定义函数和方法
  • return 用于从函数返回
  • defer 用于类似析构函数
  • go 用于并发
  • select 用于选择不同类型的通讯
  • interface 用于定义接口
  • struct 用于定义抽象数据类型
  • break、case、continue、for、fallthrough、else、if、switch、goto、default 流程控制
  • chan用于channel通讯
  • type用于声明自定义类型
  • map用于声明map类型数据
  • range用于读取slice、map、channel数据

GO要点1

gopath

  • src 存放源代码(比如:.go .c .h .s等)
  • pkg 编译后生成的文件(比如:.a)
  • bin 编译后生成的可执行文件

go类型

rune, int8, int16, int32, int64和byte, uint8, uint16, uint32, uint64。其中rune是int32的别称,byte是uint8的别称,浮点数的类型有float32和float64两种(没有float类型),默认是float64。
Go还支持复数,它的默认类型是complex128(64位实数+64位虚数)。如果需要小一些的,也有complex64(32位实数+32位虚数)。复数的形式为RE + IMi,其中RE是实数部分,IM是虚数部分,而最后的i是虚数单位。

var c complex64 = 5+5i
//output: (5+5i)
fmt.Printf("Value is: %v", c)

array、slice、map

  • array就是数组,数组也就不能改变长度
  • slice并不是真正意义上的动态数组,而是一个引用类型。slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度。

make、new

  • 内建函数make(T, args)与new(T)有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型,而不是*T。本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值。
  • new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个*T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。

switch

Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码。

integer := 6
switch integer {
case 4:
    fmt.Println("The integer was <= 4")
    fallthrough
case 5:
    fmt.Println("The integer was <= 5")
    fallthrough
case 6:
    fmt.Println("The integer was <= 6")
    fallthrough
case 7:
    fmt.Println("The integer was <= 7")
    fallthrough
case 8:
    fmt.Println("The integer was <= 8")
    fallthrough
default:
    fmt.Println("default case")
}

函数

  • Panic
  • Recover

import

  • 相对路径
    import “./model” //当前文件同一目录的model目录,但是不建议这种方式来import
  • 绝对路径
    import “shorturl/model” //加载gopath/src/shorturl/model模块
  • 点操作
 import(
     . "fmt"
 )
fmt.Println("hello world")可以省略的写成Println("hello world")
  • 别名操作
 import(
     f "fmt"
 )
  • _操作
import (
        "database/sql"
        _ "github.com/ziutek/mymysql/godrv"
    )

_操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。

struct匿名字段

type Human struct {
    name string
    age int
    weight int
}

type Student struct {
    Human  // 匿名字段,那么默认Student就包含了Human的所有字段
    speciality string
}

通过匿名访问和修改字段相当的有用,但是不仅仅是struct字段,所有的内置类型和自定义类型都是可以作为匿名字段的。如果字段名有冲突遵循最外层的优先访问原则,访问内层的可以通过匿名字段名来访问

面向对象-method

method语法定义

func (r ReceiverType) funcName(parameters) (results)

在使用method的时候重要注意几点:

  • 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
  • method里面可以访问接收者的字段
  • 调用method通过.访问,就像struct里面访问字段一样
  • receiver既可以是值传递,也可以是引用传递
  • 可以用在你自定义的类型、内置类型、struct等各种类型上面
  • 如果一个method的receiver是*T,你可以在一个T类型的实例变量V上面调用这个method,而不需要&V去调用这个method
  • 如果一个method的receiver是T,你可以在一个*T类型的变量P上面调用这个method,而不需要 *P去调用这个method
  • 如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method。
package main

import (
    "fmt"
    "math"
)

type Rectangle struct {
    width, height float64
}

type Circle struct {
    radius float64
}

func (r Rectangle) area() float64 {
    return r.width*r.height
}

func (c Circle) area() float64 {
    return c.radius * c.radius * math.Pi
}


func main() {
    r1 := Rectangle{12, 2}
    r2 := Rectangle{9, 4}
    c1 := Circle{10}
    c2 := Circle{25}

    fmt.Println("Area of r1 is: ", r1.area())
    fmt.Println("Area of r2 is: ", r2.area())
    fmt.Println("Area of c1 is: ", c1.area())
    fmt.Println("Area of c2 is: ", c2.area())
}

可见性

Go语言没有像其它语言一样有public、protected、private等访问控制修饰符,它是通过字母大小写来控制可见性的,如果定义的常量、变量、类型、接口、结构、函数等的名称是大写字母开头表示能被其它包访问或调用(相当于public),非大写开头就只能在包内使用(相当于private,变量或常量也可以下划线开头)

下半年学习规划

下半年学习规划

以往学习的比较杂乱,现在统一制定下下半年的学习规划,年底截止,完成的打钩

阅读

  • 财经类两本
  • 悬疑、科幻、历史类
    • 《明朝1566》
    • 《白夜行》
    • 《放学后》
  • 英语阅读

工程能力

  • 掌握GO编程、阅读3本相关书籍、并重构IOT通信系统
  • 掌握Docker应用、阅读1本相关书籍,时间富足可以学习Kubernetes
  • 掌握Redis、MySQL集群的使用,并深入了解
  • 掌握Python的高级使用,并参加Kaggle比赛

算法能力

  • 学习基本的机器学习知识并应用起来
    • 线性回归
    • 逻辑回归
    • 神经网络
    • 算法评估
    • 支持向量机
    • 聚类
    • 异常检测
    • 实战
  • 学习深度学习相关知识
  • 复习数据结构和算法,参考书籍算法导论

Docker使用

  Docker使用Google公司推出的Go语言进行开发实现,基于Linux 内核的cgroup,namespace,以及 AUFS 类的Union FS等技术对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等,极大的简化了容器的创建和维护。而虚拟机会虚拟出一套硬件,在其上运行一套操作系统, 因此Docker 技术比虚拟机技术更为轻便、快捷。

快速上手

安装

curl -sSL https://get.docker.com/ |sh
注意使用国内镜像源

运行

docker run --name demo -it -d centos

基本概念

镜像

镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。在构建的过程中是一层一层构建的,前一层是后一层的基础,每一层构建完就不会发生改变。
相关命令:


Usage:docker image COMMAND Manage images Commands: build Build an image from a Dockerfile history Show the history of an image import Import the contents from a tarball to create a filesystem image inspect Display detailed information on one or more images load Load an image from a tar archive or STDIN ls List images prune Remove unused images pull Pull an image or a repository from a registry push Push an image or a repository to a registry rm Remove one or more images save Save one or more images to a tar archive (streamed to STDOUT by default) tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

容器

  容器可以理解为镜像运行时的实体,可以被创建、启动、停止、删除、暂停等
相关命令:

Usage:docker container COMMAND
Manage containers
Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

注意事项:

  • 在执行命令的时候推荐用exec而不是attach,避免exit的时候容器退出
  • 可以使用inspect 命令查看容器详细信息,使用logs命令查看相关日志,用于定位错误
  • 容器与容器之间默认是无法互联的,可以使用docker-compose部署或使用link参数在运行时组网,不过建议使用docker create network命令构建网络

仓库

镜像存储分发的地方,类似于GITHUB,推荐使用阿里云做加速

其它内容

数据管理

数据卷

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用

  • 对数据卷的修改会立马生效

  • 对数据卷的更新,不会影响镜像

  • 数据卷默认会一直存在,即使容器被删除

 docker volume create my-vol
 docker volume ls
 docker volume rm my-vol

网络连接

  • -p 映射 TCP/UDP 不一样
  • 创建网络
  • 容器互联

DockerFile的编写

  • 参考网上教程

Compose的使用

  • 使用PIP安装,安装后创建compose文件即可使用,管理起来比较方便而且默认是互联的

Kubernetes的使用

一些示例

Docker run --name test -it -d centos bash 启动交互式命令行
Docker run --name redis -it -d redis redis-server --appendonly yes -v /home/work/data/redis:/data 使用AUFS在宿主机保存Redis数据
Docker run --name test -it -d -p 23:22  centos bash 端口23 映射到22