真正在工作中用Go的时间不久,所以也作为新手,总结了一些常见的问题和坑

Go 中指针使用注意点

// 1.空指针反向引用不合法
package main
func main() {
var p *int = nil
*p = 0
}
// in Windows: stops only with: <exit code="-1073741819" msg="process crashed"/>
// runtime error: invalid memory address or nil pointer dereference // 2.文字或者常量引用也不合法
const i = 5
ptr := &i //error: cannot take the address of i
ptr2 := &10 //error: cannot take the address of 10

Go语言常见内置函数

sort

// sort 包
import "sort"
sort.Strings(keys)

close 用于管道通信,select 用于通信的switch

type T int
func main() {
c := make(chan T)
close(c)
} // select 用法
var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
}

len、cap

len 用于返回某个类型的长度或数量(字符串、数组、切片、map 和管道);

cap 是容量的意思,用于返回某个类型的最大容量(只能用于切片和 map)

new、make

new 和 make 均是用于分配内存:new 用于值类型和用户定义的类型,如自定义结构,make 用于内置引用类型(切片、map 和管道)。

它们的用法就像是函数,但是将类型作为参数:new (type)、make (type)。new (T) 分配类型 T 的零值并返回其地址,也就是指向类型 T 的指针。

它也可以被用于基本类型:v := new(int)。make (T) 返回类型 T 的初始化之后的值,因此它比 new 进行更多的工作,new () 是一个函数,不要忘记它的括号

copy、append

用于复制和连接切片

panic、recover

两者均用于错误处理机制

print、println

底层打印函数,在部署环境中建议使用 fmt 包

complex、real、imag

操作复数,使用场景不多

Go不支持函数重载

Go 语言不支持这项特性的主要原因是函数重载需要进行多余的类型匹配影响性能;没有重载意味着只是一个简单的函数调度。所以你需要给不同的函数使用不同的名字,我们通常会根据函数的特征对函数进行命名

如果需要申明一个在外部定义的函数,你只需要给出函数名与函数签名,不需要给出函数体:

func flushICache(begin, end uintptr) // implemented externally

函数也可以以申明的方式被使用,作为一个函数类型,就像:

type binOp func(int, int) int

Go的map遍历时候变量地址一直用的是同一个

最佳实践:读数据可以用key,value,写数据用地址,如果要把地址赋值给另外的map,那么需要用临时变量

  kvMap := make(map[int]int)
kvMap[0] = 100
kvMap[1] = 101
kvMap[2] = 102
kvMap[3] = 103 for k, v := range kvMap {
println(k, &k, v, &v)
} // 0 0xc000049e50 100 0xc000049e48
// 1 0xc000049e50 101 0xc000049e48
// 2 0xc000049e50 102 0xc000049e48
// 3 0xc000049e50 103 0xc000049e48

Go遍历的key,value是值,而不是地址

// Version A:
items := make([]map[int]int, 5)
for i:= range items {
items[i] = make(map[int]int, 1)
items[i][1] = 2
}
fmt.Printf("Version A: Value of items: %v\n", items) // Version B: NOT GOOD!
items2 := make([]map[int]int, 5)
for _, item := range items2 {
item = make(map[int]int, 1) // item is only a copy of the slice element.
item[1] = 2 // This 'item' will be lost on the next iteration.
}
fmt.Printf("Version B: Value of items: %v\n", items2)

应当像 A 版本那样通过索引使用切片的 map 元素。在 B 版本中获得的项只是 map 值的一个拷贝而已,所以真正的 map 元素没有得到初始化

锁和 sync 包

并发编程在大部分语言里面都会有,用来解决多个线程对临界资源的访问,经典的做法是一次只能让一个线程对共享变量进行操作。当变量被一个线程改变时 (临界区),我们为它上锁,直到这个线程执行完成并解锁后,其他线程才能访问它,Go语言的这种锁机制是通过sync包中的Mutex来实现访问的,下面是一个例子,另外在sync包中还有一个读写锁,RWMutex ,其写互斥的方法与Mutex一样,读互斥采用下面的方法

mu sync.Mutex

func update(a int) {
mu.Lock()
a = xxx
mu.Unlock()
} mu2 sync.RWMutex
mu2.RLock()
mu2.RUnlock()

吴邪,小三爷,混迹于后台,大数据,人工智能领域的小菜鸟。

更多请关注

