【Go】Go语言面试②

  • List item

文章目录

一、蜂,视频面试

https://zhuanlan.zhihu.com/p/77425984

http里的cookie 和session✅

HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务端的链接就会关闭,再次交换数据需要建立新的链接。这就意味着服务器无法从链接上面跟踪会话。

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再次请求该网站时,浏览器把请求的网址连同该Cookie一同发送给服务器。服务器检查该Cookie,以此来辨别用户状态。服务器还可以根据需要修改Cookie的内容

Cookie通过在客户端记录信息确定用户身份,Session通过在服务器记录确定用户身份

Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

如果说Cookie机制是通过检查客户身上的"通行证"来确定客户身份的话,那么Session就是通过检查服务器上的"客户明细表"来确认身份。Session相当于程序在服务器上建立的一份客户档案,客户来访时只需要检查客户的档案表就可以了

数据库有没有做切分✅

上来就问我简历里的项目(oj),数据库有没有做切分,我说暂时没有做,because目前数据量还没有达到要分库分表的地步,问了是垂直切分还是水平切分,以及水平切分后数据库如何访问
https://www.cnblogs.com/756623607-zhang/p/6850912.html

1)垂直分表

也就是“大表拆小表”,基于列字段进行的。一般是表中的字段较多,将不常用的, 数据较大,长度较长(比如text类型字段)的拆分到“扩展表“。一般是针对那种几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。

垂直切分解决了什么问题
垂直切分可以降低单节点数据库的负载。原来所有数据表都放在一个数据库节点上,无疑所有的读写请求也都发到这个MySQL上面,所以数据库的负载太高。如果把一个节点的数据库拆分成多个MySQL数据库,这样就可以有效的降低每个MySQL数据库的负载。

垂直切分不能解决什么问题
垂直切分不能解决的是缩表,比如说商品表无论划分给哪个数据库节点,商品表的记录还是那么多,不管你把数据库垂直拆分的有多细致,每个数据表里面的数据量是没有变化的。

2)水平分表

1)按照某种特定的规则来进行切分。

1.某个数字类型字段基于特定数目取余数
2.某个时间类型字段的范围
3.某个字符类型字段的hash值。

2)使相关的数据进行切分之后尽量存放在相同的数据库中,即使是需要join查询,也可以非常简单的关联上,在数据库层面上就可以进行关联查询。

水平切分的优点

◆ 表关联基本能够在数据库端全部完成;

◆ 不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;

◆ 应用程序端整体架构改动相对较少;

◆ 事务处理相对简单;

◆ 只要切分规则能够定义好,基本上较难遇到扩展性限制;

水平切分的缺点

◆ 切分规则相对更为复杂,很难抽象出一个能够满足整个数据库的切分规则;

◆ 后期数据的维护难度有所增加,人为手工定位数据更困难;

◆ 应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难。

但是也不是所有的数据表都要做水平切分。数据量较大的数据表才需要做数据切分,比如说电商系统中的,用户表、商品表、产品表、地址表、订单表等等。有些数据表就不需要切分,因为数据量不多,比如说品牌表、供货商表、仓库表,这些都是不需要切分的。

3)垂直分库

垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Producet一个库,订单Order一个库。切分后,要放在多个服务器上,提高性能。

4)水平分库分表

将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。

why database index is so fast ✅

https://www.cnblogs.com/xxiaoye/p/3679899.html

首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。

添加索引的话,首先去索引列表中查询,而我们的索引列表是B类树的数据结构,查询的时间复杂度为O(log2N),定位到特定值得行就会非常快,所以其查询速度就会非常快。

nginx引用 配置文件。

go goroutine。

go interface.

init函数能被外部调用吗(不能)

go中多个defer的执行顺序。✅

defer的执行顺序为:后defer的先执行。
defer的执行顺序在return之后,但是在返回值返回给调用方之前,所以使用defer可以达到修改返回值的目的。

select的用法,加上default又会怎么样?✅

select对应的每个case如果有已经准备好的case 则进行chan读写操作;若没有则执行defualt语句;
若都没有则阻塞当前goroutine,直到某个chan准备好可读或可写,完成对应的case后退出。

快排,归并排序的原理。

socket编程,(说了bind,listen,received,但是面试官不太满意)。

二、晓黑板教育,电话面试

进程、线程、协程是什么,区别

定义
进程:操作系统资源分配的基本单位,分了一块内存资源,有自己独立的虚拟cpu等,由操作系统进行调度。

线程:基于进程,进程中最小的执行单元,有自己的堆栈区;同一进程中的线程可共享进程的存储、io资源,由而线程是任务调度和执行的基本单位。

协程:程序控制和调度的,更轻量。(可以理解为协程是用来并发执行函数的)

区别

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。

包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

我说协程更轻量,切换起来快,(给自己埋坑),面试官又问为什么协程更轻,直接挂了

堆、栈、队列之间的区别是?

①堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。

②栈就是一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来。(后进先出)

③队列只能在队头做删除操作,在队尾做插入操作.而栈只能在栈顶做插入和删除操作。(先进先出)

注意:其实堆栈本身就是栈,只是换了个抽象的名字。

堆栈的特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列。 堆栈中定义了一些操作。
两个最重要的是PUSH和POP。 PUSH操作在堆栈的顶部加入一 个元素。POP操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一。

什么是用户态/内核态,

直接懵逼,说了一下nginx里有个参数 sendfile就是直接把文件直接copy到用户态,避免再从内核态到用户态的复制

对docker 的理解

数据库索引为什么这么快

 索引就是通过事先排好序,从而在查找时可以应用二分查找等高效率的算法。
 
 一般的顺序查找,复杂度为O(n),而二分查找复杂度为O(log2n)。当n很大时,二者的效率相差及其悬殊

