写点什么

拿到 Offer 了才知道,这家公司年终奖只有几百块~

作者:王中阳Go
  • 2024-06-04
    北京
  • 本文字数:3866 字

    阅读完需:约 13 分钟

拿到Offer了才知道,这家公司年终奖只有几百块~

我也挠头了

最近又有不少粉丝上岸了,其中一位分享的事情比较有意思,和你分享一下:


以后你对比 Offer 的时候也可以多个经验。

事情是这样的:

他在经过 2 个多月空窗期之后终于拿到了 Offer,月薪涨幅不大,但是有绩效考核,绩效好的话年终奖还是不错的。于是这哥们就查了一下这家公司的年终奖。


不查不知道,一查吓一跳,正好查到了网上上的热点:传天 X 信年终奖打折,到账几百块。


他还给我发了几个热帖评论。


网友一: 天 X 信的年终奖,确实在闹笑话,一年累死累活到头来 0 年终。


网友二: 话说今年安全公司哪家发年终奖了??


网友三: 啥?年终奖 200 块,你嫌弃少啊,给你就不错了,这的那的~


上市公司天 X 信发放年终奖,人均几百元,我擦,牛不牛;员工觉得这是侮辱啊;什么努力奋进,什么归属感,什么目标责任感,钱呢?钱呢?

要不要去?

问我要不要去?去的话月薪涨幅不大,想靠绩效年终奖找补,但是又不稳~


不去的话,已经找了俩月了,已经身心疲惫了,也不确定后面还能不能找到更好的。


大家觉得这哥们是选择入职?还是继续找更好的?


我在 公众号 发起的投票如下:



来吃瓜的你又有什么想说的呢?欢迎在评论区留言讨论!


我也和这位朋友问了下,有没有整理面经,也好和大家分享一下,答案是没有,哈哈。


总结复盘面经还是灰常重要的!我建议他如果继续找,后面可得做总结复盘!


下面给大家分享一些 Go 后端面试必须掌握的、特别基础的知识点:

常考面试题

01 = 和 := 的区别?

=是赋值变量,:=是定义变量。

02 指针的作用

