天天看點

面試之路2019 - 01

日期

2019-06-20 8:00 pm

問題

golang相關

問題1:golang中單例模式如何實作?

sync.once,簡單實作如下:

var m *Manager
var once sync.Once

func GetInstance() *Manager {
    once.Do(func() {
        m = &Manager {}
    })
    return m
}

type Manager struct {}

func (p Manager) Manage() {
    fmt.Println("manage...")
}
           

問題2: golang的once的實作機制

其實golang中once的實作及其簡單,源碼如下:

import (
	"sync/atomic"
)
type Once struct {
	m    Mutex
	done uint32
}
func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 1 {
		return
	}
	// Slow-path.
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}
           

其中的構成是一個mutex互斥鎖外加一個done的标記位

同時用atomic原子操作,保證了标志位設定過程的原子性

使用了雙重檢驗的機制

關鍵點:once是線程安全的,并發安全

問題3: defer

  • defer 在 return 之前執行
  • defer 是 後進先出的順序執行

redis相關

問題:redis中的并發讀寫如何實作?

  1. 首先redis服務端是單線程的,是串行處理業務端請求的
  2. 是以并發問題主要存在于業務端
  3. 建議使用**消息隊列(chan)**的方式,将業務端的寫操作也串行化
  4. 如果不使用消息隊列的方式,就需要使用redis中incr,setnx指令,實作分布式鎖, 這個分布式鎖有官方實作的包,建議使用

邏輯思維相關

一根金條,一個長工,7天時間,每天給他1/7的工資;隻能切這個金條兩次:

  1. 切成 1 - 2 - 4 的比例
  2. 隐含條件是可以贖回,比如第二天的時候,可以将2/7給長工,然後把1/7拿回來
總體的表現不是很好,基本都沒有答出來,需要後續補上對應的内容

繼續閱讀