您现在的位置是:首页 >技术杂谈 >Go 面试经验-面试题目01网站首页技术杂谈
Go 面试经验-面试题目01
1、为什么学go?讲讲你对go的理解?看过什么书?
- 从2015年到2019年golang的发展趋势一直处在稳定上升
-
Golang的核心开发组成员由一群大神级人物组成。其中,最核心的三人分别是Ken Thompson、Rob Pike、Robert Griesemer。
Ken Thompson,C和B语言的设计者、Unix创始人之一,操作系统Plan 9的主要作者,1983年图灵奖得主;
Rob Pike,UTF8的主要设计者,与Ken Tompson为贝尔实验室的同事,共同参与了Plan9。而且Golang的logo,据说是囊地鼠,英文gopher,就是Rob Pike的妻子设计的;
Robert Griesemer,参与开发了 Java HotSpot 虚拟机和Javascript的Chrome V8引擎;
-
go 的语言特性
-
静态语言与高并发
- 静态语言、静态编译速度快,拥有静态语言的安全与性能;
- 天然支持并发,基于CPS并发模型,goroutine轻量级线程,支持大并发处理;
- 简洁的脚本化语法,如变量赋值 a := 1,兼具静态语言的特性与动态语言的开发效率;
- 提供垃圾回收机制,不需要开发人员管理,通过循环判活,再启用goroutine来清理内存;
- 创新的异常处理机制,普通异常通过返回error对象处理,严重异常由panic、recover处理;
- 函数多返回值,方便接收多值,一些解释性语言已经支持,如python、js的es6等;
- 支持defer延迟调用,从而提供了一种方式来方便资源清理,降低资源泄露的概率;
- 面向接口的oop,没有对象与继承,强调组合,以类似于duck-typing的方式编写面向对象
-
- 优秀项目
- docker,golang头号优秀项目,通过虚拟化技术实现的操作系统与应用的隔离,也称为容器;
- kubernetes,由google开发,简称k8s,k8s和docker是当前容器化技术的重要基础设施;
- etcd,一种可靠的分布式KV存储系统,有点类似于zookeeper,可用于快速的云配置;
- codis,由国人开发提供的一套优秀的redis分布式解决方案;
- tidb,国内PingCAP 团队开发的一个分布式SQL 数据库,国内很多互联网公司在使用;
- influxdb,时序型DB,着力于高性能查询与存储时序型数据,常用于系统监控与金融领域;
- cockroachdb,云原生分布式数据库,继NoSQL之后出现的新的概念,称为NewSQL数据库;
- beego,国人开发的一款及其轻量级、高可伸缩性和高性能的web应用框架;
- caddy,类比于nginx,一款开源的,支持HTTP/2的 Web 服务端;
- flynn,一款开源的paas平台;
- consul,HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置;
- go-kit,Golang相关的微服务框架,这类框架还有go-micro、typthon;
- go-ethereum,官方开发的以太坊协议实现;
- couchbase,是一个非关系型数据库;
- nsq,一款高性能、高可用消息队列系统,每天能处理数十亿条的消息;
- packer,一款用来生成不同平台的镜像文件的工具,例如VM、vbox、AWS等;
- doozer:高速的分布式数据同步服务,类似ZooKeeper;
- tsuru:开源的PAAS平台,和SAE实现的功能一模一样;
- gor:一款用Go语言实现的简单的http流量复制工具;
- 应用领域:
- 区块链
- 当前的两个主流区块链框架,分布式记账本框架hyperledger和以太坊合约框架go-ethereum都是使用Golang开发;
-
微服务
-
现在越来越多的项目会采用微服务架构,前面介绍的优秀项目中也看到很多go提供的微服务框架,如git-kit、micro等。
举一些具体公司的例子,比如今日头条使用Golang构建了千万级微服务;
-
- 云服务
-
云服务,如国内著名的七牛云全站采用Golang开发;还有如盛大CDN、阿里云CDN等;
很多的云平台基础设施如docker、kubernetes等为Golang开发;
京东的消息推送与分布式存储也是如此;
-
-
分布式
-
诸如数据库中间件、代理服务等很多采用Golang开发,比如前面的介绍codis、cockroachdb、etcd等;
-
-
其他
-
很多领域都能看到Golang的影子,诸如直播领域、游戏开发等等,在其中golang为后台的调度系统、任务处理,批量的数据计算、系统监控等提供了各种解决方案。
比如,最近知乎近也使用Golang进行重构了自己的推荐系统。
-
- 区块链
Golang官网
Golang官方地址: golang.org,无论学习什么知识,第一手资料基本都是首发于官网。进入到官网后,会看到很多资源,比如:
文档:golang.org/doc,官方文档,仔细读下文档首页并分类,了解下自己要学哪些内容;
一览:tour.golang.org,交互式运行环境,不安装golang便可体验学习它的语法与使用;
指南:golang.org/ref/spec,golang学习指导手册,从基础语法到高级特性全部都有介绍;
标准库:golang.org/pkg/,可以查看所有的官方库的接口、源码以及使用介绍;
博客:blog.golang.org/,不定期分享go的最佳实践,有些公司也会投稿介绍自己的案例;
实验室:play.golang.org,感觉和tour类似,不过在这里编写的代码可以分享给别人;
golang社区
一门语言的发展需要有大批牛人的分享布道,也需要我们这些菜鸟学习有更多的参考路径。这一切都离不开社区。国内外也有很多优秀的go语言社区;
go语言中文网,studygolang.com,分享Go 语言知识,聚合各种golang文章和书籍资料;
beego社区,beego.me/community,国人开发的框架社区;
go交流论坛,gocn.vip,go语言学习交流论坛;
go官方讨论组,forum/golang-nuts,golang的官方邮件讨论组;
2、go的内存模型
- Go语言中内存分配大致有3种模式: Stack 、 Heap 、 Fixed Size Segment 。
我们为什么需要内存模型?由于cpu指令重排,以及多级的内存cache的存在,比如go语言存在的多级内存模型,不同的cpu架构,例如x86,arm 等等,而且编译器的优化也会对于指令进行重排,所以编程语言需要一个内存规范,即为:内存模型。
3、go的基本数据类型
- 布尔型(占一个字节)
- 值:TRUE 和 FALSE
- 数值型
- 整型
- 有符号:int,int8,int16,int32,int64
- 无符号:uint,uint8,uint16,uint32,uint64,byte
- int 和 uint 的大小和系统有关
- byte 类似 uint8
- rune 类型 int32
- 浮点型
- float32、float64
- complex64(32位实数和虚数)
- complex128(64位实数和虚数)
- 整型
- 字符串型
- string
4、go的传参机制
5、你是怎么理解docker的?
6、dockerFile 常用指令
Dockerfile是什么
dockerfile仅仅是用来制作镜像的源码文件,是构建容器过程中的指令,docker能够读取dockerfile的指定进行自动构建容器,基于dockerfile制作镜像,每一个指令都会创建一个镜像层,即镜像都是多层叠加而成,
Dockerfile的指令根据作用可以分为两种:构建指令和设置指令。
(1)构建指令用于构建image,其指定的操作不会运行在image的容器中执行。
(2)设置指令用于设置image的属性,其指定的操作将在运行image的容器中执行。
Dockerfile 常用指令
-
FROM (构建指令)
指定 base 镜像,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的镜像。FROM指令指定的base镜像可以是官方远程仓库中的,也可以位于本地仓库。
该指令有两种格式:
FROM <image>
指定基础image为该image的最后修改的版本(latest)。
或者:
FROM <image>:<tag>
指定基础image为该image的一个tag版本
-
MAINTAINER (构建指令)
格式:MAINTAINER <name>
设置镜像的作者,可以是任意字符串。用于将image的制作者相关的信息写入到image中。当我们对该image执行
docker inspect命令时,输出中有相应的字段记录该信息。
现在已经被“LABEL maintainer=”取代
LABEL maintainer="berry <xxxxxxx@qq.com>"
-
COPY(构建指令)
将文件从 build context 复制到镜像。
COPY 支持两种形式:
COPY src ... dest
COPY ["src", ... "dest"]
-
ADD(构建指令)
与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。
此指令用于复制新文件、目录或者远程URL地址添加到容器的指定 <dest>路径下,指令包含两种形式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
-
ENV(构建指令)
设置环境变量,环境变量可被后面的指令使用,并在容器运行时保持。
格式:ENV <key> <value>
例如:
...
ENV PATH /usr/local/nginx/sbin:$PATH
ENV MY_VERSION 1.3
RUN apt-get install -y mypackage=$MY_VERSION
-
EXPOSE(设置指令)
格式:EXPOSE <port> [<port>/<protocol>...]
可以指定TCP或UDP,默认是TCP
告诉Docker服务器暴露的端口号,供互联系统使用。
在启动容器的时候如果使用-P,Docker主机自动分配一个端口和容器端口映射。
在启动容器的时候如果使用-p,则可以具体指定哪个宿主机端口和容器端口映射。
当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。我们会在容器网络部分详细讨论。
-
VOLUME(设置指令)
格式:VOLUME ["<mountpoint>"]
将文件或目录声明为 volume。使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。我们会在容器存储部分详细讨论。
-
WORKDIR(设置指令)
格式:WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)
为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。
-
RUN(构建指令)
在构建镜像过程中要指定执行的命令。
-
CMD(设置指令)
容器启动时运行指定的命令。
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。
-
ENTRYPOINT(设置指令)
设置容器启动时运行的命令。
Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。
-
USER
USER指令用于指定容器执行程序的用户身份,默认是root用户。
使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。
格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
示例:
USER www
原文链接:https://blog.csdn.net/m0_56342013/article/details/125671097
-
HEALTHCHECK
容器健康状况检查命令
语法有两种:
1. HEALTHCHECK [OPTIONS] CMD command
2. HEALTHCHECK NONE
第一个的功能是在容器内部运行一个命令来检查容器的健康状况
第二个的功能是在基础镜像中取消健康检查命令
[OPTIONS]的选项支持以下三种选项:
--interval=DURATION 两次检查默认的时间间隔为30秒,间隔(s秒、m分钟、h小时),从容器运行起来开始计时interval秒(或者分钟小时)进行第一次健康检查,随后每间隔interval秒进行一次健康检查;还有一种特例请看timeout解析。
--timeout=DURATION 健康检查命令运行超时时长,默认30秒,执行command需要时间,比如curl 一个地址,如果超过timeout秒则认为超时是错误的状态,此时每次健康检查的时间是timeout+interval秒。
--retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3
-
ARG构建参数
格式: ARG <参数名>[=<默认值>]
ARG构建参数和 ENV 的效果一样,都是设置变量。所不同的是, ARG 所设置的构建环境的变量,在将来容器运行时是不会存在这些变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。
ARG是唯一一个可用于FROM前的指令
ARG CODE_VERSION=latest
FROM busybox:${CODE_VERSION}
-
LABEL(lable)
给镜像添加信息。使用docker inspect可查看镜像的相关信息
语法:
LABEL <key>=<value> <key>=<value> ......
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用符号
如下:
LABEL multi.label1="value1"
multi.label2="value2"
other="value3"
说明:LABEL会继承基础镜像中的LABEL,如遇到key相同,则值覆盖
7、docker 数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性: - 数据卷可以在容器之间共享和重用 - 对数据卷的修改会立马生效 - 对数据卷的更新,不会影响镜像 - 数据卷默认会一直存在,即使容器被删除 Docker中提供了两种挂载方式,-v和-mount
Docker的镜像是由一系列的只读层组合而来,当启动一个容器的时候,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题。
容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便的对容器中的文件进行访问
多个容器之间的数据无法共享
当删除容器时,容器产生的数据将丢失
为了解决这些问题,Docker引入了数据卷(volume)机制。volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利。
volume在容器创建时就初始化,在容器运行时就可以使用其中的文件
volume能在不同的容器之间共享和重用
对volume中的数据的操作会马上生效
对volume中数据操作不会影响到镜像本身
volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除
数据卷的使用
- 创建数据卷
docker volume create mydata
- 查看所有数据卷
docker volume ls
- 查看数据卷信息
docker volume inspect mydata
8、对 Kubernetes 的了解程度
Kubernetes是Google公司在2014年6月开源的一个容器集群管理系统,使用Go语言开发,也叫K8S。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。**Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着(**比如用户想让apache一直运行,用户不需要关心怎么去做,Kubernetes会自动去监控,然后去重启,新建,总之,让apache一直提供服务),管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提升工具以及人性化方面,让用户能够方便的部署自己的应用。
最后写了道题:二叉树右视图