tcp三次握手?

这个要想记住自己的name一样,记劳,只要是面试就会问,上一个例外)

tcp为什么是可靠?

我就拿上一个问题回答了,因为三次握手,所有就“可靠”,现在回想起来。。。。(脸都丢尽了,去百度一下就知道原因了)

是否对微服务和分布式有了解?

 分布式是指将不同的业务分布在不同的地方。而集群指的是将几台服务器集中在一起,实现同一业务。 分布式中的每一个节点,都可以做集群。而集群并不一定就是分布式的。
 

==简单说,分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。==

微服务的设计是为了不因为某个模块的升级和BUG影响现有的系统业务。微服务与分布式的细微差别是,微服务的应用不一定是分散在多个服务器上,他也可以是同一个服务器
  • load balance
    • 客户端层->反向代理层】的负载均衡
      是通过“DNS轮询”实现的:DNS-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问DNS-server,会轮询返回这些ip,保证每个ip的解析概率是相同的。这些ip就是nginx的外网ip,以做到每台nginx的请求分配也是均衡的。
    • Nginx均衡负载
      轮训、带权重的轮训、hash_ip

三、pop im(早安科技),电话面试

http cookies 和session,以及cookies是如何存储到浏览器的,

这里我一直不懂面试官的意图,最后,幡然醒悟,说在response的header里有有个set-cookies字段,告知浏览器,存储cookies,面试官听到了满意答案,很满意。

redis的五种数据结构

redis内存满了怎么办,我说都设了expire time,所以就。。

mysql索引有哪些以及索引 why fast?我又扯出来一个hash索引,结果,他又问我怎么实现的,结果我又又扯出来了B树,(面试官也笑了)于是,你懂得。。当然,最后都答出来了。

ngxin的负载均衡,

我刚开始谈到了master-worker模型,面试官不太满意,说和具体的逻辑业务关系?幡然醒悟,就是多加几个 backend server 以及负载均衡算法(轮训,权重轮训,hash_ip等)

websocket是否了解?

快排描述?

算法题:?

给定一个链表如何判断一个有环(巧极了,昨天刚看了,这里要感谢盖哥),具体做法就是用两个pointer,一个快,一个慢,判断两个pointer 是否重合。

go的goroutine ,如何停止一个goroutine?

有点懵逼,(其实我觉的面试官的意思是如何控制goroutine的退出,可以用channel和Contex,Select,sync.waitGroup)

goroutine泄露,或是内存泄漏?

go 里的slice 和array 的区别

slice的底层就是array,但是slice可以动态扩容,另外还有两个属性,len和cap

三- 2、pop im(二面)(广州),zoom视频面试

python里的装饰器,原理(闭包),用法

除了nginx的负载均衡以外的负载均衡用法,没太懂面试管的意思,他说在nginx之前或之后都可以load balance,我本来想说getway来着,最后也没说出口。

线程切换(我只扯到了寄存器。。。)??

什么是上下文切换?

主要是CPU通过给每个线程分配CPU时间片来实现多线程的任务,当一个任务的时间片用完,就会切换到另一个任务。在切换之前会保存上一个任务的状态,当下次再切换到该任务,就会加载这个状态。
——任务从保存到再加载的过程就是一次上下文切换。

时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程时同时执行的,时间片一般是几十毫秒(ms)。

切出: 一个线程被剥夺处理器的使用权而被暂停运行
切入: 一个线程被系统选中占用处理器开始或继续运行

在这里插入图片描述

进程与线程上下文切换最主要的区别?

就是线程的切换虚拟空间内存是相同的(因为都是属于自己的进程),但是,进程切换的虚拟空间内存则是不同的。

线程上下文切换比进程上下文切换快的多。

项目部署发布的过程

提交到gitlab,merge request
根据你提交的branch做CI pipeline
最后cd 到k8s及集群中

项目里的websocket的用法,假如是异常关闭怎么办?

我说后端对正常和异常关闭的连接一视同仁,我只能keep listening

https的建立过程???(说的我都不知道是什么,公钥,证书,tcp三次握手扯了一下)

http2了解吗?(并行)?

go interface?

如果流量激增,如何应对?✅

  • 前端: 按钮
  • 网关: ip黑名单
  • 后端:消息中间件、缓存、静态页面、漏斗等算法、集群高可用

给定一个长度为n的数组,让求第K大的数?

我说用维护最小堆,以及最小堆如何维护的(之前看了很多遍,本来以为是要撸代码,就差把剑指offer吃了,结果还是问问题,白准备and紧张了三天)

三- 3 pop im三面(技术负责人面)视频面

项目经历,那个部分让我提高了能力以及遇到的问题

mysql里用到的优化✅

一、EXPLAIN、最左原则

二、SQL 语句中 IN 包含的值不应过多 
  MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了;再或者使用连接来替换。

三、SELECT语句务必指明字段名称
  SELECT*增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。

四、当只需要一条数据的时候,使用limit 1
  这是为了使EXPLAIN中type列达到const类型

五、如果排序字段没有用到索引,就尽量少排序

六、如果限制条件中其他字段没有索引,尽量少用or
  or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”会得到更好的效果。

七、尽量用 union all 代替 union
  union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,union all的前提条件是两个结果集没有重复数据。

八、不使用ORDER BY RAND()

项目语言占比

Python 50% + Go 30% + Ts 20%

手撸代码:给定一个数字,求是否是回文数?

package main

import (
	"fmt"
	"strconv"
)

func Process(num int)  {
	strNum := strconv.Itoa(num)
	for i := 0; i < len(strNum)/2; i++ {
		j := len(strNum ) -1
		if strNum[i] != strNum[j]{
			fmt.Printf("不是回文数")
			return
		}
		j--
	}
}

