1、go中拼接字符串有几种方式

1、"+"

最常用的方法就是,使用"+"将两个字符串进行连接,与Python类似,不过Go语言中的字符串是不可变的类型,因此用"+"进行连接会产生一个新的字符串,这样对效率会有所影响。

a := "字符串"
b := "拼接"
c := a+b
fmt.Print(c) //c = "打印字符串"

2、使用sprintf函数

第二种方法,就是使用sprintf函数,虽然不会像直接使用+那样产生临时的字符串,但效率也不高。

a := "字符串"
b := "拼接"
c := fmt.Sprintf("%s%s", a, b) //c = "打印字符串"

3、使用Join函数

第三种方法就是,使用Join函数,这里需要先引入strings包才能调用Join函数,此函数会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,如果没有的话效率也不高。

//需要先导入strings包
a := "字符串"
b := "拼接"
//定义一个字符串数组包含上述的字符串
var str []string = []string{a, b}
//调用Join函数
c := strings.Join(str, "")
fmt.Print(c)

4、调用buffer.WriteString函数

第四种方法就是,调用buffer.WriteString函数,此方法的性能要远远大于上面的方法。

//需要先导入bytes包
a := "字符串"
b := "拼接"
//定义Buffer类型
var bt bytes.Buffer
向bt中写入字符串
bt.WriteString(a)
bt.WriteString(b)
//获得拼接后的字符串
c := bt.String()

5、用buffer.Builder

第五种方法是用buffer.Builder,此方法和上面的差不多,不过官方建议使用这个,且使用方法和上面基本一样。

//需要先导入Strings包
a := "字符串"
b := "拼接"
var build strings.Builder
build.WriteString(a)
build.WriteString(b)
c := build.String()

2、go中"_"的作用

1、import中的下滑线

此时“_”的作用是:当导入一个包的时候,不需要把所有的包都导进来,只需要导入使用该包下的文件里所有的init()的函数。

