Gate.io 面试

面试官超级nice,不懂的问题都告诉了我答案,是一家非常喜欢的公司

线程安全map

  1. 使用 sync.map
  2. 使用 sync.RWMutex 手动加锁

defer 对程序性能的影响

一般场景下,defer 的性能开销微不足道,但在循环中,手动管理资源释放可能是更优的选择

gc

三色渲染法,写屏障

进程、线程、协程

  1. 进程: 进程是具有一定独立功能的程序,进程是系统资源分配和调度的最小单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
  2. 线程: 线程是进程的一个实体,线程是内核态,而且是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
  3. 协程: 协程是一种用户态的轻量级线程,协程的调度完全是由用户来控制的。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

协程如何释放CPU

  1. 协程在执行 I/O 操作、阻塞调用、同步操作(如互斥锁、channel 等)时会自动释放 CPU。
  2. 可以使用 runtime.Gosched() 主动让出 CPU,让 Go 调度器去调度其他 goroutine。
  3. 从 Go 1.14 开始,Go 支持抢占式调度,即使没有显式释放 CPU,Go 运行时也能强制调度其他 goroutine

内存泄露分析工具

可以通过Go自带的工具pprof或者使用Gops去检测诊断当前在系统上运行的Go进程的占用的资源。

B 树和 B+树的区别

  • 在B+树中,叶子节点包含了所有的数据记录,而B树的数据记录分布在所有节点上(包括非叶子节点)。
  • B+树的叶子节点之间有链表结构,便于顺序遍历,而B树没有这样的结构。

聚簇索引和非聚簇索引

  • 聚簇索引将数据的物理存储顺序与索引顺序一致。也就是说,表中的数据按索引列的顺序进行存储,聚簇索引不仅存储索引,还决定了表中数据的物理排列方式。
  • 聚簇索引不需要回表
  • 非聚簇索引是将索引与数据分开存储,索引的结构中保存了指向实际数据的指针(即物理地址),通过索引查找需要先查索引,再根据指针去访问实际的数据行。
  • 非聚簇索引需要回表

mysql默认隔离级别

可重复读

redis大key会有什么影响

大key(即占用内存较多的键值对)可能会对系统性能、内存使用和管理带来一些负面影响。
大key在Redis中会导致内存消耗增加、操作阻塞、网络瓶颈、持久化和主从复制延迟等问题。为了避免这些问题,最好在设计时避免创建大key,定期监控并优化大key的使用。同时可以通过分片、TTL等策略,降低大key对系统的负面影响。

后续又投了一波,居然又给了一次面试的机会,可惜没把握住

波场的带宽和能量

在波场(TRON)网络中,带宽(Bandwidth)能量(Energy)是两种资源,用于不同类型的操作和消耗,分别处理交易费用和智能合约执行的成本。它们的设计目的是为用户提供灵活的资源使用模式,避免单一的交易费用模式。

1. 带宽(Bandwidth)

  • 用途:用于支付普通的转账交易,例如 TRX 代币的转移等。
  • 获取方式
    • 每个账户每天会自动获得一定的免费带宽(通常是 1500 带宽),但这些免费额度可能不足以支付较频繁的交易。
    • 额外的带宽可以通过冻结 TRX 获得,用户在冻结 TRX 后可以按比例获得更多的带宽资源。
    • 若带宽不足,也可以支付 TRX 手续费来完成交易。
  • 计算消耗:每次交易会消耗带宽,消耗量取决于交易的大小(以字节为单位),一般为每字节 1 带宽。

2. 能量(Energy)

  • 用途:用于支付智能合约的执行费用,包括合约的创建、调用和运算等操作。
  • 获取方式
    • 与带宽类似,用户可以通过冻结 TRX 获得能量,且冻结的 TRX 不同于获得带宽的部分。
    • 用户也可以选择直接支付 TRX 来支付能量消耗的费用。
  • 计算消耗:每次调用智能合约都会消耗能量,消耗量取决于合约的复杂性和计算需求。消耗的能量越多,合约执行的成本也越高。

带宽与能量的差异

资源类型 用途 获取方式 计算方式
带宽 普通交易的手续费 每日免费带宽、冻结 TRX 获取、直接支付 TRX 根据交易大小消耗带宽
能量 智能合约的执行费用 冻结 TRX 获取、直接支付 TRX 根据合约复杂度和运算需求消耗能量