一个指针可以指向任意变量的地址,它所指向的地址在 32 位或 64 位机器上分别固定占 4 或 8 个字节。指针的作用有:


  • 获取变量的值


 import fmt  func main(){  a := 1  p := &a//取址&  fmt.Printf("%d\n", *p);//取值* }
复制代码


  • 改变变量的值


// 交换函数func swap(a, b *int) {        *a, *b = *b, *a}
复制代码


  • 用指针替代值传入函数,比如类的接收器就是这样的。


type A struct{}
func (a *A) fun(){}
复制代码

03 Go 允许多个返回值吗?

可以。通常函数除了一般返回值还会返回一个 error。

04 Go 有异常类型吗?

有。Go 用 error 类型代替 try...catch 语句,这样可以节省资源。同时增加代码可读性:


 _, err := funcDemo()if err != nil {    fmt.Println(err)        return}
复制代码


也可以用 errors.New()来定义自己的异常。errors.Error()会返回异常的字符串表示。只要实现 error 接口就可以定义自己的异常,


 type errorString struct {  s string }  func (e *errorString) Error() string {  return e.s }  // 多一个函数当作构造函数 func New(text string) error {  return &errorString{text} }package main
import ( "errors" "fmt")
func divide(a, b int) (int, error) { if b == 0 { //通过errors.New 可类似实现throw new Exception捕获异常 return 0, errors.New("division by zero") } return a / b, nil}
func main() { result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Result:", result) }
result, err = divide(10, 0) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Result:", result) }}
复制代码

05 什么是协程(Goroutine)

协程是用户态轻量级线程,它是线程调度的基本单位。通常在函数前加上 go 关键字就能实现并发。一个 Goroutine 会以一个很小的栈启动 2KB 或 4KB,当遇到栈空间不足时,栈会自动伸缩, 因此可以轻易实现成千上万个 goroutine 同时启动。

06 ❤如何高效地拼接字符串

拼接字符串的方式有:+ fmt.Sprintf, strings.Builder, bytes.Buffer, strings.Join


  1. +


使用+操作符进行拼接时,会对字符串进 行遍历,计算并开辟一个新的空间来存储原来的两个字符串。


  1. 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 的长度,因为我们传入切片长度固定,所以提前进行容量分配可以减少内存分配,很高效。


性能比较


strings.Join` ≈ `strings.Builder` > `bytes.Buffer` > `+` > `fmt.Sprintf
复制代码


5 种拼接方法的实例代码:


func main(){        a := []string{"a", "b", "c"}        //方式1:+        ret := a[0] + a[1] + a[2]        //方式2:fmt.Sprintf        ret := fmt.Sprintf("%s%s%s", a[0],a[1],a[2])        //方式3:strings.Builder        var sb strings.Builder        sb.WriteString(a[0])        sb.WriteString(a[1])        sb.WriteString(a[2])        ret := sb.String()        //方式4:bytes.Buffer        buf := new(bytes.Buffer)        buf.Write(a[0])        buf.Write(a[1])        buf.Write(a[2])        ret := buf.String()        //方式5:strings.Join        ret := strings.Join(a,"")}
复制代码

答疑

在 Go 语言中,strings.Builder的性能通常比bytes.Buffer好,主要有以下几个原因:


  1. 零拷贝:strings.Builder在内部使用了可变长度的[]byte切片来存储字符串,而bytes.Buffer使用了固定长度的[]byte切片。当进行字符串拼接时,strings.Builder可以直接修改切片中的内容,而不需要进行额外的内存分配和拷贝操作,从而避免了不必要的性能开销。

  2. 预分配内存:strings.Builder在初始化时会预分配一定大小的内存空间,避免了频繁的内存分配和释放操作。这样可以减少内存分配的次数,提高性能。

  3. 字符串连接优化:strings.Builder提供了WriteString方法,可以直接将字符串追加到内部的[]byte切片中,而不需要进行类型转换和拷贝操作。这样可以减少不必要的中间步骤,提高字符串连接的效率。


需要注意的是,strings.Builderbytes.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) 序列。


sample := "我爱GO"runeSamp := []rune(sample)runeSamp[0] = '你'fmt.Println(string(runeSamp))  // "你爱GO"fmt.Println(len(runeSamp))  // 4
复制代码

08 如何判断 map 中是否包含某个 key ?

var sampleMap map[int]intif _, ok := sampleMap[10]; ok {        ...} else {        ...}// sampleMap[10] 返回vlaue 和 bool
复制代码

09 Go 支持默认参数或可选参数吗?

不支持。但是可以利用结构体参数,或者...传入参数切片数组。


// 传入结构体参数struct Options {        concurrent bool}func pread(offset int64, len int64, o *Options) {        ...}// 这个函数可以传入任意数量的整型参数func sumN(nums ...int) int {    total := 0    for _, num := range nums {        total += num    }    return total}
复制代码

10 defer 的执行顺序

defer 执行顺序和调用顺序相反,类似于栈后进先出(LIFO)。


defer 在 return 之后执行,但在函数退出之前,defer 可以修改返回值。下面是一个例子:


func test() int {        i := 0        defer func() {                fmt.Println("defer1")        }()        defer func() {                i += 1                fmt.Println("defer2")        }()        return i}
func main() { fmt.Println("return", test())}// defer2// defer1// return 0
复制代码


上面这个例子中,test 返回值并没有修改,这是由于 Go 的返回机制决定的,执行 Return 语句后,Go 会创建一个临时变量保存返回值。如果是有名返回(也就是指明返回值func test() (i int)


func test() (i int) {        i = 0        defer func() {                i += 1                fmt.Println("defer2")        }()        return i}
func main() { fmt.Println("return", test())}// defer2// return 1
复制代码


这个例子中,返回值被修改了。对于有名返回值的函数,执行 return 语句时,并不会再创建临时变量保存,因此,defer 语句修改了 i,即对返回值产生了影响。

早日上岸!

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。


没准能让你能刷到自己意向公司的最新面试题呢。


感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。

发布于: 刚刚阅读数: 2
用户头像

王中阳Go

关注

靠敲代码在北京买房的程序员 2022-10-09 加入

【微信】wangzhongyang1993【公众号】程序员升职加薪之旅【成就】InfoQ专家博主👍掘金签约作者👍B站&掘金&CSDN&思否等全平台账号:王中阳Go

评论 (1 条评论)

发布
用户头像
经过2个多月空窗期之后终于拿到了Offer,月薪涨幅不大,但是有绩效考核,绩效好的话年终奖还是不错的。于是这哥们就查了一下这家公司的年终奖。不查不知道,一查吓一跳,正好查到了网上上的热点~
刚刚 · 北京
回复
没有更多了
拿到Offer了才知道,这家公司年终奖只有几百块~_golang_王中阳Go_InfoQ写作社区