func main() {
	var num int = 54321
	Process(num)
}

三-4 pop im(四面) HR面

平常遇到问题,都是通过什么途径解决的,

百度,Google

关于他们的产品

四: 格,电话面试

简单说一下自己学的东西

协程 goroutine的调度实现?

我说了M-G-P模型,面试官较为满意

redis 的五种数据结构

redis为什么这么快,我说了(内存,单线程避免切换,最后才是大头,多路复用IO的底层原理,就是epoll)

epoll的源码有没有看过?

socket编程?

问了了解的web framework

Flask、Django、Gin、Beego、Micro

五、春招 畅 2020-03-06

一面(passed)

go init 的执行顺序,注意是不按导入规则的

(这里是编译时按文件名的顺序执行的)
interface nil 比较

原生map非线程安全,加锁以及sync.Map{}的实现

channel no buffer以及buffer的区别

如何删除slice中间的元素

(s = append(s[:i],s[i+1,]…),其实就是切片的应用,i think)

怎么保存在程序崩溃时的数据?✅

当时没理解到,我觉得是(defer+reciver)

func test()  {
	//使用 defer + recover
	defer func() {
		//捕获test抛出的panic
		if err := recover();err!=nil{
			fmt.Println("test发生错误",err)
		}
	}()
	//定义一个map
	var myMap map[int]string
	myMap[0] = "golang" //error
}

func main() {
	go test()

	for i := 0; i < 10; i++ {
		fmt.Println("main() ok=",i)
		time.Sleep(time.Second)
	}
}

go实现一个SQL Pool ⏰

(可以借鉴database/sql pool的实现)

https://zhuanlan.zhihu.com/p/149521227

go 怎么控制查询timeout (context)

常见方法

context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) // 指定时长超时结束
context.WithCancel(parent Context) (ctx Context, cancel CancelFunc) // 手动结束
context.WithDeadline(parent Context, d time.Time) (Context, CancelFunc) // 指定时间结束

Docker image、container的区别✅

https://www.cnblogs.com/baizhanshi/p/9655102.html

docker的整个生命周期有三部分组成:镜像(image)+容器(container)+仓库(repository);

docker 的镜像概念类似虚拟机的镜像。是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。(
docker create <image -id > :为指定的镜像添加一个可读写层,构成一个新的容器;)