package mainimport _ "hello/imp"func main() {//imp.Print() //编译报错,说:undefined: imp

2、下划线在代码中
作用是:下划线在代码中是忽略这个变量

也可以理解为占位符,那个位置上本应该赋某个值,但是我们不需要这个值,所以就把该值给下划线,意思是丢掉不要,这样编译器可以更好的优化,任何类型的单个值都可以丢给下划线。

如果方法返回两个值,只想要其中的一个结果,那另一个就用_占位

package mainimport "fmt"v1, v2, _ := function(...)

3、占位符

"_"是特殊标识符,用来忽略结果

3、使用go实现99乘法表

 for i := 1; i < 10; i++ {for j := 1; j <= i; j++ {fmt.Printf("%d*%d=%d ", j, i, i*j)}fmt.Println("")}结果:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 

4、linux命令,查看端口占用,cpu负载,内存占用,如何发送信号给一个进程、修改文件权限

  Linux 查看端口占用情况:lsof -i:端口号netstat -tunlp | grep 端口号cpu负载:uptime内存占用:top如何发送信号给一个进程:1. kill() 函数2. alarm() 函数修改文件权限:chmod命令用于修改文件权限

5、Redis redo log, binlog 与 undo log

redo log是属于innoDB层面,binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。
redo log是物理日志,记录该数据页更新的内容;binlog是逻辑日志,记录的是这个更新语句的原始逻辑
redo log是循环写,日志空间大小固定;binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。
binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

1.redo log通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
2.undo用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。

6、使用三个协程,每秒钟打印cat dog fish

使用三个协程,每秒钟打印cat dog fish
注意:1、顺序不能变化(协程1打印cat,协程2打印dog,协程3打印fish)2、无限循环即可
/*
使用三个协程,每秒钟打印cat dog fish
注意:顺序不能变化(协程1打印cat,协程2打印dog,协程3打印fish)
无限循环即可
*/
func main() {wg := sync.WaitGroup{}wg.Add(3)chcat := make(chan int)chdog := make(chan int)chfish := make(chan int)go printCat(&wg, chcat, chfish)go printDog(&wg, chdog, chcat)go printfash(&wg, chfish, chdog)wg.Wait()
}
func printDog(wg *sync.WaitGroup, dog chan int, cat chan int) {defer wg.Done()for {<-catfmt.Println("dog")time.Sleep(time.Second)dog <- 1}
}
func printCat(wg *sync.WaitGroup, cat chan int, fish chan int) {defer wg.Done()for {cat <- 1fmt.Println("cat")time.Sleep(time.Second)<-fish}
}
func printfash(wg *sync.WaitGroup, fish chan int, dog chan int) {defer wg.Done()for {<-dogfmt.Println("fish")time.Sleep(time.Second)fish <- 1}
}

7、Go出现panic的场景

go中发生panic的场景:
- 数组/切片越界
- 空指针调用。比如访问一个 nil 结构体指针的成员
- 过早关闭 HTTP 响应体
- 除以 0
- 向已经关闭的 channel 发送消息
- 重复关闭 channel
- 关闭未初始化的 channel
- 未初始化 map。注意访问 map 不存在的 key 不会 panic,而是返回 map 类型对应的零值,但是不能直接赋值
- 跨协程的 panic 处理
- sync 计数为负数。
- 类型断言不匹配。`var a interface{} = 1; fmt.Println(a.(string))` 会 panic,建议用 `s,ok := a.(string)`

8、Http是短连接还是长连接?

  • HTTP/1.0中,默认使用的其实是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就要建立一次连接,但任务结束后就会中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话;
  • 从HTTP/1.1起,默认使用长连接,用以保持会话的连接特性。使用长连接的HTTP协议,会在响应头中加入这行代码:Connection:keep-alive;
  • 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立好的连接。但Keep-Alive也不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。我们要注意,实现长连接要客户端和服务端都支持长连接。
  • TCP三次握手和四次挥手过程

    既然上面我们说到了三次握手和四次挥手,健哥就再扩展一下说说这两个操作的实现过程。

    三次握手:先向HTTP服务器发起TCP的确认请求

  • 客户端 --> SYN --> 服务器
  • 服务器 --> SYN+ACK --->客户端
  • 客户端 --> ACK --> 服务器
  • 四次挥手:客户端要和服务器断开TCP连接

  • 客户端 --> FIN +ACK ---> 服务器
  • 服务器 --> FIN ---> 客户端
  • 服务器 --> ACK --> 客户端
  • 客户端 --> ACK ---> 服务器

总结

1、Http协议到底是长连接还是短连接,要看HTTP协议的版本,Http1.0中默认是短连接,      2、 Http1.1中默认是长连接;

3、 Http协议位于OSI网络模型的应用层;

4、Http协议底层在传输层上使用的是TCP协议,在网络层使用的是IP协议;

5、TCP协议具有三次握手和四次挥手的过程,传输数据安全稳定。

9、liunx协程和线程初始申请内存大小

协程初始化创立的时候为其调配的栈有2KB。而线程栈要比这个数字大的多,能够通过ulimit 命令查看,个别都在几兆,作者的机器上是10M。如果对每个用户创立一个协程去解决,100万并发用户申请只须要2G内存就够了,而如果用线程模型则须要10T。

协程和线程默认申请的内存是堆内存

10、go面试题实现一个内存缓存系统

面试题内容
1、支持设定过期时间,精度到秒
2、支持设定最大内存,当前超出时做出合适的处理
3、支持并发安全
4、按照以下接口要求实现
type Cache interface {//size:1KB 100KB 1MB 2MB 1GBSetMaxMemory(size string) bool//将value写入缓存Set(key string, val interface{}, expire time.Duration) bool//根据key值获取valueGet(key string) (interface{}, bool)//删除keyDel(key string) bool//判断key是否存在Exists(key string) bool//清空所有keyFlush() bool//获取缓存中所有key的数量Keys() int64
}

1、util.go文件中代码

package cacheimport ("encoding/json""log""regexp""strconv""strings"
)const (B = 1 << (iota * 10)KBMBGBTBPB
)func ParseSize(size string) (int64, string) {//默认大小为100MBre, _ := regexp.Compile("[0-9]+")unit := string(re.ReplaceAll([]byte(size), []byte("")))num, _ := strconv.ParseInt(strings.Replace(size, unit, "", 1), 10, 64)unit = strings.ToUpper(unit)var byteNum int64 = 0switch unit {case "B":byteNum = numcase "KB":byteNum = num * KBcase "MB":byteNum = num * MBcase "GB":byteNum = num * GBcase "TB":byteNum = num * TBcase "PB":byteNum = num * PBdefault:num = 0byteNum = 0}if num == 0 {log.Println("ParseSize 仅支持B KB MB GB TB PB")num = 100unit = "MB"byteNum = num * MB}sizeStr := strconv.FormatInt(num, 10) + unitreturn byteNum, sizeStr
}
func GetValSize(val interface{}) int64 {bytes, _ := json.Marshal(val)size := int64(len(bytes))return size
}

2、cache.go

package cacheimport "time"type Cache interface {//size:1KB 100KB 1MB 2MB 1GBSetMaxMemory(size string) bool//将value写入缓存Set(key string, val interface{}, expire time.Duration) bool//根据key值获取valueGet(key string) (interface{}, bool)//删除keyDel(key string) bool//判断key是否存在Exists(key string) bool//清空所有keyFlush() bool//获取缓存中所有key的数量Keys() int64
}

3、memCache.go

package cacheimport ("fmt""log""sync""time"
)type memCache struct {//最大内存maxMemorySize int64//最大内存字符串表示maxMemorySizeStr string//当前已使用内存currencyMemorySize int64//缓存健值对values map[string]*memCacheValue//读写锁locker sync.RWMutex//清除过期缓存时间间隔clearExpireItemTimeInterval time.Duration
}
type memCacheValue struct {//value值val interface{}//过期时间expireTime time.Time//有效时长expire time.Duration//value 大小size int64
}func NewMemCache() Cache {mc := &memCache{values:                      make(map[string]*memCacheValue),clearExpireItemTimeInterval: time.Second * 10,}//go mc.clearExpireItem()return mc
}//size:1KB 100KB 1MB 2MB 1GB
func (mc *memCache) SetMaxMemory(size string) bool {mc.maxMemorySize, mc.maxMemorySizeStr = ParseSize(size)return true
}//将value写入缓存
func (mc *memCache) Set(key string, val interface{}, expire time.Duration) bool {mc.locker.Lock()defer mc.locker.Unlock()v := &memCacheValue{val:        val,expireTime: time.Now().Add(expire),expire:     expire,size:       GetValSize(val),}mc.del(key)mc.add(key, v)if mc.currencyMemorySize > mc.maxMemorySize {mc.del(key)log.Println(fmt.Sprintf("max memory size %d", mc.maxMemorySize))}return true
}
func (mc *memCache) Get(key string) (interface{}, bool) {mc.locker.RLock()defer mc.locker.RUnlock()mcv, ok := mc.values[key]if ok {//判断缓存是否过期if mcv.expire != 0 && mcv.expireTime.Before(time.Now()) {mc.del(key)return nil, false}return mcv.val, ok}return nil, false
}
func (mc *memCache) del(key string) {tmp, ok := mc.get(key)if ok && tmp != nil {mc.currencyMemorySize -= tmp.sizedelete(mc.values, key)}
}
func (mc *memCache) add(key string, val *memCacheValue) {mc.values[key] = valmc.currencyMemorySize += val.size
}//根据key值获取value
func (mc *memCache) get(key string) (*memCacheValue, bool) {val, ok := mc.values[key]return val, ok
}//删除key
func (mc *memCache) Del(key string) bool {mc.locker.Lock()defer mc.locker.Unlock()mc.del(key)return true
}//判断key是否存在
func (mc *memCache) Exists(key string) bool {mc.locker.RLock()defer mc.locker.RUnlock()_, ok := mc.values[key]return ok
}//清空所有key
func (mc *memCache) Flush() bool {mc.locker.Lock()defer mc.locker.Unlock()mc.values = make(map[string]*memCacheValue, 0)mc.currencyMemorySize = 0return true
}//获取缓存中所有key的数量
func (mc *memCache) Keys() int64 {mc.locker.RLock()defer mc.locker.RUnlock()return int64(len(mc.values))
}
func (mc *memCache) clearExpireItem() {timeTicker := time.NewTicker(mc.clearExpireItemTimeInterval)defer timeTicker.Stop()for {select {case <-timeTicker.C:for key, item := range mc.values {if item.expire != 0 && time.Now().After(item.expireTime) {mc.locker.Lock()mc.del(key)mc.locker.Unlock()}}}}
}

4、memCache_test.go

package cacheimport ("testing""time"
)func TestCacheDP(t *testing.T) {testData := []struct {key    stringval    interface{}expire time.Duration}{{"slsd", 678, time.Second * 10},{"dds", 678, time.Second * 11},{"slsddsd", 678, time.Second * 12},{"dsd", map[string]interface{}{"a": 3, "b": false}, time.Second * 13},{"ds", "aadasdasdad", time.Second * 14},{"dsdsd", "这里是的的饿的啊得到", time.Second * 15},}c := NewMemCache()c.SetMaxMemory("10MB")for _, item := range testData {c.Set(item.key, item.val, item.expire)val, ok := c.Get(item.key)if !ok {t.Error("缓存取值失败")}if item.key != "slsddsd" && val != item.val {t.Error("缓存取值数据与预期不一致")}}
}

5、main.go

package mainimport ("fmt"cache_server "test111/cache-server""time"
)func main() {//fmt.Println(dns_reques.DigDomain("127.0.0.1:53", "www.baidu.com"))cache := cache_server.NewMemCache()cache.SetMaxMemory("200GB")cache.Set("aa", 1, 10*time.Second)cache.Set("bb", false, 10*time.Second)cache.Set("data", map[string]interface{}{"a": 1}, 10*time.Second)/*cache.Set("int", 1)cache.Set("bool", false)cache.Set("data", map[string]interface{}{"a": 1})*/fmt.Println(cache.Get("aa"))fmt.Println(cache.Get("bb"))fmt.Println(cache.Get("data"))cache.Del("int")cache.Flush()cache.Keys()
}

最新golang语言面试题总结(三)相关推荐

  1. 最新golang语言面试题总结(一)

    1.go中make和new区别 new: 分配内存.内存里存的值是对应类型的零值. 只有一个参数.参数是分配的内存空间所存储的变量类型,Go语言里的任何类型都可以是new的参数,比如int, 数组,结 ...

  2. 国二计算机c 考试内容,计算机国二C语言考试试题第三套

    <计算机国二C语言考试试题第三套>由会员分享,可在线阅读,更多相关<计算机国二C语言考试试题第三套(10页珍藏版)>请在人人文库网上搜索. 1.第三套1.对下面程序描述正确的一 ...

  3. 2021年最新大厂php+go面试题集(三)

    14.快手一面 微信公众号:码农编程进阶笔记 关注可获得更多的视频教程及面试技巧.问题或建议,请公众号留言! 1.CDn工作原理答:CDN通过广泛的网络节点分布,提供快速.稳定.安全.可编程的全球内容 ...

  4. c语言用户标识符不能描述常量,福建省c语言考试试题c题库选择题答案06-08(最新)...

    1.12006 年年 6 月份月份2008 年年 1 月份月份C 语言等级考试语言等级考试模拟试卷模拟试卷集成集成(选择题部分选择题部分)一.选择题一.选择题1.关于.关于 C 语言数据类型的叙述,正 ...

  5. 国二c语言是笔试还是机,2017最新国二c语言笔试题.doc

    2017最新国二c语言笔试题 2017最新国二c语言笔试题篇1 1一个C程序的执行是从( ). A) 本程序的main函数开始,到main函数结束 B) 本程序文件的第一个函数开始,到本程序文件的最后 ...

  6. 国二和本专业的C语言的差距,2021最新国二c语言笔试题

    2021最新国二c语言笔试题 发布时间:2021-04-24 C语言是一门通用计算机编程语言,应用广泛.下面就由第一范文网小编为大家介绍一下20xx最新国二c语言笔试题的文章,欢迎阅读. 20xx最新 ...

  7. 2016二级c语言笔试内容,2016年计算机二级c语言笔试试题「最新」

    2016年计算机二级c语言笔试试题「最新」 (25)设有如下程序段 char s[20]= "Bejing",*p; p=s; 则执行p=s;语句后,以下叙述正确的是 A)可以用* ...

  8. 东软 c语言笔试题,C语言笔试题及参考答案-东软集团(最新整理)

    <C语言笔试题及参考答案-东软集团(最新整理)>由会员分享,可在线阅读,更多相关<C语言笔试题及参考答案-东软集团(最新整理)(7页珍藏版)>请在人人文库网上搜索. 1.C 语 ...

  9. 最新字节跳动面试题与岗位层级,绩效考核制度介绍

    最新字节跳动面试题与岗位层级,绩效考核制度介绍 1.算法题一:无序数组的中位数 (快排思想O(N) 时间复杂度) 2.算法题二:给一数组,让你找一对满足i 3.算法题三: 给一数组,让你找一对满足i& ...

