關(guān)于Golang面試寶典
最近幾年望抽,Go的熱度持續(xù)飆升加矛,國內(nèi)外很多大公司都在大規(guī)模的使用Go。Google是Go語言誕生的地方煤篙,其他公司如Facebook斟览、騰訊、阿里辑奈、字節(jié)跳動苛茂、百度、京東鸠窗、小米等都在擁抱和轉(zhuǎn)向Go妓羊。Go語言的開源項(xiàng)目也非常多,如kubernetes稍计、docker躁绸、etcd。
隨著市場對Go語言人才需求的增長臣嚣,很多開發(fā)者都投入了Go語言的懷抱净刮。本系列文章將以第一視角與大家一同開始Golang的面試之路,希望大家能夠有所收獲硅则,拿下心儀的offer淹父。
使用Go實(shí)現(xiàn)23種設(shè)計(jì)模式——行為型模式(下)
迭代器模式
提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而又不需要暴露該對象的內(nèi)部表示
適用場景
- 把在元素之間游走的責(zé)任交給迭代器怎虫,而不是集合對象
Go語言實(shí)現(xiàn)
type IAggregate interface {
Iterator() IIterator
}
type IIterator interface {
HasNext() bool
Current() int
Next() bool
}
type Aggregate struct {
Container []int
}
func (a *Aggregate) Iterator() IIterator {
i := new(Iterator)
i.aggregate = a
return i
}
type Iterator struct {
cursor int
aggregate *Aggregate
}
func (i *Iterator) HasNext() bool {
return i.cursor < len(i.aggregate.Container)-1
}
func (i *Iterator) Current() int {
return i.aggregate.Container[i.cursor]
}
func (i *Iterator) Next() bool {
if i.HasNext() {
i.cursor++
return true
}
return false
}
func main() {
a := &Aggregate{Container: []int{1, 2, 3, 4}}
it := a.Iterator()
for {
fmt.Printf("current: %d\n", it.Current())
if it.HasNext() {
it.Next()
} else {
break
}
}
}
迭代器模式優(yōu)點(diǎn)
- 它支持不同的方式遍歷集合對象
- 迭代器簡化了聚合類
- 在同一個(gè)聚合上面可以有多個(gè)遍歷
- 迭代器模式中暑认,新增聚合類和迭代器都很方便督暂,無需新增代碼
迭代器模式缺點(diǎn)
- 增加新的聚合類需要增加對應(yīng)新的迭代器
解釋器模式
提供如何定義語言的文法,以及對語言句子的解釋方法
適用場景
- 一般應(yīng)用于編譯器穷吮、規(guī)則引擎逻翁、正則表達(dá)式等功能
Go語言實(shí)現(xiàn)
type Expression interface {
Interpret(context string) bool
}
type TerminalExpression struct {
Context string
}
func (e *TerminalExpression) Interpret(context string) bool {
return strings.Contains("good", context)
}
type OrExpression struct {
Expr1 Expression
Expr2 Expression
}
func NewOrExpression(e1, e2 Expression) *OrExpression {
return &OrExpression{
Expr1: e1,
Expr2: e2,
}
}
func (e *OrExpression) Interpret(context string) bool {
return e.Expr1.Interpret(context) || e.Expr2.Interpret(context)
}
func main() {
g := &TerminalExpression{Context: "go"}
d := &TerminalExpression{Context: "god"}
o := NewOrExpression(g, d)
r := o.Interpret("god")
fmt.Println(r)
}
解釋器模式優(yōu)點(diǎn)
- 可擴(kuò)展性高、靈活
- 易于實(shí)現(xiàn)簡單的文法
解釋器模式缺點(diǎn)
- 可使用場景少
- 復(fù)雜文法較難維護(hù)
命令模式
將一個(gè)請求封裝為一個(gè)對象捡鱼,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開
適用場景
- 對行為進(jìn)行記錄八回、撤銷、重做等處理
Go語言實(shí)現(xiàn)
type Order interface {
Execute()
}
type Runner struct{}
func (r *Runner) Execute() {
fmt.Println("running")
}
type Control struct {
Cmd Order
}
func (c *Control) SetCmd(cmd Order) {
c.Cmd = cmd
}
func (c *Control) Do() {
c.Cmd.Execute()
}
func main() {
c := Control{}
r := Runner{}
c.SetCmd(&r)
c.Do()
}
命令模式優(yōu)點(diǎn)
- 通過引入中間件降低了系統(tǒng)的耦合度
- 擴(kuò)展性良好驾诈,且滿足"開閉原則"
命令模式缺點(diǎn)
- 每一個(gè)具體操作都需要設(shè)計(jì)一個(gè)具體命令類缠诅,增加了系統(tǒng)復(fù)雜度
責(zé)任鏈模式
將所有請求的處理者通過前一對象記住其下一個(gè)對象的引用而連成一條鏈,直到請求被處理為止
適用場景
- 多個(gè)對象可以處理一個(gè)請求乍迄,但是具體由誰來執(zhí)行在運(yùn)行時(shí)自動確定
- 可動態(tài)指定一組對象處理請求或添加新的處理者
Go語言實(shí)現(xiàn)
type Context struct {
Data string
}
type Handle interface {
Handle(context Context)
SetNext(handle Handle)
GetNext() (next Handle, ok bool)
}
type LogHandle struct {
next Handle
}
func (h *LogHandle) Handle(c Context) {
fmt.Printf("日志:%s", c.Data)
if next, ok := h.GetNext(); ok {
next.Handle(c)
}
}
func (h *LogHandle) SetNext(next Handle) {
h.next = next
}
func (h *LogHandle) GetNext() (next Handle, ok bool) {
if h.next != nil {
return h.next, true
}
return nil, false
}
type AuthHandle struct {
next Handle
}
func (h *AuthHandle) Handle(c Context) {
fmt.Printf("權(quán)限:%s", c.Data)
if next, ok := h.GetNext(); ok {
next.Handle(c)
}
}
func (h *AuthHandle) SetNext(next Handle) {
h.next = next
}
func (h *AuthHandle) GetNext() (next Handle, ok bool) {
if h.next != nil {
return h.next, true
}
return nil, false
}
func main() {
auth := AuthHandle{}
log := LogHandle{}
log.SetNext(&auth)
context := Context{Data: "test"}
log.Handle(context)
}
責(zé)任鏈模式優(yōu)點(diǎn)
- 降低了對象間的耦合度
- 增強(qiáng)了系統(tǒng)的可擴(kuò)展性
- 增強(qiáng)了給對象指派職責(zé)的靈活性
- 簡化了對象間的連接
責(zé)任鏈模式缺點(diǎn)
- 不能保證每個(gè)請求一定被處理
- 責(zé)任鏈建立的合理性靠客戶端保證管引,增加了客戶端的復(fù)雜性