docker利用容器来运行应用:docker容器是由docker镜像创建的运行实例。docker容器类似虚拟机,可以执行包含启动,停止,删除等。每个容器间是相互隔离的。容器中会运行特定的运用,包含特定应用的代码及所需的依赖文件。可以把容器看作一个简易版的linux环境(包含root用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。

mysql的主从备份

less more 以及linux 中如何查看日志中某一行的数据 (sed)?

总结:

基础,基础,基础,计算机原理基础,操作系统,还有重要到天的tcp网络,数据库索引,redis,socket编程,算法就是快排保底,其余的知道的越多越好,绝不让你后悔。

六、易鲸×(一面)2020-04-02

Python和Go的区别✅

1.golang可读性很强,与或对应&&, ||这也使得golang看起来更像传统编程语言,而不是python的or,and
2.很难修改字符串,需要的话就重排吧
3.字符串经常需要在string和[]byte之间来回转换,数字转字符串必须用strconv
4.if,else,elif必须和配对的 { 在同一行
5.无时无刻不在使用自定义的struct,初始化结构体要用,json转成数据结构也要用,如果json转成的是复合结构还要嵌套struct,很多时候strcut来当python中的map用
6.定义type test struct,想得到一个test的数组,要使用[]*test,而不是[]test
7.struct及其里面的元素的首字母要大写,不然很可能访问不到
8.golang的map比python难用多了,没有dict.keys(),没有dict.values(),想把map转成别的结构只能遍历map
9.声明并赋值使用:=
10.没有set,没有tuples,要经常使用slices
11.没有__getattr,要经常检查是否存在
12.引用的包,声明的变量必须都的使用,不然编译都无法通过
13.数组没有[:-1]、[::-1]、a,b,c=[1,2,3]这些灵活的用法
14.如果能确定函数返回的类型,就不要用interface{},哪怕结构很复杂,也要使用strcut来返回。如果返回interface{},那么string(),for遍历这些基础用法都没法使用了
15.空指针是nil,python中的None在golang用nil代替,经常写err != nil判断是否出错

rust的了解

Flask与Django区别✅

django提供了:

django-admin快速创建项目工程目录
manage.py管理项目工程
orm模型(数据库抽象层)
admin后台管理站点


而这些,flask只有路由,其他都需要扩展包来提供

Flask框架的核心就是Werkzeug和Jinja2。

Flask扩展包:

Flask-SQLalchemy:操作数据库;
Flask-migrate:管理迁移数据库;
Flask-Mail:邮件;
Flask-WTF:表单;
Flask-script:插入脚本;
Flask-Login:认证用户状态;
Flask-RESTful:开发REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和时间;

Flask与Django区别总结

Django有自己的模板和路由和orm,没有服务,使用的是wsgiref。
flask 只有自己的路由,模板使用jinja2。
Orm使用的是flask-sqlalchemy 模块。
flask是轻量级框架,只封装了核心功能(路由),使用比较灵活

go的oop与传统的oop的区别

go的继承 多态

数据库索引

mysql隔离等级

数据库的架构

七、伴×(一面挂)

mvcc

幻读

B+ B树的区别

四次挥手

close_wait过多

算法题(接雨水)

七、×米(一面)

针对项目(api安全,)

如何保证外网开放接口的安全性。
使用加签名方式,防止数据篡改
信息加密与密钥管理
搭建OAuth2.0认证授权
使用令牌方式
搭建网关实现黑名单和白名单

redis挂了怎么办?

Redis 持久化

RDB vs AOF
RDB与AOF两种方式各有优缺点。

RDB的优点:与AOF相比,RDB文件相对较小,恢复数据比较快(原因见数据恢复部分)
RDB的缺点:服务器宕机,RBD方式会丢失掉上一次RDB持久化后的数据;使用bgsave fork子进程时会耗费内存。

AOF的优点:AOF只是追加文件,对服务器性能影响较小,速度比RDB快,消耗内存也少,同时可读性高。
AOF的缺点:生成的文件相对较大,即使通过AOF重写,仍然会比较大;恢复数据的速度比RDB慢。

数据库的恢复
服务器启动时,如果没有开启AOF持久化功能,则会自动载入RDB文件,期间会阻塞主进程。如果开启了AOF持久化功能,服务器则会优先使用AOF文件来还原数据库状态,因为AOF文件的更新频率通常比RDB文件的更新频率高,保存的数据更完整。

持久化方案的建议
如果Redis只是用来做缓存服务器,比如数据库查询数据后缓存,那可以不用考虑持久化,因为缓存服务失效还能再从数据库获取恢复。
如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。如果你可以接受灾难带来的几分钟的数据丢失,那么可以仅使用RDB。
通常的设计思路是利用主从复制机制来弥补持久化时性能上的影响。即Master上RDB、AOF都不做,保证Master的读写性能,而Slave上则同时开启RDB和AOF(或4.0以上版本的混合持久化方式)来进行持久化,保证数据的安全性。

mysql 各种引擎的区别

B+以及B树的区别

回表
索引建立的注意事项

go gc(三色)、go 调度模型

go slice 与arrary的区别以及扩容机制

go 如何关闭goroutine

进程与线程的区别、进程切换的过程

tcp的可靠性、tcp与udp的区别

linux的查看进程,网络,磁盘,内存的命令

(二面)

算法题(好多牛牛,dp)

平常怎么学习,下一步的打算,准备学什么东西

select count(*)在mysql的引擎中那个最快

https://www.cnblogs.com/jamaler/p/12579416.html

在 MyISAM 存储引擎中,把表的总行数存储在磁盘上,当执行 select count(*) from t 时,直接返回总数据。

在 InnoDB 存储引擎中,跟 MyISAM 不一样,没有将总行数存储在磁盘上,当执行 select count(*) from t
时,会先把数据读出来,一行一行的累加,最后返回总数量

b树与b+树那个查找效率最高

topK,100万,找钱100,(minheap,quick sort)

反转字符串

2.1

2.2

八、2019秋招 | golang的面经 秋招总结 三(字节跳动、映客直播)

https://zhuanlan.zhihu.com/p/51220836

趣丸(一面)

趣丸的面试难度堪比bat,但是薪水偏低了

为什么选pg

go怎么从源码编译到二进制文件

go的调度模型

go的锁如何实现,用了什么cpu指令

go的runtime如何实现

二面

c++的map和go的map的区别(红黑树和hashtable)

ctx包了解吗?有什么用??

go什么情况下会发生内存泄漏?(他说ctx没有cancel的时候,这个真不知道)??

怎么实现协程完美退出??

智力题:1000瓶酒中有1瓶毒酒

1000瓶酒中有1瓶毒酒,10只老鼠,7天后毒性才发作,第8天要卖了,怎么求那瓶毒酒?

简单dp题,n*n矩阵从左上角到右下角有多少种走法(只限往下和往右走)

九、映客直播

映客是京东开奖那段时间投的补招,他们公司用的golang也挺多,可惜也是北京,薪水比京东好一点

9.2 二面

用channel实现定时器?(实际上是两个协程同步)

channel的实现?不了解

go为什么高并发好?讲了go的调度模型

git回滚

看什么书,怎么学习

redis的zset用什么实现,除了跳跃表

操作系统内存管理?进程通讯,为什么共享存储区效率最高

http的状态码

tcp和udp

udp的头部

http和tcp的关系

9.3 三面

怎么看一本书?
如果团队有一个人的任务做不完,你也很忙,你会怎么做?

十、Ucloud

Ucloud是做服务器的,跟七牛云很像,但Ucloud主要是C++,七牛云主要是golang。一面完说通过,约二面,后面说那周深圳的总监没空,调下周,后面没消息,估计凉凉了

10.1 一面

实现一个hashmap,解决hash冲突的方法,解决hash倾斜的方法

c++的模板跟go的interface的区别

怎么理解go的interface

100亿个数选top5,小根堆

十一、字节跳动

头条很早就笔试了,A了一道多,刚好赶上补招,给面试,拖了几周担心拖不了就面试了,面试中也有一些不会的,不过三面后加hr微信问过没过,hr说过了,第二天跟我联系,然后就担心没有部门捞(头条三面通过要有部门要才有offer),第二天就谈薪资收到offer了

11.1 一面

go代码运行结果(闭包函数)

git和svn区别,模型

唯一订单号问题,并发量高的话怎么解决

方案一:
如果存在并发,且订单号是由一个进程中的多个线程产生的,那么只要把线程ID添加到序列号中就可以保证订单号唯一。
如果存在并发,且订单号是由同一台主机中的多个进程产生的,那么只要把进程ID添加到序列号中就可以保证订单号唯一。
如果存在并发,且订单号是由不同台主机产生的,那么MAC地址、IP地址或CPU序列号等能够区分主机的号码添加到序列号中就可以保证订单号唯一。

方案二:
时间戳+用户ID+几个随机数+乐观锁。

方案三:
用redis的原子递增,做好高可用集群。

方案四(非纯数字):
java自带uuid。

hash表设计要注意什么问题

数组和为n的数组对

最大连续子数组和

redis容灾,备份,扩容

跳跃表,为什么使用跳跃表而不使用红黑树

11.2 二面

输入url后涉及什么

答案

1、浏览器根据域名找到对应的 ip 地址(远程服务器)。

2、浏览器与远程服务器建立连接(tcp 连接,三次握手)。

3、浏览器与远程服务器发送和接收数据。

4、浏览器与远程服务器断开连接。

tcp怎么找到哪个套接字

ipc方式,共享存储区原理

进程虚拟空间布局

进程状态转换

线程的栈在哪里分配

多个线程读,一个线程写一个int32会不会有问题,int64呢(这里面试官后来说了要看数据总线的位数,32位的话写int32没问题,int64就有问题)

判断二叉树是否为满二叉树

lru实现

一个大整数(字符串形式表示的),移动字符求比它大的数中最小的

11.3 三面

MVC优点

点赞系统设计

12. 2019秋招 | golang的面经 秋招总结一 (七牛云、360、京东)

12.1 七牛云(一面)

七牛云的技术还是不错的,虽然实习不想去上海(建议实习不要看地点,实习很短不要介意地点)

go的调度

go struct能不能比较

go defer(for defer)

select可以用于什么

context包的用途

client如何实现长连接

主协程如何等其余协程完再操作✅

使用channel进行通信,context,select

select就是用来监听和channel有关的IO操作,当 IO 操作发生时,触发相应的动作。

//select基本用法
select {
case <- chan1:
// 如果chan1成功读到数据,则进行该case处理语句
case chan2 <- 1:
// 如果成功向chan2写入数据,则进行该case处理语句
default:
// 如果上面都没有成功,则进入default处理流程

slice,len,cap,共享,扩容

map如何顺序读取

实现set

实现消息队列(多生产者,多消费者)

大文件排序

基本排序,哪些是稳定的

http get跟header、http 401,403、keep-alive、能不能一次连接多次请求,不等后端返回

tcp与udp区别,udp优点,适用场景

time-wait的作用

数据库如何建索引✅

创建索引:ALTER TABLE testalter_tbl ADD INDEX (c);
删除索引:ALTER TABLE testalter_tbl DROP INDEX (c);
显示索引信息

SHOW INDEX FROM table_name\G

孤儿进程,僵尸进程

死锁条件,如何避免

linux命令,查看端口占用,cpu负载,内存占用,如何发送信号给一个进程

git文件版本,使用顺序,merge跟rebase

13. 360

360是秋招第一个面试的公司,在实习期间请假面试的,一天基本就面完所有流程,但最终还是进入备胎池(巨深),虽然也不想去北京,但还是点名批评360的备胎池

13.1 一面

一面是个小胖小胖的面试官,说我的实习经历挺丰富的(几个校内项目跟一个小公司实习项目),基本上问项目跟场景,中间穿插一些基础知识

讲实习项目的简单业务流程,数据库有水平拆分什么的吗?

Slice与数组区别,Slice底层结构

项目里的微信支付这块,在支付完微信通知这里,收到两次微信相同的支付通知,怎么防止重复消费(类似接口的幂等性),说了借助Redis或者数据库的事务

项目里的消息推送怎么做的(业务有关)

Go的反射包怎么找到对应的方法(这里忘记怎么问的,直接说不会,只用了DeepEqual,简单讲了DeepEqual)

Redis的List用过吗?底层怎么实现的?知道但是没用过,不知道怎么实现

Mysql的索引有几种,时间复杂度???

InnoDb是表锁还是行锁,为什么??

Go的channel(有缓冲和无缓冲)???

退出程序时怎么防止channel没有消费完?

这里一开始有点没清楚面试官问的,然后说了监听中断信号,做退出前的处理,然后面试官说不是这个意思,然后说发送前先告知长度,长度要是不知道呢?close channel下游会受到0值,可以利用这点(这里也有点跟面试官说不明白)

用过什么消息中间件之类吗?

13.2 二面

二面的面试官好像是部门技术总监,面完了加微信,可能需要Go的人,感觉很多不会然后给过了,面完面试官人超好,微信推荐我看书

生产者消费者模式,手写代码(

Go直接使用channel实现很简单,还想着面试官会不会不让用channel实现,不用channel的可以使用数组加条件变量),channel缓冲长度怎么决定,怎么控制上游生产速度过快,这里没说出解决方案,只是简单说了channel长度可以与上下游的速度比例成线性关系,面试官说这是一种解决方案

手写循环队列??

写的循环队列是不是线程安全,不是,怎么保证线程安全,加锁,效率有点低啊,然后面试官就提醒Go推崇原子操作和channel
写完代码面试官说后面问的问题回答就可以,不知道的话没关系

TimeWait和CloseWait原因??

线段树了解吗?不了解,字典树?了解

看过啥源码,nsq(Go的消息中间件),简单问了我里面的waitgroup包证明我看过

sync.Pool用过吗,为什么使用,对象池,避免频繁分配对象(GC有关),那里面的对象是固定的吗?

有什么问题吗?评价?

基础不错,Linux尚缺,Go的理解不够深入,高级数据结构不了解,优点是看源码
后面面试官讲了他们做的东西,主要是广告部分,说日均数据量至少百万以上,多达上亿,高并发使用Go支撑,有微服务,服务治理,说我需要学的东西挺多的

14. 京东

京东本来是现场面的,但运气好,几轮的面试官都允许改成电话面试,岗位是京东云部门的Golang开发工程师,很少有大公司明招golang,面试官说主要做docker和跟调度相关。收到offer后给三天的时间考虑,虽然非常想去京东,方向也非常感兴趣,最终还是希望跟女朋友留在深圳就放弃了京东的offer。

14.1 一面

单点登录,tcp粘包

项目

手写洗牌

14.2 二面

项目1处理粘包断包实现,面试官以为是negle算法有关,解释了下negle跟糊涂窗口综合征有关,然后面试官觉得其他项目是crud就没问了

看什么书?

以前看redis设计与实现之类的,现在看linux相关

goroutine调度用了什么系统调用

这个不会,面试官想从go问到操作系统,然后以为***作系统基础不好,就问了操作系统问题

进程虚拟空间分布,全局变量放哪里?

有没有网络编程,有,怎么看连接状态?netstat,有哪些?

ESTABLISHED,LISTEN等等,有异常情况吗?TIME_WAIT很多,为什么?大量短链接

14.3 HR面

优缺点

15. 京东

make new的区别

  • 3.1 make返回类型(引用类型),new 返回指针并初始化

通过make()命令创建的缓冲区被分配了一块内存后。如何销毁缓冲区并收回内存?

buffer = nil, 在运行时,buffer = nil将启动垃圾回收。

Go语言的引用类型

make ()能创建的类型包括:切片,map,管道,三者都是引用类型:。
Go语言的引用类型:

1.引用类型的值的内存分配是在堆中的,栈中使用一个地址指向之;

2.需要回收时,将栈中的指针/引用指向即可nil;

数组和切片的区别

  • 3.2 数组是值拷贝, 切片Slice是引用,

  • 数组长度不可变而切片可变(在运行时渴动态增加、减少切片的大小)

  • 数组

    var arr1 [3]int
    var arr2 [3]int = [3]int{1, 2, 3}
    fmt.Println(arr1)
    fmt.Println(arr2)
    
  • 切片(引用类型)

    // 创建一个整型切片
    // 其长度为 3 个元素,容量为 5 个元素
    slice := make([]int, 3, 5)
    
    // 创建字符串切片
    // 其长度和容量都是 3 个元素
    myStr := []string{"Jack", "Mark", "Nick"}
    // 创建一个整型切片
    // 其长度和容量都是 4 个元素
    myNum := []int{10, 20, 30, 40}
    

Go线程安全?

Go语言基础考核

16. 2020腾讯后端面试题

1、goalng相关

Q:context作用,原理,超时控制

A: golang context的理解,context主要用于父子任务之间的同步取消信号,本质上是一种协程调度的方式。另外在使用context时有两点值得注意:上游任务仅仅使用context通知下游任务不再需要,但不会直接干涉和中断下游任务的执行,由下游任务自行决定后续的处理操作,也就是说context的取消操作是无侵入的;

context是线程安全的,因为context本身是不可变的(immutable),因此可以放心地在多个协程中传递使用。

Q:channel关闭阻塞问题,goroutine如何调度,gopark是怎么回事?PMG模型描述,谁创建的PMG,runtime是怎么个东西,怎么启动第一个goroutine?

A: golang CPS并发模型和PMG模型的理解。

Q:go逃逸分析怎么回事,内存什么时候栈分配什么时候堆分配

R: 内存方面问题,这个网上很多,自己理解完整正确。

Q:sync.Map实现原理,适用的场景

A:go 1.9 官方提供sync.Map 来优化线程安全的并发读写的map。该实现也是基于内置map关键字来实现的。

这个实现类似于一个线程安全的 map[interface{}]interface{} . 这个map的优化主要适用了以下场景:

(1)给定key的键值对只写了一次,但是读了很多次,比如在只增长的缓存中;

(2)当多个goroutine读取、写入和覆盖的key值不相交时。

更进一步,可看sync.Map源码。

Q:go语言有什么优点和缺点

A: 优势:容易学习,生产力,并发,动态语法。
劣势:包管理,错误处理,缺乏框架。

Q:Go框架用过哪些,有看源码吗

A: 优势:beego,go-micro,gin等

Q:Go GC算法,三色标记法描述

A: 自己找,网上有

Q:Go内存模型(tcmalloc)

A:tcmalloc是线程缓存的malloc,实现了高效的多线程内存管理,用于替代系统的内存分配相关的函数

Q:行列都是有序的二维数组,查找k是否存在,时间复杂度

1 3 5 7 9

3 5 7 9 11

4 6 8 10 12

A:二分查找:O(log2(max(m,n)))

Q:有序数组,有2N+1个数,其中N个数成对出现,仅1个数单独出现,找出那个单独出现的数.,时间复杂度

1,1,2,2,3,4,4,5,5,6,6,7,7

答案为3

A: O(log2(2N))二分查找,查找中间位置的数相等值是在左边还是右边?左边则再左子数组继续查找,右边则在右子数组继续查找。

Q:100亿个数求top100,时间复杂度

A:分组查找或bitmap

Q:100亿个数和100亿个数求交集,时间复杂度

A: 全排列问题

两个整数数组各100亿条数据,已经排序,保存在磁盘上;内存10M,
1.如何取得交集?时间和空间效率分别是多少?
2.如果其中一个数组只有100条数据,如何优化算法取得交集?时间和空间效率分别是多少?

对于第一个问题,是比较容易处理的,可以借助归并排序的思路来解,只是需要判断两边的数是否相等就可以了,时间效率是O(n),空间复杂度是O(1)

复杂的是第二个小问题,100亿对100亿取交集时,可以借助归并排序的思路,但其中一个是100个元素时,这个问题就退化成了在1亿个有序元素中查找1个元素是否存在的问题,这种情况下应该使用二分查找

如果你想到了二分查找,我认为你已经接近答案了,接下来要注意的是,二分查找的范围

大数组的查找范围是可以不断缩小的,假设小数组为A,那么A[0]可以确定二分查找的起始位置,A[99]可以确定二分查找的结束位置,当查询A[1]时就可以借助A[0]和A[99]所确定的范围,查找A[98]时可以借助A[1]和A[99]
确定的范围

2、linux,操作系统

Q:Select/epoll,IO多路复用,底层数据结构,epoll的几个函数,两种模式

A: Select/epoll 问题,网上很多

Q:抢占式调度是什么回事

A: 进程优先级和时间分片等方面理解

Q:用户态和内核态,为什么要有用户态和内核态?

A: 系统态(内核态),操作系统在系统态运行——运行操作系统程序

用户态(也称为目态),应用程序只能在用户态运行——运行用户程序

内核态:cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。

用户态:只能受限的访问内存,且不允许访问外围设备,占用cpu的能力被剥夺,cpu资源可以被其他程序获取。

由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 – 用户态和内核态。

https://www.cnblogs.com/maxigang/p/9041080.html

3、mysql相关

Q:innodb和myisam区别(事务,索引,锁。。。)

InnoDB MyISAM
支持事务 不支持事务
支持外键 不支持外键
支持行锁 不支持行锁,支持表锁
写操作效率高 读操作效率高(执行大量读的操作,是很不错的选择)
支持全文索引 支持全文索引
表占用空间较小 表占用空间较大
聚集(主键)索引 非聚集索引

Q:B+树和B树区别,优缺点

A:B树每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为null。只有叶子节点存储data,叶子节点包含了这棵树的所有键值,叶子节点不存储指针,顺序访问指针,也就是每个叶子节点增加一个指向相邻叶子节点的指针。

Q:B树和二叉查找树或者红黑色区别

A:基础数据结构问题

Q:聚簇索引什么特点,为什么这样,顺序查询的实现,回表查询,联合索引特性

A:

聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据

非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因

使用聚集索引的查询效率要比非聚集索引的效率要高,但是如果需要频繁去改变聚集索引的值,写入性能并不高,因为需要移动对应数据的物理位置。
非聚集索引在查询的时候可以的话就避免二次查询,这样性能会大幅提升。
不是所有的表都适合建立索引,只有数据量大表才适合建立索引,且建立在选择性高的列上面性能会更好。

非聚集索引和聚集索引的区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据

Q:大表分页查询,10亿行数据,查找第N页数据,怎么优化

  • 避免 select *

  • 使用 id 限定优化

    这种方式假设数据表的id是连续递增的,则我们根据查询的页数和查询的记录数可以算出查询的id的范围,可以使用 id between and 来查询:

  • 数据引擎
    mysql 在300万条数据(myisam引擎)情况下使用 count(*) 进行数据总数查询包含条件(正确设置索引)运行时间正常。对于经常进行读取的数据我们建议使用myIsam引擎。

Q:悲观锁和乐观锁,mysql相关锁说一下

A:说下概念,其他网上找:

乐观锁( Optimistic Locking):对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,"乐观"的认为加锁一定会成功的,在最后一步更新数据的时候再进行加锁。

悲观锁(Pessimistic Lock):悲观锁对数据加锁持有一种悲观的态度。因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

MyISAM 中的查询为什么比 InnoDB 快?

在这里插入图片描述

4、redis

Q:几种数据结构(list,set,zset,geohash,bitmap)实现原理

A:网上找

Q:redis pipline(非原子性)

A:pipeline的作用是将一批命令进行打包,然后发送给服务器,服务器执行完按顺序打包返回。 pipeline是非原子性

Q:redis 事务

A: redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

Q:备份(aof/rdb)原理,哪些参数可调

A:RDB是根据指定的规则定时将内存中的数据备份到硬盘上,AOF是在每次执行命令后命令本身记录下来,所以RDB的备份文件是一个二进制文件,而AOF的备份文件是一个文本文件。至于调参,网上可找。

Q:网络模型

A:redis网络模型,网上找,需要理解。

Q:为什么单线程就能hold住几万qps

A:I/O复用,Reactor 设计模式

Q:热点key怎么处理

A:1、热key加载到系统内存中,直接从系统内存中取,而不走到redis层。

2、redis集群,热点备份分布到集群中,避免单台redis集中访问。

Q:一致性hash解决什么问题

A:redis集群和负载均衡

Q:redis集群(主从,高可用,扩展节点)

5、kafka相关

Q:消息是否按照时间有序,kafka分区的数据是否有序,如何保证有序

A:不保证按时间有序,主题在单个分区是有序的。

如何保证有序?kafka topic 只设置一个分区,或者producer将消息发送到指定分区

Q:Kafka为什么吞吐量高

A:

1)顺序读写
kafka的消息是不断追加到文件中的,这个特性使kafka可以充分利用磁盘的顺序读写性能,顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写。

2)零拷贝
利用Linux kernel"零拷贝(zero-copy)"系统调用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户态缓冲区”。

3)分区
kafka中的topic中的内容可以被分为多分区存在,每个分区又分为多个段,所以每次操作都是针对一小部分做操作,很轻便,并且增加并行操作的能力。