最新文章

  1. 关于MYSQL日期 字符串 时间戳互转
  2. Oracle中的UPDATE FROM解决方法
  3. 中科大 计算机网络11 应用层原理
  4. leetcode - 56. 合并区间
  5. form必填默认校验_Salesforce LWC学习(十六) Validity 在form中的使用浅谈
  6. 收获,不止SQL优化——抓住SQL的本质--第三章
  7. word2010生成目录的方法
  8. day21保护操作系统
  9. 鸿蒙系统装机量,王成录:华为对今年鸿蒙OS系统的装机量预估是3亿台
  10. android textwatcher 获取当前控件,使用TextWatcher实现EditText与TextView同步
  11. 基础平台系列-1-第三方服务
  12. “联盟鱼”-国外广告联盟lead项目最新玩法介绍
  13. 小青龙的Java面试笔记
  14. SECTION 11 安装软件程序
  15. 用Excel理解神经网络
  16. hive表信息查询:查看表结构、表操作等(转)
  17. 心脏支架手术后遗症 做完心脏支架手术留下后遗症
  18. python通过网络发送图片_python 打开网络图片
  19. JAVA微信登陆详解
  20. 客快物流大数据项目(一百一十七):网关 Spring Cloud Gateway

热门文章

  1. 编辑pdf - pdfplumber的使用
  2. 全球Linux发展迅速 资质专业人才严重不足
  3. 计算机应用基础doc,统考计算机应用基础大全.doc
  4. 前后端交互(小白教学)
  5. 解决C#提示导入密钥文件失败的问题
  6. 在SAP GUI中玩扫雷小游戏
  7. 26--鞋子配对有多丑
  8. (一)JQuery动态加载js的三种方法
  9. 华为你学不会,包括数据管理
  10. opencv中的waitKey函数