当前位置: 首页 > news >正文

【go】简单问答八股,go的理解,接口,锁,channel

谈谈你对go的理解,与其他语言的优势与缺陷

  • 我认为go是一个非常务实的语言,语法简单直接,支持原生高并发,开发速度块,性能强于java,有接近c语言的执行效率(静态编译成机器码)部署简单高效。
  • go的缺陷:
    • 相较于c++不支持函数重载,宏,且GC在超低延迟系统(高频交易)比不过纯手控的c++
    • 错误处理繁琐,频繁if err ,不过go1.13之后引入了错误包装
    • 科学计算和AI领域go的第三方库不如java和python丰富

go的两个接口之间可以存在什么关系?

  • 2个接口有相同的方法列表,那么就是等价的,可以互相赋值
  • 接口可以嵌套

互斥锁与读写锁

  • 互斥锁读写都锁,读写锁,读锁锁写操作,写锁读写都锁
  • 读写锁适合读多写少,互斥锁适合写操作多
package mainimport ("fmt""sync""time"
)var (num = 0// lock = sync.Mutex{} // 使用互斥锁保护共享变量 50ms+lock = sync.RWMutex{} // 使用读写锁保护共享变量 100ms+
)func main() {start := time.Now()var wg sync.WaitGroup // 定义一个 WaitGroup,用于等待所有 goroutine 完成wg.Add(1) // 增加一个计数,表示有一个 goroutine 需要完成go func() {defer wg.Done() // 在 goroutine 完成时减少计数for i := 0; i < 100000; i++ {lock.Lock()num++lock.Unlock()}}()for i := 0; i < 100000; i++ {lock.Lock()num++lock.Unlock()}wg.Wait() // 等待所有 goroutine 完成fmt.Println(num)               // 打印最终的 num 值fmt.Println(time.Since(start)) // 打印程序运行耗时
}// 总结:读写锁适合读多写少
// 互斥锁适合写操作多

channel特点,需要注意什么

Channel 是 goroutine 之间主要通讯方式,通信通过 Channel 完成同步。

  • 类型安全
    一个 Channel 只能传递指定类型的数据,比如 chan int 只能放 int。

  • 分为有缓冲通道和无缓冲通道同步 or 缓冲

    • 无缓冲 channelmake(chan int)):
      • 发送和接收必须同步,发的人等收的人准备好才能发。
    • 有缓冲 channelmake(chan int, 10)):
      • 可以容纳一定数量的数据,发的人可以先存进去,缓冲满了才阻塞。
  • 阻塞性

    • 向 无缓冲channel 发送数据,如果没人接收,会阻塞。
    • 从 无缓冲channel 接收数据,如果没人发送,也会阻塞。
  • 关闭特性

    • close(chan) 可以关闭通道。
    • 关闭后不能再发送数据,但可以继续接收,直到读取完毕
    • 关闭后再次发送数据,会导致panic。关闭已经关闭的通道会panic。(对策:由发送方关闭channel,可通过sync.Once确保只关闭一次)
    • 关闭后接收数据,返回类型零值
  • 多路复用(select)

    • 可以用 select 语句同时等待多个 channel 的操作(类似多路监听)。
  • nil Channel行为

    • 发送到nil channel会永久阻塞

    • 从nil channel接收会永久阻塞

    • 关闭nil channel会panic

无缓冲的通道是同步的,有缓冲的通道是异步


例子
package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroup    // 等待组var ch chan int          // nil channelvar ch1 = make(chan int) // 创建无缓冲channelfmt.Println(ch, ch1)     // <nil> 0xc000086060wg.Add(1)                // 等待组的计数器+1go func() {// ch <- 15 // 如果给一个nil的channel发送数据会造成永久阻塞// <-ch // 如果从一个nil的channel中接收数据也会造成永久阻塞ret := <-ch1fmt.Println(ret)ret = <-ch1 // 从一个已关闭的通道中接收数据,如果缓冲区中为空,则返回该类型的零值fmt.Println(ret)wg.Done() // 等待组的计数器-1}()go func() {// close(ch1)// close(ch) 关闭nil channel会panicch1 <- 15  // 给一个已关闭通道发送数据就会包panic错误close(ch1) // 关闭一个已关闭的channel会panic}()wg.Wait() // 等待组的计数器不为0时阻塞
}