4)批量发送
kafka允许进行批量发送消息,producter发送消息的时候,可以将消息缓存在本地,等到了固定条件发送到kafka

等消息条数到固定条数,一段时间发送一次。

5)数据压缩
Kafka还支持对消息集合进行压缩,Producer可以通过GZIP或Snappy格式对消息集合进行压缩

压缩的好处就是减少传输的数据量,减轻对网络传输的压力

Q:kafka的存储模型

A:网上找。

Q:Kafka消费者多个group消费同一个topic,会重复消费吗?

A:不会。

6、算法和数据结构问题:

Q:hash算法实现(类似crc32或者murmur),保证随机性和均匀性,减少哈希冲突

A:考的是hash算法的了解,需要知道一些经典哈希算法实现。

7、动态规划相关

Q:100个球,一次只能拿2-5个,你先拿,我后拿,怎么保证你能拿到最后一个球

A:一次2-5,去掉先手,最后回合剩余7个即可保证拿到最后一个球。因此,先手拿2个,每一回合保证拿掉球的总数为7,即可。(100-2)/7=14回合。

Q:正整数数组,求和为sum的组合 换零钱,1,5,10元都很充足,给你N元去换零钱,多少种换法

A:算法题给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数,动态规划法。

Q:图的最短路径

A:网上找