3. 使用场景和优势

  • 免费交易:通过冻结 TRX,用户可以减少支付 TRX 手续费的需求,尤其适合频繁交易和合约操作的用户。
  • 智能合约:能量专门用于合约,适合合约调用量大的用户,通过冻结 TRX 获取能量可以有效减少直接支付的 TRX 成本。

B+树的高度是什么决定的

B+ 树的高度主要由树的阶数(degree)存储的数据量(节点数)决定。B+ 树是一种自平衡的多路查找树,通常用于数据库和文件系统中,因为它能高效地进行大量数据的插入、删除和查询操作。

1. 树的阶数(degree)

  • 阶数定义:B+ 树的阶数(m)指每个内部节点最多可以有 m 个子节点,或者说每个节点中可以存储最多 m-1 个键。
  • 对高度的影响:B+ 树的阶数越高,单个节点可以存储的键越多,意味着每次查询时可以“分流”到更多的子节点。这样树的分叉系数更高,树的深度就会更小。因此,树的阶数越大,B+ 树的高度越低。
  • 实际应用:在数据库和文件系统中,阶数通常设得较大(例如 100 以上),以减少树的高度,从而减少磁盘 I/O 操作,提升查询性能。

2. 数据量(节点数)

  • 影响高度的原因:B+ 树是平衡树,随着存储数据量的增加,树会自动保持平衡,通过增加树的高度来适应更多的数据。
  • 高度关系:假设 B+ 树的阶数为 m,树的高度为 h,则 B+ 树在最坏情况下存储的数据量 N 可以达到:
    [
    N \leq m^h
    ]
    因此,树的高度 h 与数据量 N 的关系为:
    [
    h \approx \log_m(N)
    ]
  • 数据量越大,树越高:在阶数固定的情况下,数据量越大,树的高度就越高,但由于 B+ 树的分支系数大,高度增加相对较慢。

总结

B+ 树的高度主要由树的阶数和数据量共同决定。较大的阶数可以显著减少树的高度,而随着数据量的增加,树的高度会逐渐增加。因此,实际应用中通过选择合适的阶数,可以在存储容量和查询效率之间取得平衡。

三色渲染的根节点

三色标记算法中,根节点指的是从哪里开始遍历和标记的起点。通常,根节点包含了程序中的所有活跃变量和全局引用,即那些能够直接或间接引用到堆内存中对象的变量。三色标记法主要用于垃圾回收,通过从根节点开始遍历来确定哪些对象是可达的,哪些对象是垃圾。

根节点的来源

根节点的典型来源包括:

  1. 全局变量和静态变量:这些变量在程序生命周期内存在,始终处于可达状态。
  2. 栈中的活动变量:当前函数调用栈上的变量,包括局部变量、参数等。
  3. 寄存器中的变量:在处理器寄存器中存储的指针或变量值。

5个协程并发,发送随机数量的随机数给另外一个协程,求和并打印结果,要求空间复杂度为O(1)。

func main() {
    ch := make(chan int)
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            j := rand.Intn(10)
            for k := 0; k < j; k++ {
                ch <- rand.Intn(10)
            }
        }()
    }

    go func() {
        wg.Wait()
        close(ch)
    }()
    sum := 0
    for num := range ch {
        sum += num
    }
    fmt.Println(sum)
}

滑点

在 Uniswap 等去中心化交易所(DEX)中,滑点(Slippage)指的是交易执行时的价格与预期价格之间的差异。滑点通常发生在市场波动较大或交易量较高时,由于流动性和价格波动的影响,实际成交价格可能与预期不同。

滑点的原因

滑点主要由以下因素引起:

  1. 价格波动:加密市场波动性较大,价格在提交交易与执行交易的时间差内可能发生显著变化。
  2. 流动性池深度:在 AMM(自动化做市商)机制中,Uniswap 的价格由流动性池中的两种代币的比例决定,交易会改变池中代币的比例,影响价格。
  3. 交易规模:大额交易会显著影响流动性池的代币比例,导致更大的价格变动,即更高的滑点。

如何应对滑点

Uniswap 允许用户设置“滑点容忍度”,即用户可以接受的滑点范围(通常为 0.1% - 1%)。如果滑点超过设定值,交易会自动取消,以避免过度滑点带来的不利价格。

滑点计算

滑点通常表示为百分比,计算方式如下:

[
\text{滑点} = \frac{\text{期望价格} - \text{实际成交价格}}{\text{期望价格}} \times 100%
]

例如:

  • 如果用户希望以 100 USDT 购买某代币,但实际成交价是 98 USDT,则滑点为 2%。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容