这三个 Go 水平自测题,手写不出来还是先老实上班吧

2023-10-30

现在技术文章特别卷,啥啥底层都能给你分析的头头是道,但是分析的对不对要看作者水平,很有可能一个错,抄他的那些人也跟着错,因为我以前看源码的时候就经常感觉自己在两种状态下切换:懂了 / 娘咧漏看了,这个函数干啥的。

八股文这个事儿,其实也特别考验面试官,如果只会一味的问八股文,那也只能说你正巧比面试的人多看点八股,并不能彰显你多有水平,换个小年轻当面试官人家也能干啊。

最近跟以前的老同事聊,他说了个他特别爱问的面试题,我觉得还是挺有水平的,既能引导候选人循序渐进地展开思维,又能考察基础和动手能力。

PS:老哥是83年的,以前在一个广告平台公司 C++,Java,安卓啥的都干过,之前当过我领导,就是他让我刚来公司两星期就去会议室封闭参与用 Go 重构项目的,算是硬逼着我学了学 Go。

老哥说:Go 当初吸引人的地方不就是并发、Channel 这些嘛,其实用过后你会发现也就那样,宣传的有点过了,但是既然平时用 Go 开发,这块就一定得过关,那怎么并发和 Channel 都考察到呢?我一般会问:"Channel 和 并发掌握的熟练吧(一般没人会说不熟)那咱们先用 Channel 实现一个互斥锁",嘿,说你呢,实现一下。

我心想这题我面试别人用过,我背过……,还能难倒我:先初始化一个 capacity 等于 1 的 Channel,它的“空槽”代表锁,哪个协程能成功地把元素发送到这个 Channel,谁就获取了这把锁,给你上代码:

// 使用chan实现互斥锁
type Mutex struct {
    ch chan struct{}
}

// 使用锁需要初始化
func NewMutex() *Mutex {
    mu := &Mutex{make(chan struct{}, 1)}
    mu.ch <- struct{}{}
    return mu
}

// 请求锁,直到获取到
func (m *Mutex) Lock() {
    <-m.ch
}

// 解锁
func (m *Mutex) Unlock() {
    select {
    case m.ch <- struct{}{}:
    default:
        panic("unlock of unlocked mutex")
    }
}

老哥说:只要不是太混,这个道题都能答出来,那么接下来我一般会在这道题的基础上两个变种,首先让候选人再扩展一下给这个锁实现 TryLock 功能,TryLock 知道吧,你不是写过两年Java,这个用过吧,你在刚才的基础上实现一下。

我心想:我现在偶尔写Java 的时候都是把以前做的那些项目代码翻出来抄抄,我哪能记得这么清楚,不过这个不就是尝试获取锁,获取不到返回 false 嘛。

这里再给大家解释一下 TryLock 这个功能,下面这段话我从JavaDoc 里抄的:

tryLock() - 可轮询获取锁。如果成功,则返回 true;如果失败,则返回 false。也就是说,这个方法无论成败都会立即返回,获取不到锁(锁已被其他线程获取)时不会一直等待。

那这个也难不倒我啊,咱们学 Channel 的时候,都要学会利用 select+chan+default 的方式,避免程序阻塞住嘛,那我就套一下这个公式呗。(不过我老不写这个,语法我给忘了,多亏GoLand 提示我半天我才写出来,面试的时候一般在纸上写,咱们读者到时候记得贝贝哈)

// 尝试获取锁
func (m *Mutex) TryLock() bool {
    select {
    case <-m.ch:
        return true
    default:
    }
    return false
}

老哥:嗯,确实是这么个解法,不过你这写的也太慢了,算你过吧,其实我直接写估计也写不出来,天天开会手都生了。那好,这个变种如果能答出来,证明这个候选人基础应该还可以,Channel 使用这块应该都没啥问题,那这会儿我就会再扩展一下,让候选人再实现下 TryLock 的重载方法,就是可以设置超时时间那个重载函数,考察一下他定时器这块的知识过不过关,诶,我怎么把答案给说出来了,你懂我意思吧。

老哥的意思就是实现一下 TryWithTimeout,Java 里锁的 Try Lock 还有个重载方法:

tryLock(long, TimeUnit) - 可定时获取锁。和 tryLock() 类似,区别仅在于这个方法在获取不到锁时会等待一定的时间,在时间期限之内如果还获取不到锁,就返回 false。如果如果一开始拿到锁或者在等待期间内拿到了锁,则返回 true。