8、项目问题

Q:遇到过内存溢出吗?怎么解决

A:主要了解有没有处理过内存泄漏导致的问题,C/C++定位内存泄漏问题;Golang和JAVA主要与GC的工作机制有关,堆内存一直增长,导致应用内存溢出等。

Q:布隆过滤器怎么设置m,n,k的值,怎么合理安排key(用户和item越来越多,怎么保证内存不会爆)

A:m,n,k 网上有实践经验,可参考。item越来越多的话,进行item的拆分,拆分本质是不要将 Hash(Key) 之后的请求分散在多个节点的多个小 bitmap 上,而是应该拆分成多个小 bitmap 之后,对一个 Key 的所有哈希函数都落在这一个小 bitmap 上。

Q:服务雪崩怎么处理,怎么解决保证不影响线上

A:限流,降级,熔断方面措施,结合后端系统架构阐述,如网关的限流和快速失败。

Q:redis和mysql数据一致性怎么保证

A:重点考虑业务逻辑上写和数据的流程(异常和错误处理等),结合MQ做异步重试处理。

Q:分布式锁应用场景,哪些坑

A:锁过期了,业务还没执行完;分布式锁,redis主从同步的坑;获取到锁后,线程异常。

散弹APP

golang中map类型的排序方法

map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。

