版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Go进阶实战100题交替打印数字和字
打印数字,另外⼀个
打印字⺟,最终效果问题很简单,使⽤channel来控制打印的进度。使⽤两个channel,来分别控制数字和字⺟的打印序列,数字打印完成后通过channel通知字⺟打印,字⺟打印完成后通知数字打印,然后周⽽复始的⼯作。letter,number:=make(chanbool),make(chanbool)wait:=sync.WaitGroup{}gofunc(){i:=1for{select{case<-number:letter<-gofunc(wait*sync.WaitGroup){i:='A'selectcase<-letter:ifi>='Z'number<-这⾥⽤到了两个channel负责通知,letter负责通知打印字⺟的goroutine来打印字⺟,number⽤来通知打印数字wait判断字符串中字符是否全都不 给定⼀个sring,请返回⼀个boo值,rue代表所有字符全都不同,e代表存在相同的字符。保证字符串中的字符为【ASCII字符】。字符串的⻓度⼩于等于【3000这⾥有⼏个重点,第⼀个是ASCII字符,ASCII字符字符⼀共有256个,其中128⼊。128然后是全部不同,也就是字符串中的字符没有重复的,再次,不准使⽤额外的储存结构,且字符串⼩于等于300如果允许其他额外储存结构,这个题⽬很好做。如果不允许的话,可以使⽤golan内置的⽅式实现。通过strings.CountfuncfuncisUniqueString(sstring)bool{ifstrings.Count(s,"")>3000{returnfor_,v:=ranges{ifv>127{returnifstrings.Count(s,string(v))>1{returnfalsereturn通过strings.Index和strings.LastIndexfuncfuncisUniqueString2(sstring)bool{ifstrings.Count(s,"")>3000{returnfork,v:=ranges{ifv>127{returnifstrings.Index(s,string(v))!=k{returnfalsereturn第⼀个⽅法使⽤的是golan内置⽅法strings.Count,量。第⼆个⽅法使⽤的是golan内置⽅法strings.Index和strings.LastIndex字符串的索引未知,分别是第⼀次发现位置和最后发现位置。翻转字符 请实现⼀个算法,在不使⽤【额外数据结构和储存空间】的情况下,翻转⼀个给定的字符串(量)。给定⼀个string,请返回⼀个string,为翻转后的字符串。保证字符串的⻓度⼩于等于5000翻转字符串其实是将⼀个字符串以中间字符为轴,前后翻转,即将str[len]赋值给str[0],将str[0]赋值str[len]funcfuncreverString(sstring)(string,bool){str:=[]rune(s)l:=len(str)ifl>5000returns,fori:=0;i<l/2;i++str[i],str[l-1-i]=str[l-1-i],returnstring(str),以字符串⻓度的1/2判断两个给定的字符串排序后是否⼀ 这⾥规定【⼤⼩写为不同字符】,且考虑字符串重点空格。给定⼀个srings1和⼀个srings2,请返回⼀个代表两串是否重新排列后可相同。保证两串的⻓度都⼩于等于5000⾸先要保证字符串⻓度⼩于5000。之后只需要⼀次循环遍历s1中的字符在s2funcisRegroup(s1,s2string)boolfuncisRegroup(s1,s2string)boolsl1:=sl2:=ifsl1>5000||sl2>5000||sl1!=returnfor_,v:=ranges1ifstrings.Count(s1,string(v))!=strings.Count(s2,string(v)){returnfalsereturn这⾥还是使⽤golang
字符串替换问 请编写⼀个⽅法,将字符串中的空格全部替换为“%20”假定该字符串有⾜够的空间存放新增的字符,并且知道字符串的真实⻓度(⼩于等于1000)给定⼀个string为原始的串,返回替换后的stringfuncfuncreplaceBlank(sstring)(string,bool){iflen([]rune(s))>1000{returns,for_,v:=rangesifstring(v)!=""&&unicode.IsLetter(v)==false{returns,falsereturnstrings.Replace(s,"","%20",-1),这⾥使⽤了golang内置⽅法unicode.IsLetter判断字符是否是字⺟,之后使⽤strings.Replace机器⼈坐标问 有⼀个机器⼈,给⼀串指令,L左转R右转,F前进⼀步,B后退⼀步,问最后机器⼈的坐标,最开始,机器⼈位于00,⽅向为正Y。可以输⼊重复指令n:⽐如R2(LF这个等于指令RLFLF。packagepackageimport(constLeft=iotafuncmain()println(move("R2(LF)",0,0,funcmove(cmdstring,x0int,y0int,z0int)(x,y,zint){x,y,z=x0,y0,z0repeat:=0repeatCmd:=""for_,s:=rangecmd{switch{caserepeat=repeat*10+(int(s)-'0')cases==')':fori:=0;i<repeat;i++x,y,z=move(repeatCmd,x,y,repeat=0repeatCmd=""caserepeat>0&&s!='('&&s!=')':repeatCmd=repeatCmd+string(s)cases==z=(z+1)%cases==z=(z-1+4)%cases=='F':switch{casez==Left||z==Right:x=x-z+1casez==Top||z==Bottom:y=y-z+2cases=='B':switch{casez==Left||z==Right:x=x+z-1casez==Top||z==Bottom:y=y+z-2这⾥使⽤三个值表示机器⼈当前的状况,分别是:x表示x坐标,y表示y坐标,zL、R命令会改变值z,F、B命令会改变值x、y。下⾯代码能运⾏吗?为什么 typetypeParamtypeShowstructfuncmain1()s:=new(Show)s.Param["RMB"]=10000
请说出下⾯代码存在什么问题 typetypestudentstructNamefunczhoujielun(vinterface{})switchmsg:=v.(type){case*student,student:golang中有规定,switchtype的caseT1,类型列表只有⼀个,那么v:=m.(type)中的v的类型就是T1类如果是caseT1,T2,类型列表中有多个,那v的类型还是多对应接⼝的类型,也就是m\h所以这⾥msg的类型还是interface{},所以他没有Name这个字段,编译阶段就会报错。具体解释⻅:https:///ref/spec#Type_switches写出打印的结果 typetypePeoplestructnamestringfuncmain()js:=`{varperr:=json.Unmarshal([]byte(js),&p)iferr!=nil{fmt.Println("err:",err)fmt.Println("people:",
是私有的,同样,在json题⽬中是⽆法正常得到People的name值的。⽽且,私有属性name也不应该加json下⾯的代码是有问题的,请说明原因 typetypePeoplestructNamefunc(p*People)String()stringreturnfmt.Sprintf("print:%v",funcmain()p:=&People{}在golang中String()string⽅法实际上是实现了String的接⼝的,该接⼝定义在fmt/print.gotypetypeStringerinterface{String()string
请找出下⾯代码的问题所在 funcfuncmain()ch:=make(chanint,1000)gofunc(){fori:=0;i<10;i++{ch<-igofunc(){for{a,ok:=<-chif!ok{fmt.Println("a:",time.Sleep(time.Second*在golang
请说明下⾯代码书写是否正确 varvarvaluefuncSetValue(deltaint32)forv:=ifatomic.CompareAndSwapInt32(&value,v,(v+delta)){下⾯的程序运⾏后为什么会爆异常 typeProjectfunc(p*Project)deferError()iferr:=recover();err!=nil{fmt.Println("recover:",err)func(p*Project)exec(msgchanchaninterface{}){formsg:=rangemsgchan{m:=msg.(int)fmt.Println("msg:",m)func(p*Project)run(msgchanchaninterface{}){for{deferp.deferError()gop.exec(msgchan)time.Sleep(time.Second*func(p*Project)Main()a:=make(chaninterface{},100)gop.run(a)gofunc(){for{a<-time.Sleep(time.Second*funcmain()p:=new(Project)
1<<63-defer 需要在协程开始出调⽤,否则⽆法捕获panic1<<63-defer请说出下⾯代码哪⾥写错 funcfuncmain()abc:=make(chanint,1000)fori:=0;i<10;i++{abc<-gofunc()fora:=rangeabc{fmt.Println("a:",a)time.Sleep(time.Second*100)请说出下⾯代码,执⾏时为什么会报 typetypeStudentstructnamefuncmain()m:=map[string]Student{"people":{"zhoujielun"}}m["people"].name="wuyanzu"⽤map[string]*Studentma的alue本身是不可寻址的,因为ma中的值会在内存中移动,并且旧的指针地址在ma故如果需要修改ma值,可以将map中的⾮指针类型value⽤map[string]*Student请说出下⾯的代码存在什么问题 typetypequeryfunc(string)funcexec(namestring,vs...query)stringch:=make(chanstring)fn:=func(iint){ch<-fori,_:=rangevs{gofn(i)return<-funcmain()ret:=exec("111",func(nstring)string{returnn+"func1"},func(nstring)string{returnn+"func2"},func(nstring)string{returnn+"func3"},func(nstring)string{returnn+"func4"下⾯这段代码为什么会卡死 packagepackageimportfuncmain()varvarigofunc()fori=0;i<=255;i++fmt.Println("Dropping//YieldexecutiontoforceexecutingothergoroutinesGolang中,bytealiasuint8fori++i=255i255也即是,forgofuncgofunc()for正在被执⾏的goroutine发⽣以下情况时让出当前goroutine的执⾏权,并调度后⾯的goroutineIO操作Channel阻塞systemcall运⾏较⻓时间如果⼀个goroutine执⾏时间太⻓,scheduler会在其G对象上打上⼀个标志(preempt),当这个内部发⽣函数调⽤的时候,会先主动检查这个标志,如果为truemaingoroutineIOChannelsystemcall、没有函数调⽤的也就是,它⽆法主动让出⾃⼰的执⾏权,即使已经执⾏很⻓时间,scheduler已经标志了preempt
都停⽌后进⾏的。因此,程序会卡 等写出下⾯代码输出内容 packagepackageimportfuncmain()funcdefer_call()deferfuncfmt.Println("打印前"deferfuncfmt.Println("打印中"deferfuncfmt.Println("打印后"panic("触发异常关键字的实现跟go关键字很类似,不同的是它调⽤的是runtime.deferproc⽽不是runtime.newprocruntime.deferreturn在defer出现的地⽅,插⼊了指令callruntime.deferproc,然后在函数返回之前的地⽅,插⼊指令runtime.deferreturngroutin的控制结构中,有⼀张表记录defer,调⽤runtime.deferproc时会将需要defr中,⽽在调⽤runtime.deferreturn的时候,则会依次从defr表中出栈并执⾏。因此,题⽬最后输出顺序应该是defer定义顺序的倒序。panic错误并不能终 的执⾏以下代码有什么问题,说明原 typetypestudentstructNamestringAgeintfuncpase_student()m:=make(map[string]*student)stus:=[]student{{Name:"zhou",Age:{Name:"li",Age:{Name:"wang",Age:for_,stu:=rangestus{m[stu.Name]=&stugolang
语法中,stufor...致最后m中的map中储存的都是stus最后⼀个studentfor...下⾯的代码会输出什么,并说明原 funcfuncmain()wg:=sync.WaitGroup{}fori:=0;i<10;i++{gofunc(){fmt.Println("i:",i)fori:=0;i<10;i++{gofunc(iint){fmt.Println("i:",i)这个输出结果决定来⾃于调度器优先调度哪个G。从runtim的源码可以看到,当创建⼀个G个调度的runnext字段上作为下⼀次优先调度的G。因此,最先输出的是最后创建的G,也就是funcfuncnewproc(sizint32,fn*funcval)argp:=add(unsafe.Pointer(&fn),sys.PtrSize)gp:=getg()pc:=getcallerpc()systemstack(func(){newg:=newproc1(fn,argp,siz,gp,_p_:=runqput(_p_,newg,true)ifmainStartedifnextoldnext:=//当next是true时总会将新进来的Gif!_p_.runnext.cas(oldnext,guintptr(unsafe.Pointer(gp))){gotoretryNextififoldnext==0//Kicktheoldrunnextouttotheregularrunqueue.gp=oldnext.ptr()下⾯代码会输出什么 typetypePeoplefunc(p*People)ShowA()func(p*People)ShowB(){typeTeacherstructfunc(t*Teacher)ShowB()fmt.Println("teacherfuncmain()t:=Teacher{}输出结果为showA、showB。golang此,*Teacher
下⾯代码会触发异常吗?请详细说 funcfuncmain(){int_chan:=make(chanint,1)string_chan:=make(chanstring,1)int_chan<-1string_chan<-"hello"select{casevalue:=<-int_chan:casevalue:=<-string_chan:结果是随机执⾏。golang在多个case下⾯代码输出什么 funcfunccalc(indexstring,a,bint)intret:=a+bfmt.Println(index,a,b,ret)returnretfuncmain()a:=b:=defercalc("1",a,calc("10",a,b))a=0defercalc("2",a,calc("20",a,b))b=1101210122002202113在定义的时候会计算好调⽤函数的参数,所以会优先输出10、20请写出以下输⼊内 funcfuncmain()s:=make([]int,s=append(s,1,2,3)输出为00000123在初始化切⽚时指定了⻓度,所以追加数据时会从len(s)下⾯的代码有什么问题 typetypeUserAgesstructagesmap[string]intfunc(ua*UserAges)Add(namestring,ageint)deferua.Unlock()ua.ages[name]=agefunc(ua*UserAges)Get(namestring)intifage,ok:=ua.ages[name];ok{returnagereturn-在执⾏Get⽅法时可能被thorw虽然有使⽤sync.Mute做写锁,但是ma是并发读写不安全的。ma过指针访问同⼀个地址,即访问共享变量,此时同时读写资源存在竞争关系。会报错误信息:“faalrrr:concurrentmapradandmapwri。因此, 中也需要加锁,因为这⾥只是读,建议使⽤读写锁sync.RWMutex下⾯的迭代会有什么问题 funcfunc(set*threadSafeSet)Iter()<-chaninterface{}{ch:=make(chaninterface{})gofunc(){forforelem:=rangeset.sch<-return
以下代码能编译过去吗?为什么 packagepackageimporttypePeopleinterfaceSpeak(string)typeStudentfunc(stu*Student)Speak(thinkstring)(talkstring)ifthink=="bitch"talk="Youareagood}elsetalk=funcmain()varpeoPeople=Student{}think:="bitch"
未实现接⼝People的⽅法,不能定义为People在golang语⾔中,Student和
以下代码打印出来什么内容,说出为什么 packagepackageimporttypePeopleinterfacetypeStudentfunc(stu*Student)Show()funclive()Peoplevarstu*Studentreturnstufuncmain()iflive()==nil{}else{跟上⼀题⼀样,不同的是*Student
是nil的,但是*Student现 接⼝,接⼝不为nil goroutinegochannelchannel中读取数字这是⼀道很简单的golang在golang⽆缓冲情况下,读写都是阻塞的,且可以⽤for循环来读取数据,当管道关闭后,forgolang中有专⽤的selectcase语法从管道读取数据。funcfuncmain()out:=make(chanint)wg:=sync.WaitGroup{}gofunc()deferfori:=0;i<5;i++{out<-rand.Intn(5)gofunc()deferfori:=rangeout{实现阻塞读且并发安全的 GO⾥⾯MAP如何实现key不存在get操作等待直到keytypetypespinterfaceOut(keystring,valinterface{})//存⼊key/val,如果该key读取的goroutine挂起,则唤醒。Rd(keystring,timeouttime.Duration)interface{}//读取⼀个key,如果key不存在阻塞,等看到阻塞协程第⼀个想到的就是channel,题⽬中要求并发安全,那么必须⽤锁,还要实现多个goroutine时候如果值不存在则阻塞,直到写⼊值,那么每个键值需要有⼀个阻塞goroutine的channel。typetypeMapstruct rmx*sync.RWMutextypeentrystruct chan isExistfunc(m*Map)Out(keystring,valinterface{})deferm.rmx.Unlock()item,ok:=m.c[key]if!ok{m.c[key]=&entry{value:val,isExist:true,item.value=valif!item.isExist{ifitem.ch!=nil{item.ch=nil⾼并发下的锁与map的读 场景:在⼀个⾼并发的we服务器中,要限制P的频繁访问。现模拟10个P同时并发访问服务器,每个P访问100次。每个IP三分钟之内只能访问⼀次。修改以下代码完成该过程,要求能成功输出packagepackageimport(typeBanstructvisitIPsfuncNewBan()*Banreturn&Ban{visitIPs:func(o*Ban)visit(ipstring)bool{if_,ok:=o.visitIPs[ip];ok{returno.visitIPs[ip]=time.Now()returnfalsefuncmain(){success:=0ban:=NewBan()fori:=0;i<1000;i++{forj:=0;j<100;j++{gofunc()ip:=fmt.Sprintf("192.168.1.%d",j)if!ban.visit(ip){fmt.Println("success:",该问题主要考察了并发情况下map的读写问题,⽽给出的初始代码,⼜存在for循环中启动goroutine⽤问题以及goroutine因此,⾸先要保证启动的goroutine得到的参数是正确的,然后保证map多CPU核⼼下修改int的值极端情况下会存在不同步情况,因此需要原⼦性的修改int下⾯给出的实例代码,是启动了⼀个协程每分钟检查⼀下map中的过期ip,forpackagepackageimporttypeBanstructvisitIPsmap[string]time.Time funcNewBan(ctxcontext.Context)*Bano:=&Ban{visitIPs:gofunc()timer:=time.NewTimer(time.Minute*1)for{selectcase<-timer.C:fork,v:=rangeo.visitIPsiftime.Now().Sub(v)>=time.Minute*1{delete(o.visitIPs,k)timer.Reset(time.Minute*1)case<-ctx.Done():returnfunc(o*Ban)visit(ipstring)bool{deferif_,ok:=o.visitIPs[ip];ok{returntrueo.visitIPs[ip]=time.Now()returnfalsefuncmain()success:=ctx,cancel:=context.WithCancel(context.Background())defercancel()ban:=wait:=wait.Add(1000*fori:=0;i<1000;i++{forj:=0;j<100;j++{gofunc(jint){deferwait.Done()ip:=fmt.Sprintf("192.168.1.%d",j)if!ban.visit(ip){atomic.AddInt64(&success,fmt.Println("success:",写出以下逻辑,要求每秒钟调⽤⼀次proc并保证程序不退 packagepackagefuncmain()gofunc()//1//2要求每秒钟调⽤⼀次proc//3selectfuncproc()panic题⽬中要求每秒钟执⾏⼀次,⾸先想到的就是time.Ticker对象,该函数可每秒钟往chan中放⼀个Time,正好
packagepackageimportfuncmain()gofunc()12要求每秒钟调⽤⼀次proc33t:=time.NewTicker(time.Second*forselect{case<-t.C:gofunc(){deferfunc(){iferr:=recover();err!=nil{selectfuncproc()packagepackageimportfuncmain()wg:=c:=make(chanstruct{})fori:=0;i<10;i++{gofunc(numint,close<-chanstruct{}){deferwg.Done()}(i,ififWaitTimeout(&wg,time.Second*5)fmt.Println("timeoutexit")time.Sleep(time.Second*funcWaitTimeout(wg*sync.WaitGroup,timeouttime.Duration)bool要求sync.WaitGroup⽀持timeout//如果timeout到了超时时间返回//如果WaitGroup⾃然结束返回
函数本身是阻塞的,同时,超时⽤到的time.Timer同时阻塞的两个对象肯定要每个启动⼀个协程,⽬前我⽤的⽅式是声明⼀个没有缓冲的chanpackagepackageimportfuncmain()wg:=c:=make(chanstruct{})fori:=0;i<10;i++{gofunc(numint,close<-chanstruct{}){deferwg.Done()}(i,ifWaitTimeout(&wg,time.Second*5)fmt.Println("timeoutexit")time.Sleep(time.Second*funcWaitTimeout(wg*sync.WaitGroup,timeouttime.Duration)bool要求sync.WaitGroup⽀持timeout//如果timeout到了超时时间返回如果WaitGroup⾃然结束返回ch:=make(chanbool,gotime.AfterFunc(timeout,func()ch<-gofunc()ch<-falsereturn<-写出以下代码出现的问 packagepackagemainimport(funcmain()varxstring=nilifx==nil{x=golang
写出以下打印内 packagepackagemainimport"fmt"const(a=b=constname= = =funcmain()找出下⾯代码的问 packagepackageimporttypequeryfunc(string)funcexec(namestring,vs...query)stringch:=make(chanstring)fn:=func(iint){ch<-fori,_:=rangevs{gofn(i)return<-funcmain()ret:=exec("111",func(nstring)string{returnn+"func1"},func(nstring)string{returnn+"func2"},func(nstring)string{returnn+"func3"},func(nstring)string{returnn+"func4"上⾯的代码有严重的内存泄漏问题,出错的位置是gofn(i),实际上代码执⾏后会启动4个协程,但是因为写出以下打印结果,并解释下为什么这么打印的 packagepackagemainimport(funcmain()str1:=[]string{"a","b","c"}str2:=str1[1:]str2[1]="new"str2=append(str2,"z","x","y")str2[1]=golang中的切⽚底层其实使⽤的是数组。当使⽤str1[1:]使,str2和语句影响str1。str2[1]=
不会影响str1
复制后影响的确实str1
始,str2索引为1的元素对应的 索引为2的元素写出以下打印结 packagepackageimporttypeStudentstructNamefuncmain()fmt.Println(&Student{Name:"menglu"}==&Student{Name:"menglu"})fmt.Println(Student{Name:"menglu"}==Student{Name:"menglu"})写出以下代码的问 packagepackageimportfuncmain()fmt.Println([...]string{"1"}==fmt.Println([]string{"1"}==下⾯代码写法有什么问题 packagepackagemainimport(typeStudentstruct{Ageintfuncmain()kv:=map[string]Student{"menglu":{Age:21}}kv["menglu"].Age=22s:=[]Student{{Age:21}}s[0].Age=22fmt.Println(kv,golang中的map通过key获取到的实际上是两个值,第⼀个是获取到的值,第⼆个是是否存在该key。因此不能直接通过key来赋值对象。 packagepackagemainimport(varmusync.Mutexvarchainstringfuncmain(){chain="main"funcfuncA()deferchain=chain+"-->A"funcB()chain=chain+"-->B"funcC()deferchain=chain+"-->A:不能编译B输出mainABCC:输出mainD:panic会产⽣死锁panic,因为Mutex packagepackagemainimport(varmusync.RWMutexvarcountintfuncmain(){goA()time.Sleep(2*time.Second)defermu.Unlock()funcA(){defermu.RUnlock()funcB()timetime.Sleep(5*time.Second)funcC(){deferA:不能编译B:输出1C:程序hang住D:panic会产⽣死锁panic,根据sync/rwmutex.go中注释可以知道,读写锁当有⼀个协程在等待写锁时,其他协程是不能获得读锁的,⽽在A和C中同⼀个调⽤链中间需要让出读锁,让写锁优先获取,⽽A的读锁⼜要求C调⽤完成, packagepackagemainimport(funcmain()varwgsync.WaitGroupgofunc(){A:不能编译B:⽆输出,正常退出C:程序hang住D:panic
双检查实现单 packagepackageimportimport(typeOncestruct{ doneuint32func(o*Once)Do(ffunc()){ifo.done==1{defero.m.Unlock()ifo.done==0{o.done=1A:不能编译B:可以编译,正确实现了单例C:可以编译,有并发问题,f函数可能会被执⾏多次D:可以编译,但是程序运⾏会panic在多核CPU中,因为CPU packagepackagemainimport(typeMyMutexstruct{countintfuncmain(){varmuMyMutexvarmu2=mufmt.Println(mu.count,A:不能编译B:输出1,1C:输出1,2D:panic加锁后复制变量,会将锁的状态也复制,所以mu1 packagemainimport(varpool=sync.Pool{New:func()interface{}{returnnew(bytes.Buffer)}}funcmain(){gofunc(){for{processRequest(1<<28)//fori:=0;i<1000;i++{gofunc(){forprocessRequest(1<<10)//varstatsruntime.MemStatsfori:=0;;i++{fmt.Printf("Cycle%d:%dB\n",i,stats.Alloc)funcprocessRequest(sizeint)b:=pool.Get().(*bytes.Buffer)time.Sleep(500*time.Millisecond)time.Sleep(1*A:不能编译B:可以编译,运⾏时正常,内存稳定C:可以编译,运⾏时内存可能暴涨D:可以编译,运⾏时内存先暴涨,但是过⼀会会回收掉个⼈理解,在单核CPU中,内存可能会稳定在256MB packagepackagemainimport(funcmain()varchchanintgofunc(){ch=make(chanint,1)ch<-1gofunc(chchanint){<-c:=time.Tick(1*time.Second)forrangec{fmt.Printf("#goroutines:%d\n",A:不能编译#goroutines:B:⼀段时间后总是输出#goroutines:#goroutines:C:⼀段时间后总是输出#goroutines:D:panic因 未初始化,写和读都会阻塞,之后被第⼀个协程重新赋值,导致写的ch都阻塞 packagepackagemainimport"fmt"funcmain(){varvarchchanvarcountintgofunc(){ch<-gofunc(){A:不能编译B:输出1C:输出0D:panic packagepackagemainimport(funcmain(){varmsync.Mapm.LoadOrStore("a",1)A:不能编译B:输出1C:输出0D:panicsync.Map没有Len`happens packagevarcpackagevarc=make(chanint)varaintfuncf(){a=1<-funcmain(){gof()c<-A:不能编译B:输出1C:输出0D:panicc<-会阻塞依赖 的执⾏c<- 读已经关闭的chan能⼀直读到东⻄,但是读到的内容根据通道内关闭前是否有元素⽽不同。chan关闭前,bufferchanbool值(是否读成功)为true。chan关闭前,buffer内有元素已经被读完,chan内⽆值,接下来所有接收的值都会⾮阻塞直接成功,返回channel元素的零值,但是第⼆个bool值⼀直为false。写已经关闭的chan会panic写已经关闭的funcfuncc:=make(chanint,3)c<-//panic:sendonclosedgoroutine1注意这个sendonclosedchannel,待会会提到。读已经关闭的packagemainimportfuncmain()ci:=make(chanint,3)num,ok:=<-fmt.Printf("读chan的协程结束,num=%v,ok=%v\n",num,ok)num1,ok1:=<-cifmt.Printf("再读chan的协程结束,num=%v,num2,ok2:=<-fmt.Printf("再再读chan的协程结束,num=%v,cs:=make(chanstring,3)cs<-"aaa"str,ok:=<-csfmt.Printf("读chan的协程结束,str=%v,str1,ok1:=<-fmt.Printf("再读chan的协程结束,str=%v,ok=%v\n",str1,ok1)str2,ok2:=<-csfmt.Printf("再再读chan的协程结束,str=%v,typeMyStructstruct{Namecstruct:=make(chanMyStruct,3)cstruct<-MyStruct{Name:"haha"}stru,ok:=<-fmt.Printf("读chan的协程结束,stru=%v,ok=%v\n",stru,ok)stru1,ok1:=<-csfmt.Printf("再读chan的协程结束,stru=%v,stru2,ok2:=<-fmt.Printf("再再读chan的协程结束,stru=%v,以下是数值的读以下是数值的读chan的协程结束,num=1,再读chan的协程结束,num=0,ok=false再再读chan的协程结束,num=0,ok=false读chan的协程结束,str=aaa,ok=true再读chan的协程结束,str=,ok=false再再读chan的协程结束,str=,ok=false读chan的协程结束,stru={haha},再读chan的协程结束,stru=,再再读chan的协程结束,stru=,
就 呢onclosedchannel"//在funcchansend(c*onclosedchannel"//在funcchansend(c*hchan,epunsafe.Pointer,blockbool,callerpcuintptr)bool//ifc.closed!=0{panic(plainError("sendonclosed//c.closed!=为什么读已关闭的chanfuncfuncchanrecv(c*hchan,epunsafe.Pointer,blockbool)(selected,receivedbool)//当chan//ep是指val,ok:=<-c⾥的valifc.closed!=0&&c.qcount==0{ifreceenabled{////typedmemclr//这就解释了上⾯代码为什么关闭的chanifep!=null{//返回两个参数//第⼆个采纳数就是val,ok:=<-c⾥的//也就解释了为什么读关闭的chan会⼀直返回returnc.closed!=0&&c.qcount==的值c.closed!=0&&c.qcount==
指通道已经关闭,且缓存为空的情况下(那接收值将获得是⼀个该类型的零值这就解释了上⾯代码为什么关闭的chan会返回对应类型的零值 funcmain()funcmain()nil:=123var_map[string]int=4⾏nilnilintmap下⾯代码输出什么 funcmain()funcmain()varxint8=-128vary=x/-1字符串转成byte数组,会发⽣内存拷⻉吗 packagepackageimportfuncmain()assh:=*(*reflect.StringHeader)(unsafe.Pointer(&a))b:=*(*[]byte)(unsafe.Pointer(&ssh))是字符串在gotypetypeStringHeaderstruct{DatauintptrLen是切⽚在gotypetypeSliceHeaderstruct{DatauintptrLenCap那么如果想要在底层转换⼆者,只需要把StringHeader的地址强转成SliceHeader就⾏。那么gounsafeunsafe.Pointer(&a)⽅法可以得到变量a再通过*
sync.Map的⽤ packagepackageimportfuncvarmv,_:=m.Load("address")A,江苏;B,v["province"]取值错误;C,m.Store存储错误;D,不知道invalidoperation:v["province"](typeinterface{}doesnotsupportinvalidoperation:v["province"](typeinterface{}doesnotsupportfunc(m*Map)Store(keyinterface{},valuefunc(m*Map)Store(keyinterface{},valueinterface所以vinterface
fmtfmt.Println(v.(map[string]string)["province"//下⾯代码输出什么 funcmain()funcmain()x:=[]string{"a","b","c"}forv:=rangex{funcmain()funcmain()x:=[]string{"a","b","c"}for_,v:=rangex{ //输出下⾯这段代码能否编译通过?如果通过,输出什么 typeUsertypeUser1UsertypeUser2=Userfunc(iUser)m1()func(iUser)m2(){funcmain()vari1typeUsertypeUser1UsertypeUser2=Userfunc(iUser)m1()func(iUser)m2(){funcmain()vari1User1vari2User22UserUser13UserUser2定义User2UserUser2Useri1.m1(是不能执⾏的,因为User1没有定义该⽅法。 ⽆缓冲的channel是默认的缓冲为1的⽆缓冲的channel和有缓冲的channel⽆缓冲的channel和有缓冲的channel⽆缓冲的channel是同步的,⽽有缓冲的channel下⾯代码是否能编译通过?如果通过,输出什么 funcfuncFoo(xinterface{}){ifx==nil{fmt.Println("emptyinterface")fmt.Println("non-emptyfuncmain()varx*int=nil考点:inrface型都为l时,接⼝类型值才为l。这⾥的x的动态类型是*int,所以x不为l。下⾯代码输出什么 funcmain()funcmain()ch:=make(chanint,//gofunc()fori:=0;i<10;i++{ch<-i//gofunc()fora,ok:=<-chif!ok{fmt.Println("a:",time.Sleep(time.Second*先定义下,第⼀个协程为A协程,第⼆个协程为B协程;当A协程还没起时,主协程已经将channelA协程往关闭的channel发送数据时会panic,panic:sendonclosedchannel select机制⽤来处理异步IOselect机制最⼤的⼀条限制就是每个case语句⾥必须是⼀个IOgolang在语⾔级别⽀持selectselect关键字的⽤法与switch下⾯的代码有什么问题 funcfuncStop(stop<-chanbool){答:有⽅向的channel下⾯这段代码存在什么问题 typeParamtypeParamtypeShowstructfuncmain()s:=new(Show)s.Param["day"]=2mapfuncmain()funcmain()s:=p:=make(Param)p["day"]=2s.Param=&ptmp:=*s.Param下⾯代码编译能通过吗 funcfuncfmt.Println("hellosyntaxerror:unexpectedsemicolonornewlinebeforesyntaxerror:unexpectedsemicolonornewlinebeforeGo语⾔中,⼤括号不能放在单独的⼀⾏。funcmain()funcmain()下⾯这段代码输出什么 varx=[]int{2:2,3,0:varx=[]int{2:2,3,0:funcmain()字⾯量初始化切⽚时候,可以指定索引,没有指定索引的元素会在前⼀个索引基础之上加⼀,所以输出[103],⽽不是[132]下⾯这段代码输出什么 funcincr(p*int)intfuncincr(p*int)intreturn*pfuncmain(){v:=1p是指针变量,指向变量v,*p++操作的意思是取出变量v的值并执⾏加⼀操作,所以v的最终值是2请指出下⾯代码的错误 packagepackagevargvarfuncmain()varoneinttwo:=2varthreethree=func(unusedstring)fmt.Println("Unusedarg.Nocompile答:变量one、two和three声明未使⽤知识点:未使⽤变量函数的参数未使⽤也是可以的。愉快的编译。funcmain()funcmain()varone_=_=two:=varthreethree=3one=threevarfourfour=另⼀个选择是注释掉或者移除未使⽤的变量。下⾯代码输出什么 typeConfigOnestructtypeConfigOnestructDaemonfunc(c*ConfigOne)String()stringreturnfmt.Sprintf("print:%v",funcmain()c:=&ConfigOne{}如果类型实现String()⽅法,当格式化输出时会⾃动使⽤String()⽅法。上⾯这段代码是在该类型的String()⽅法runtime:runtime:goroutinestackexceeds1000000000-bytelimitfatalerror:stackoverflow下⾯代码输出什么 funcmain()funcmain()vara=[]int{1,2,3,4,5}varr=make([]int,0)fori,v:=rangeaifi==0a=append(a,6,a=append(a,6,r=append(r,aforrange过程中增加了两个元素,len5增加到7forrange时会使⽤aalen5forrange5a5下⾯的代码有什么问题 importimportfuncmain()如果你真的需要引⼊包,可以使⽤下划线操作符,_importimport_var_=log.Printlnfuncmain(){_=下⾯代码输出什么 funcmain()x:=funcmain()x:=interface{}(nil)y:=(*int)(nil)a:=y==b:=y==_,c:=x.(interface{})println(a,b,c)falsetruetruetruefalsetrue类型断⾔语法:i.(Type),其中i是接⼝,Type是类型或接⼝。编译时会⾃动检测i的动态类型与Type是否⼀致。下⾯代码有⼏处错误的地⽅?请说明原因 funcmain()funcmain()varss=varmm["one"]=1处错误1nilmapmake(appendnilfuncmain()funcmain()varmm=make(map[string]int)m["one"]=1下⾯代码有什么问题 funcmain()funcmain()m:=make(map[string]int,2)capmap的容量使⽤make创建mapcap()函数适⽤于数组、数组指针、slicechannelmaplenmap的元素个下⾯的代码有什么问题 funcmain()funcmain()varx=_=nilinterface、函数、maps、sliceschannels的“零值”。如果不指定变量的类型,编译器猜不出变量funcmain()funcmain()varxinterface{}=_=下⾯代码能编译通过吗 typeinfostructtypeinfostructresultfuncwork()(int,error)returnfuncmain()vardatadata.result,err:=fmt.Printf("info:non-namedata.resultonleftsideofnon-namedata.resultonleftsideoffuncmain()funcmain()vardatavarerrdata.result,err=work()//okiferr!=nil{下⾯代码有什么错误 funcmain()funcmain()one:=one:=的。funcmain()funcmain()one:=one,two:=1,2one,two=two,one下⾯代码有什么问题 funcmain()funcmain()x:=[]int{_=第四⾏代码没有逗号。⽤字⾯量初始化数组、slice和mapfuncmain()funcmain():= //x=[]int{3,4,}⼀⾏noerrory=y下⾯代码输出什么 functest(xbyte)functest(xbyte)funcmain()varabyte=0x11varbuint8=avarcuint8=a+b与rune是int32的别名⼀样,byte是uint8下⾯的代码有什么问题 funcmain()funcmain()constx=123consty=1.23下⾯代码输出什么 constconstxuint16=120s="abc"funcmain()fmt.Printf("%T%v\n",y,y)fmt.Printf("%T%v\n",z,uint16uint16120string下⾯代码有什么问题 funcmain()funcmain()varxstring=ifx==nilx=答:将nil分配给stringfuncmain()funcmain()varxstring//defaultsto""(zeroifx==""x=下⾯的代码有什么问题 funcmain()funcmain()data:=[]int{1,2,3}i:=0⾃增、⾃减不在是运算符,只能作为独⽴语句,⽽不是表达式;不像其他语⾔,Go语⾔中不⽀持++i和--i操作;表达式通常是求值代码,可作为右值或参数使⽤。⽽语句表示完成⼀个任务,⽐如f、fr语句使⽤,但语句不能当做表达式。funcmain()funcmain()data:=[]int{1,2,3}i:=0下⾯代码最后⼀⾏输出什么?请说明原因 funcfuncmain(){x:=1i,x:=2,2fmt.Println(x)//print答:输出使⽤变量简短声明符号:=变量尽进⾏赋值操作。但如果出现作⽤域之后,就会导致变量隐藏的问题,就像这个例⼦⼀样。这个坑很容易挖,但⼜很难发现。即使对于经验丰富的Go下⾯代码有什么问题 typefoostructtypefoostructbarfuncmain()varff.bar,tmp:=1,non-namef.baronleftsideofnon-namef.baronleftsideof下⾯的代码输出什么 funcmain()funcmain()invalidcharacterU+007EinvalidcharacterU+007E很多语⾔都是采 作为按位取反运算符,Go⾥⾯采⽤的是^。按位取反之后返回⼀个每个bit位都取反的数对于有符号的整数来说,是按照补码进⾏取反操作的(快速计算⽅法:对数a取反,结果为-(a+1)),对于⽆符号funcmain()funcmain()varaint8=3varbuint8=3varcint8=-fmt.Printf("^%b=%b%d\n",a,^a,^a)//^11=-100-fmt.Printf("^%b=%b%d\n",b,^b,^b)//^11=11111100252fmt.Printf("^%b=%b%d\n",c,^c,^c)//^-11=102另外需要注意的是,如果作为⼆元运算符,^表示按位异或,即:对应位相同为0,相异为1funcmain()funcmain()varaint8=3varcint8=fmt.Printf("a:fmt.Printf("c:%08b\n",c)fmt.Printf("a^c:%08b\n",a^c)&^,按位置零,例如:zx&^yybit1zbit0z对应bit位等于x中相应的bit不知道⼤家发现没有,我们还可以这样理解或操作符|,表达式z=x|y,如果y中的bit位为1,则z对应bit位1zbitxbit&^完全相反。varvarxuint8=214varyuint8=92fmt.Printf("x:%08b\n",x)fmt.Printf("y:%08b\n",y)fmt.Printf("x|y:%08b\n",x|y)fmt.Printf("x&^y:%08b\n",x&^y)x:x:y:x|y:x&^y:下⾯代码输出什么 funcmain()funcmain()varchchanintselect{casev,ok:=<-ch:println(v,ok)chnil下⾯这段代码输出什么 typePeoplestructtypePeoplestructnamestringfuncmain()js:=varperr:=json.Unmarshal([]byte(js),&p)iferr!=nil{fmt.Println("err:",err)答:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年滁州职业技术学院高职单招职业适应性考试参考题库带答案解析
- 2026年上交所期权基础知识练习题库含答案
- 2026年电商运营招聘笔试模拟题及标准全解含答案
- 2026年建筑防火规范考试复习指南含答案
- 2026年福建体育职业技术学院单招职业技能考试备考试题带答案解析
- 2026年新团员入团培训团课考试题库含答案
- 2026年系统架构师岗位面试高并发系统设计思路含答案
- 2026年政府法治综合测试题与解答
- 2026年甘肃能源化工职业学院高职单招职业适应性测试模拟试题带答案解析
- 2026年心理咨询师案例分析技巧测验含答案
- 山东省潍坊市2023-2024学年高一上学期1月期末考试英语试题 含解析
- 农村个人土地承包合同模板
- 2025届北京市海淀区一零一中学数学七年级第一学期期末综合测试模拟试题含解析
- 初中道德与法治课中提升学生政治认同素养的策略研究
- 糖尿病的急救和护理
- 中医养生的吃野山参粉养生法
- 小学道德与法治-认识居民身份证教学课件设计
- 采购灭火器施工方案
- 小学生古诗词大赛备考题库(300题)
- GB/T 25085.3-2020道路车辆汽车电缆第3部分:交流30 V或直流60 V单芯铜导体电缆的尺寸和要求
- GB/T 242-2007金属管扩口试验方法
评论
0/150
提交评论