每日go语言面试题六

1.Redis分布式锁如何实现的

分布式锁一般需要从几个方面去考虑,正确性和效率,分布式锁一般需要一个全局的key,然后持有锁的用完必须进行释放锁,如果忘记释放,必须要有过期时间。因为redis命令执行的时候是以单线程进行执行的,符合天然的原子性条件之一,没有冲突,可以考虑用setnx命令去设置锁,值存在的时候才有效,并且在高版本的时候还可以设置过期时间,解锁的时候需要加锁的值进行匹配,防止被其他人进行解锁。除了用sentx命令之外,还可以用lua脚本多个命令批量执行。初次之外,在一些业务场景下面,常常用数据库的唯一键来做幂等处理。

2.分布式锁还有哪些实现方案

用的多的有数据库的唯一索引、redis的单线程实行的原理和zomkeeper等。

3.线程池是用来处理啥的、使用的业务场景、解决什么业务问题

线程池存在是为加快响应处理业务,减少了线程创建的等待时间,线程池主要是对工作的线程进行统一管理,从内存、调度和GC的角度去考虑,线程池在业务上应用很广,比如MySQL连接池,TomCat的连接池等。

4.让你实现一个RPC框架,应该要考虑哪些点

协议、压缩方式、端口号、序列化。

5.阻塞IO和非阻塞IO有什么区别

文件从磁盘或者网卡传输到用户缓冲区的时候,会先将数据拷贝到内核区,在从内核去拷贝到用户区,阻塞时只从数据从外部拷贝到内核区的时候,用户进程时阻塞还是轮询,轮询时非常消耗cpu资源,阻塞的话,应用进程进行休眠。

6.如何实现多路复用IO

要实现IO多路复用,一般是通过一个slect去监听多个文件描述符,当有读写时间来的时候,在进行处理读写事件,这就实现了IO多路复用。

7.select、epoll原理

select是通过监听文件描述符,具体流程是,将监听的文件描述符从用户区拷贝到内核区,通过内核去遍历文件哪些文件描述符已经就绪,然后将就绪的拷贝到用户区,在进行遍历,将满足条件的文件描述符分别进行读或者写,select监听的文件描述符是有上限的,上限为1024个,select基本和poll相似。epoll是解决了文件描述符集合在用户态和内核态之间拷贝和遍历的开销,epoll是由事件进行驱动的,有epoll_create,epoll_ctl,epoll_wait,epoll_ctl是将新监听的文件描述符加入到内核区域维护的一个B+树中,当有就绪的时候,直接通过epoll_wait就可以返回就绪的文件描述符。

https://xiaolincoding.com/os/8_network_system/selete_poll_epoll.html#%E8%BE%B9%E7%BC%98%E8%A7%A6%E5%8F%91%E5%92%8C%E6%B0%B4%E5%B9%B3%E8%A7%A6%E5%8F%91

9.go语言实现堆排序。

// 5个核心的方法
type Que []int 
func (que Que)Len{return len(que)}
func (que Que)Less(i , j int)bool{return que[i] < que[j]}
func (que Que)Swap(i , j int){que[i] , que[j] = que[j] , que[i]}
func (que *Que)Push(x interface{}){*que = append(*que , x.([]int)}
func (que *Que)Pop interface{}{
    old := que
    n := len(old)
    x := old[n - 1]
    *que = old[:n-1]
    return n
}

10.算法

  • 反转链表

头插法

  • 最长回文子串

遍历

  • 子集

      dfs

  • n个骰子的点数和为k的概率

暴力解法:dfs

动态规划,上一层的状态与下一层的状态之间的联系。

func main() {
   n := 2
   k := 11
   dp := make([][]float64, n+1)
   var dfs func(n, k int) float64
   dfs = func(n, k int) float64 {
      if n < 0 || k < 0 {
         return 0
      }
      if dp[n][k] != 0 {
         return dp[n][k]
      }
      for i := 1; i <= 6; i++ {
         if k >= i {
            dp[n][k] = dp[n][k] + dfs(n-1, k-i)/6
         }
      }
      return dp[n][k]
   }
   for i := 0; i <= n; i++ {
      dp[i] = make([]float64, k+1)
   }
   dp[0][0] = 1
   dfs(n, k)
   fmt.Println(dp[n][k])
   fmt.Println(float64(1) / 18)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿联爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值