package main

import "fmt"

func sortMapValue(mp map[string]int) {
	reverseMap := make(map[int][]string)

	for key, value := range mp {
		fmt.Println(key, value)
		reverseMap[value] = append(reverseMap[value], key)
	}
	fmt.Println("reverseMap:", reverseMap)
}

func main() {
	map1 := make(map[string]int)
	map1["Mon"]=1
	map1["Tue"]=5
	map1["Wed"]=3
	map1["Thu"]=4
	map1["Fri"]=2
	map1["Sat"]=6
	map1["Sun"]=7
	fmt.Println(map1)

	sortMapValue(map1)
}


map[Fri:2 Mon:1 Sat:6 Sun:7 Thu:4 Tue:5 Wed:3]
Wed 3
Thu 4
Fri 2
Sat 6
Sun 7
Mon 1
Tue 5
reverseMap: map[1:[Mon] 2:[Fri] 3:[Wed] 4:[Thu] 5:[Tue] 6:[Sat] 7:[Sun]]

方法二:sync.WaitGroup
Go 语言提供一个更简单的方式就是,sync.WaitGroup 来实现等待。

sync.WaitGroup 内部是实现了一个计数器,它有三个方法

Add() 用来设置一个计数 Done() 用来在操作结束时调用,使计数减1 Wait() 用来等待所有的操作结束,即计数变为0。