大数据开发-Go-新手常遇问题的更多相关文章

  1. 从 Airflow 到 Apache DolphinScheduler,有赞大数据开发平台的调度系统演进

    点击上方 蓝字关注我们 作者 | 宋哲琦 ✎ 编 者 按 在不久前的 Apache  DolphinScheduler Meetup 2021 上,有赞大数据开发平台负责人 宋哲琦 带来了平台调度系统 ...

  2. 2019春招——Vivo大数据开发工程师面经

    Vvio总共就一轮技术面+一轮HR面,技术面总体而言,比较宽泛,比较看中基础,面试的全程没有涉及简历上的东西(都准备好跟他扯项目了,感觉是抽取的题库...)具体内容如下: 1.熟悉Hadoop哪些组件 ...

  3. 杭州某知名xxxx公司急招大量java以及大数据开发工程师

    因公司战略以及业务拓展,收大量java攻城狮以及大数据开发攻城狮. 职位信息: java攻城狮: https://job.cnblogs.com/offer/56032 大数据开发攻城狮: https ...

  4. 大数据开发实战:HDFS和MapReduce优缺点分析

    一. HDFS和MapReduce优缺点 1.HDFS的优势 HDFS的英文全称是 Hadoop Distributed File System,即Hadoop分布式文件系统,它是Hadoop的核心子 ...

  5. 大数据开发实战:Stream SQL实时开发三

    4.聚合操作 4.1.group by 操作 group by操作是实际业务场景(如实时报表.实时大屏等)中使用最为频繁的操作.通常实时聚合的主要源头数据流不会包含丰富的上下文信息,而是经常需要实时关 ...

  6. 大数据开发实战:Stream SQL实时开发二

    1.介绍 本节主要利用Stream SQL进行实时开发实战,回顾Beam的API和Hadoop MapReduce的API,会发现Google将实际业务对数据的各种操作进行了抽象,多变的数据需求抽象为 ...

  7. 大数据开发实战:Stream SQL实时开发一

    1.流计算SQL原理和架构 流计算SQL通常是一个类SQL的声明式语言,主要用于对流式数据(Streams)的持续性查询,目的是在常见流计算平台和框架(如Storm.Spark Streaming.F ...

  8. 大数据开发实战:Spark Streaming流计算开发

    1.背景介绍 Storm以及离线数据平台的MapReduce和Hive构成了Hadoop生态对实时和离线数据处理的一套完整处理解决方案.除了此套解决方案之外,还有一种非常流行的而且完整的离线和 实时数 ...

  9. 大数据开发实战:Storm流计算开发

    Storm是一个分布式.高容错.高可靠性的实时计算系统,它对于实时计算的意义相当于Hadoop对于批处理的意义.Hadoop提供了Map和Reduce原语.同样,Storm也对数据的实时处理提供了简单 ...

随机推荐

  1. Spring事件发布与监听机制

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 目录 ...

  2. 为什么 Python 没有函数重载?如何用装饰器实现函数重载?

    英文:https://arpitbhayani.me/blogs/function-overloading 作者:arprit 译者:豌豆花下猫("Python猫"公众号作者) 声 ...

  3. golang 用defer 捕获error 需小心

    有时一个函数内需要根据最后是否出错,决定是否执行某个操作.这时候如果函数的分支又比较多,就会比较麻烦了. defer 处理这个情况刚好合适 func main() { var err error by ...

  4. 二QT中使用QTimer定时器

    QT中的定时器类叫QTimer(5.8以上版本才有),构造函数只需要提供父对象的指针 使用的话,需要调用QTImer的start方法,该方法以毫秒单位,每过指定毫秒时间,该类对象就会发出一个timeo ...

  5. FastDFS文件系统迁移和数据恢复

    迁移步骤 打包旧服务器文件的所有文件 定位到旧服务器的tracker和Storage目录,将整个文件夹打包 tar -zcf fdfs-storage-data.tar.gz /fastdfs/sto ...

  6. POJ 1873 The Fortified Forest 凸包 二进制枚举

    n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...

  7. WEB与游戏开发的一些区别

    WEB与游戏开发的一些区别 前言 ​ 最近由于在准备期末考,以及准备实习.其实都没好好写过博客,但今天由于个人身边的一些事,所以对做web和做游戏开发的区别做个记录,以下都是从网上搜索到的资料文章,感 ...

  8. SpringCloud:扩展zuul配置路由访问

    继续上次整合SpringCloud的demo进行扩展zuul:https://www.cnblogs.com/nhdlb/p/12555968.html  这里我把zuul划分出一个模块单独启动 创建 ...

  9. Linux date 获取时间

    获取当前日期: ubuser@ubuser-OptiPlex-7010:~$ date +%Y_%m_%d2020_12_16 获取当前时间: ubuser@ubuser-OptiPlex-7010: ...

  10. docker进入容器所在虚拟机的指令

    sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9 在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了. $ sudo nsenter ...