讲解go中new

  • new 用于为给定类型分配内存并进行零值初始化,并返回对应类型的指针

  • 和 make 不同,new 适用于所有类型,而 make 只适用于 slice、map 和 channel

  • new 只做零值初始化不会为内部数据结构做额外准备;而 make 则会初始化返回一个可用对象(不是指针)。

p := new(int)
// p是*int类型,指向一个值为0的int变量
  • 实际开发中,除了极少数需要明确指针的场景,更多是直接使用字面量 &T{} 来创建对象,所以 new 在 Go 中使用得比较

go中的make

  • make 只用于 slice、map、channel

  • make 负责内存分配 + 内部数据结构初始化

  • 返回的是(不是指针)。


Printf、Sprintf、FprintF都是格式化输出,有什么不同?

  • Printf:格式化并输出到标准输出(终端/控制台)。

  • Sprintf:格式化并返回字符串,不直接输出,常用于后续处理。

  • Fprintf:格式化并输出到实现了 io.Writer接口的对象(比如文件、网络连接、缓冲区等)。

io.Writer接口只需要实现一个Write方法

type Writer interface {Write(p []byte) (n int, err error)
}

示例:实现一个简单内存Writer

type MemoryWriter struct {Buffer []byte
}func (m *MemoryWriter) Write(p []byte) (n int, err error) {m.Buffer = append(m.Buffer, p...)return len(p), nil
}func main() {var mw MemoryWriterfmt.Fprintf(&mw, "Hello, %s!", "World")fmt.Println(string(mw.Buffer)) // 输出: Hello, World!
}

go语言中值传递和地址传递(引用传递)如何运行?有什么区别?举例说明

  • 值传递:参数拷贝到函数内
  • 引用传递: 参数地址拷贝到函数内
  • go没有真正的引用传递,都是值传递
http://www.xdnf.cn/news/237925.html

相关文章:

  • 处理vue3热加载后axios的请求重复访问的问题
  • 深入理解C++17中的std::string_view
  • LibAI Lab走进西浦:重塑“AI+建筑”教育
  • 做了数据中台,还需要做数据治理吗?
  • 2025.4.28 Vue.js 学习笔记
  • 饿了么推出骑手AI助手小饿,智能配送再升级
  • 【综述】相位解包裹算法对比分析
  • QML学习:使用QML实现抽屉式侧边栏菜单
  • 融合AI助力医疗提效,华奥系医务系统助力医院数字化升级!
  • 老王说暗网【第8期】攻防演练的盲区?ATO(Account Takeover)攻击风险
  • EchoMimic 阿里开源数字人项目的复现过程
  • datax导出hdfs数据到关系型数据库空值处理
  • Redis基础系列-集群模式
  • 基于站点观测的中国1km土壤湿度日尺度数据集(2000-2022)
  • 深入探索ChatClient:简化AI模型交互的强大工具
  • 关于现代哲学的哲学理论的探索
  • layui轮播图根据设备宽度图片等比例,高度自适应
  • 在柯希霍夫积分法偏移成像中,反假频处理
  • 【黑马JavaWeb+AI知识梳理】后端Web基础01 - Maven
  • ReSearch: Learning to Reason with Search for LLMs via Reinforcement Learning
  • 【补题】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du
  • 西门子PLC S7-1200 的组态软件控制
  • DeepSeek V2:引入MLA机制与指令对齐
  • ZLG嵌入式笔记 | 移动硬盘和虚拟机的那些事儿
  • 深度卷积模型:案例研究
  • 【iPaaS融合集成平台-混合云时代,iPaaS正在成为企业集成的“中央枢纽”】
  • 数据访存性能影响因素:虚拟内存管理和TLB的概念和工作流程
  • 【Java】一篇讲透Java中的集合类
  • 多智能体协同作战:MagenticOne如何指挥一支AI团队
  • 什么是工业互联网平台?