拿到 Offer 了才知道,这家公司年终奖只有几百块~
我也挠头了
最近又有不少粉丝上岸了,其中一位分享的事情比较有意思,和你分享一下:
以后你对比 Offer 的时候也可以多个经验。
事情是这样的:
他在经过 2 个多月空窗期之后终于拿到了 Offer,月薪涨幅不大,但是有绩效考核,绩效好的话年终奖还是不错的。于是这哥们就查了一下这家公司的年终奖。
不查不知道,一查吓一跳,正好查到了网上上的热点:传天 X 信年终奖打折,到账几百块。
他还给我发了几个热帖评论。
网友一: 天 X 信的年终奖,确实在闹笑话,一年累死累活到头来 0 年终。
网友二: 话说今年安全公司哪家发年终奖了??
网友三: 啥?年终奖 200 块,你嫌弃少啊,给你就不错了,这的那的~
上市公司天 X 信发放年终奖,人均几百元,我擦,牛不牛;员工觉得这是侮辱啊;什么努力奋进,什么归属感,什么目标责任感,钱呢?钱呢?
要不要去?
问我要不要去?去的话月薪涨幅不大,想靠绩效年终奖找补,但是又不稳~
不去的话,已经找了俩月了,已经身心疲惫了,也不确定后面还能不能找到更好的。
大家觉得这哥们是选择入职?还是继续找更好的?
我在 公众号 发起的投票如下:
来吃瓜的你又有什么想说的呢?欢迎在评论区留言讨论!
我也和这位朋友问了下,有没有整理面经,也好和大家分享一下,答案是没有,哈哈。
总结复盘面经还是灰常重要的!我建议他如果继续找,后面可得做总结复盘!
下面给大家分享一些 Go 后端面试必须掌握的、特别基础的知识点:
常考面试题
01 = 和 := 的区别?
=是赋值变量,:=是定义变量。
02 指针的作用
一个指针可以指向任意变量的地址,它所指向的地址在 32 位或 64 位机器上分别固定占 4 或 8 个字节。指针的作用有:
获取变量的值
改变变量的值
用指针替代值传入函数,比如类的接收器就是这样的。
03 Go 允许多个返回值吗?
可以。通常函数除了一般返回值还会返回一个 error。
04 Go 有异常类型吗?
有。Go 用 error 类型代替 try...catch 语句,这样可以节省资源。同时增加代码可读性:
也可以用 errors.New()来定义自己的异常。errors.Error()会返回异常的字符串表示。只要实现 error 接口就可以定义自己的异常,
05 什么是协程(Goroutine)
协程是用户态轻量级线程,它是线程调度的基本单位。通常在函数前加上 go 关键字就能实现并发。一个 Goroutine 会以一个很小的栈启动 2KB 或 4KB,当遇到栈空间不足时,栈会自动伸缩, 因此可以轻易实现成千上万个 goroutine 同时启动。
06 ❤如何高效地拼接字符串
拼接字符串的方式有:+
fmt.Sprintf
, strings.Builder
, bytes.Buffer
, strings.Join
+
使用+操作符进行拼接时,会对字符串进 行遍历,计算并开辟一个新的空间来存储原来的两个字符串。
fmt.Sprintf
由于采用了接口参数,必须要用反射获取值,因此有性能损耗。
3 strings.Builder
用 WriteString()进行拼接,内部实现是指针+切片,同时 String()返回拼接后的字符串,它是直接把[]byte 转换为 string,从而避免变量拷贝。
4 bytes.Buffer
bytes.Buffer 是一个一个缓冲 byte 类型的缓冲器,这个缓冲器里存放着都是 byte,
bytes.buffer 底层也是一个[]byte 切片。
5 strings.join
strings.join 也是基于 strings.builder 来实现的,并且可以自定义分隔符,在 join 方法内调用了 b.Grow(n)方法,这个是进行初步的容量分配,而前面计算的 n 的长度就是我们要拼接的 slice 的长度,因为我们传入切片长度固定,所以提前进行容量分配可以减少内存分配,很高效。
性能比较:
5 种拼接方法的实例代码:
答疑
在 Go 语言中,strings.Builder
的性能通常比bytes.Buffer
好,主要有以下几个原因:
零拷贝:
strings.Builder
在内部使用了可变长度的[]byte
切片来存储字符串,而bytes.Buffer
使用了固定长度的[]byte
切片。当进行字符串拼接时,strings.Builder
可以直接修改切片中的内容,而不需要进行额外的内存分配和拷贝操作,从而避免了不必要的性能开销。预分配内存:
strings.Builder
在初始化时会预分配一定大小的内存空间,避免了频繁的内存分配和释放操作。这样可以减少内存分配的次数,提高性能。字符串连接优化:
strings.Builder
提供了WriteString
方法,可以直接将字符串追加到内部的[]byte
切片中,而不需要进行类型转换和拷贝操作。这样可以减少不必要的中间步骤,提高字符串连接的效率。
需要注意的是,strings.Builder
和bytes.Buffer
都是用于字符串拼接和缓冲的类型,选择使用哪个取决于具体的需求和场景。如果需要频繁进行字符串拼接操作,尤其是在循环中,strings.Builder
通常会更高效。而如果只是简单的缓冲操作,bytes.Buffer
也可以满足需求。
总结来说,strings.Builder
的性能比bytes.Buffer
好,主要是因为它采用了零拷贝、预分配内存和字符串连接优化等技术,避免了不必要的内存分配和拷贝操作,提高了字符串拼接的效率。
07 什么是 rune 类型
ASCII 码只需要 7 bit 就可以完整地表示,但只能表示英文字母在内的 128 个字符,为了表示世界上大部分的文字系统,发明了 Unicode, 它是 ASCII 的超集,包含世界上书写系统中存在的所有字符,并为每个代码分配一个标准编号(称为 Unicode CodePoint),在 Go 语言中称之为 rune,是 int32 类型的别名。
Go 语言中,字符串的底层表示是 byte (8 bit) 序列,而非 rune (32 bit) 序列。
08 如何判断 map 中是否包含某个 key ?
09 Go 支持默认参数或可选参数吗?
不支持。但是可以利用结构体参数,或者...
传入参数切片数组。
10 defer 的执行顺序
defer 执行顺序和调用顺序相反,类似于栈后进先出(LIFO)。
defer 在 return 之后执行,但在函数退出之前,defer 可以修改返回值。下面是一个例子:
上面这个例子中,test 返回值并没有修改,这是由于 Go 的返回机制决定的,执行 Return 语句后,Go 会创建一个临时变量保存返回值。如果是有名返回(也就是指明返回值func test() (i int)
)
这个例子中,返回值被修改了。对于有名返回值的函数,执行 return 语句时,并不会再创建临时变量保存,因此,defer 语句修改了 i,即对返回值产生了影响。
早日上岸!
我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。
没准能让你能刷到自己意向公司的最新面试题呢。
感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。
版权声明: 本文为 InfoQ 作者【王中阳Go】的原创文章。
原文链接:【http://xie.infoq.cn/article/553511917a8c8c6adc8e78391】。文章转载请联系作者。
评论 (1 条评论)