/*
@File : 用channel来实现同步
*/

package main

import (
   "fmt"
   "sync"
)


func printString(str string) {
   for _, data := range str {
      fmt.Printf("%c", data)
   }
   fmt.Printf("\n")
}

// 使用 sync.WaitGroup 的方式来实现主协程等待其他子协程
var wg sync.WaitGroup

var tongBu = make(chan int)

func person1() {
   printString("Gerald")
   tongBu <- 1
 
   wg.Done()
}

func person2() {
   <- tongBu
   printString("Seligman")

   wg.Done()
}

func main() {
   wg.Add(2)

   // 目的:使用 channel 来实现 person1 先于 person2 执行
   go person1()

   go person2()
   defer close(tongBu)

   wg.Wait()
}

redis mysql数据同步

延时双删策略

互斥锁Mutex和读写锁RWMutex

https://www.cnblogs.com/f-ck-need-u/p/9998729.html

  • Lock()和Unlock()用于申请和释放写锁
  • RLock()和RUnlock()用于申请和释放读锁
  • 一次RUnlock()操作只是对读锁数量减1,即减少一次读锁的引用计数
  • 如果不存在写锁,则Unlock()引发panic,如果不存在读锁,则RUnlock()引发panic
    RLocker()用于返回一个实现了Lock()和Unlock()方法的Locker接口

Mutex和RWMutex都不关联goroutine,但RWMutex显然更适用于读多写少的场景。仅针对读的性能来说,RWMutex要高于Mutex,因为rwmutex的多个读可以并存。

计算机

堆栈区

所谓堆栈区是程序要求系统为程序保留的固定尺寸的内存区域,尺寸大小由程序提出,属于编译选项。

存储区分为两部分:堆和栈

堆是一整片存储区,可以由程序使用,比如你在程序区中用malloc或new来申请存储区就是在堆中申请,如果堆满了,就申请失败;另外其他的子程序也会使用,比如printf,scanf也会在堆中临时申请内存存储输入输出的字符串

栈是一片存储区,由系统帮助管理,叫先进后出、后进先出存储区,这些存储区一般用于调用子程序时保存现场、保存参数、开设子程序变量,只要调用函数就会用到栈,只不过这些操作是c语言程序编译好后自动调用的,用户一般不会体会到它的使用,栈也会满,递归函数由于要出现大量调用函数的情况,尤其对栈的消耗很大。另外,嵌套循环也会用到栈。

对微服务的理解

https://www.zhihu.com/question/289101554/answer/838197119

Python

Python3 GIL下 多线程与多进程

应用:

多线程用于IO密集型,如socket,爬虫,web

多进程用于计算密集型,如金融分析

https://www.cnblogs.com/Xuuuuuu/p/10337079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值