因为 Go 里边没有重载方法这种机制咱们就只能写个 TryWithTimeout 方法啦,刚才说了用定时器能实现,不过这块我也忘了怎么用了…...只好默默打开的了浏览器搜索,最后实现答案版本如下:

// 加入一个超时的设置
func (m *Mutex) LockTimeout(timeout time.Duration) bool {
    timer := time.NewTimer(timeout)
    select {
    case <-m.ch:
        timer.Stop()
        return true
    case <-timer.C:
    }
    return false
}

最后老哥看了看:嗯,看着挺像那么回事的,今天家里领导有事,我得赶紧接二公主放学了,下回再聊吧。


今天的小短文,主要带大家以一种循序渐进技术问答的形式和我一起回顾下 Channel 并发相关的知识。完整源码已经收录到我整理的Go 开发参考电子书中,给公众号「网管叨bi叨」私信【gocookbook】关键字即可领取,里面收录了很多实用的内容。

67643f7ad87d7e10699cff1fdbe31582.png

平时我们实际应用时最好不要用 Channel 替代sync.Mutex,但是用 Channel 确实除了实现互斥锁的功能外,还能扩充出TryLocKLockTimeout这些扩展功能。

利用 select+chan+defualt 的方式,很容易实现 TryLockTryLockWithTimeout 的功能。具体来说就是,在 select 语句中,我们可以使用 default 实现 TryLock,再加一个 Timer 来实现 Timeout 的功能。

关于 Channel 和 定时器的基础用法,我瞅了眼以前有写过,如果你才刚接触 Go,可以看下面两篇基础内容:

两篇老文章,内容可以,但是排版非常之垃圾,大家看前得做好心理准备,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这三个 Go 水平自测题,手写不出来还是先老实上班吧 的相关文章

随机推荐

  • Mysql获取数据库的所有表以及表所有字段信息

    mysql获取所有表以及表所有字段信息 SELECT TB TABLE SCHEMA 模式 TB TABLE NAME 表名 TB TABLE COMMENT 表名注释 COL COLUMN NAME 字段名 COL COLUMN TYPE
  • 风投与IT

    风投即风险投资 广义的风险投资泛指一切具有高风险 高潜在收益的投资 狭义的风险投资是指以高新技术为基础 生产与经营技术密集型产品的投资 根据美国全美风险投资协会的定义 风险投资是由职业金融家投入到新兴的 迅速发展的 具有巨大竞争潜力的企业中
  • vue设置不出现滚动条的全屏背景100%

    1 想在登录页面设置页面背景占比100 而且不出现滚动 首先给你所需要的元素设置好css 2 如果没生效 看下App vue中是否有定义 app的宽高 将其设置成100 3 如果综上两部设置完成还未生效 那就需要在index html文件中
  • kubernetes集群实战——资源限制(内存、CPU、NameSpace)

    1 k8s容器资源限制 Kubernetes采用request和limit两种限制类型来对资源进行分配 request 资源需求 即运行Pod的节点必须满足运行Pod的最基本需求才能 运行Pod limit 资源限额 即运行Pod期间 可能
  • MySQL必知必会 学习笔记 第一章 了解SQL

    数据库是保存有组织的数据的容器 通常是一个或一组文件 数据库软件称为DBMS 数据库管理系统 数据库是被DBMS创建和操纵的容器 数据库究竟是文件或其他东西并不重要 因为你不会直接访问数据库 而是间接通过DBMS替你访问数据库 表是某种特定
  • BootstrapTable checkbox默认选中

    BootstrapTable 在Web后台管理项目中对表格展示数据使用居多 主要是表格的多条件查询 分页 排序等功能 我们的项目中前端框架是Bootstrap 所以很多插件都是支持Bootstrap的 bootstrap table是一款非
  • 关于List的subList原理分析

    今天在看Java开发手册的时候看到这么一句话 如果需要对list某个范围内的元素进行操作 可以使用subList 任何对子列表的操作最终都会反映到原列表中 例如list subList 0 2 clear 这样的操作便会对原列表进行修改 修
  • SARScape中用sentinel-1数据做SBAS-InSAR完整流程(1/2)

    SARScape中用sentinel 1数据做SBAS InSAR完整流程 1 SABA InSAR原理简述 2 数据采集和预设 2 1 SAR数据采集 2 2 DEM数据下载与放置 2 3 精密轨道数据下载与放置 2 4 制作研究区范围矢
  • 三分钟教你小程序实现无感刷新!

    无感刷新 无感刷新对于前端来说是一项非常实用的技术 其本质是为了优化用户体验 让用户感受不到token已经过期 本质上就是登录时 储存token和refresh token 当token过期或错误时不需要用户跳回登录页重新登录 而是在响应拦
  • python读取文件名存到list_python读取文件名称生成list的方法

    下面为大家分享一篇python读取文件名称生成list的方法 具有很好的参考价值 希望对大家有所帮助 一起过来看看吧 经常需要读取某个文件夹下所有的图像文件 我使用python写了个简单的代码 读取某个文件夹下某个后缀的文件 将文件名生成为
  • 力扣 删除链表的节点

    给定单向链表的头指针和一个要删除的节点的值 定义一个函数删除该节点 返回删除后的链表的头节点 注意 此题对比原题有改动 示例 1 输入 head 4 5 1 9 val 5 输出 4 1 9 解释 给定你链表中值为 5 的第二个节点 那么在
  • 手动实现Spring IOC 跟 AOP 的雏形

    关注后回复 进群 拉你进程序员交流群 作者丨sowhat1412 来源丨sowhat1412 Spring Spring make java more simpleSpring make java more modernSpring mak
  • 在Linux下用C语言写贪吃蛇;

    项目思路 ncurses上下左右键的获得 gt 贪吃蛇地图的实现 gt 显示贪吃蛇的完整身子 gt 贪吃蛇向右移动 gt 贪吃蛇撞墙找死 gt 贪吃蛇自行向右行走与页面一起刷新 利用线程解决 gt 贪吃蛇四个方向的自由走位 gt 贪吃蛇吃饭
  • 教程:群体演化方法分析玉米的驯化与改良

    一般文章在筛选 正选择区间 时 大多 不考虑 群体的 演化历史 即不考虑 群体大小 的变化 只进行亚群之间各种群体遗传参数的对比 这可能会产生大量的假阳性 另一方面 研究一般也 不考虑 遗传信息的 迁移 所以作者希望将群体演化历史及遗传信息
  • MySQL高性能索引策略

    文章目录 高性能索引策略 独立的列 前缀索引 多列索引 选择合适的索引列顺序 聚簇索引 覆盖索引 使用索引扫描来做排序 高性能索引策略 正确地创建和使用索引是实现高性能查询的基础 高效地选择和使用索引有很多种方式 其中有些是针对特殊案例的优
  • 二叉树的基本概念(定义,特性,存储结构等)

    一 二叉树的定义 二叉树 Binary Tree 是n n gt 0 个数据元素的有限集合 该集合可以为空 空二叉树 也可以由一个称为根 root 的元素及两个不相交的 被分别称为左子树和右子树的二叉树组成 如上图中含有7个结点 其中A是根
  • Python安装MySQL库详解(解决Microsoft Visual C++ 9.0 is required )

    前面我们介绍的Python网络爬虫通常将抓取的数据存储至TXT或CSV文件 而当数据量增加之时 就需要将其存储至本地数据库了 Python访问数据库需要对应的接口程序 我们可以把接口程序理解为Python的一个模块 它提供了数据库客户端的接
  • css3选择器如何选择同一个父级下的相同class的第一个元素 nth-child nth-of-type

    1 2 3 4 5 选择第一个类名 demo item nth of type 1 demo item nth child 1 选择最后一个类名 demo item last child 选择其中一个指定的类名 demo item nth
  • Window.open()方法参数详解

    1 最基本的弹出窗口代码 window open page html 2 经过设置后的弹出窗口 window open page html newwindow height 100 width 400 top 0 left 0 toolba
  • 这三个 Go 水平自测题,手写不出来还是先老实上班吧

    现在技术文章特别卷 啥啥底层都能给你分析的头头是道 但是分析的对不对要看作者水平 很有可能一个错 抄他的那些人也跟着错 因为我以前看源码的时候就经常感觉自己在两种状态下切换 懂了 娘咧漏看了 这个函数干啥的 八股文这个事儿 其实也特别考验面
Powered by Hwhale