golang面试-代码编写题1-14
- 1.代码编写题--统计文本行数-bufio
- 2.代码编写题--多协程收集错误信息-channel
- 3.代码编写题--超时控制,内存泄露
- 4.代码编写题--单例模式
- 5.代码编写题--九九乘法表
- 6.代码编写题--交替打印数字和字⺟
- 7.代码编写题--依次打印猫狗鱼
- 8.代码编写题--判断字符串中字符是否全都不同
- 9.代码编写题--翻转字符串
- 10.代码编写题--判断两个给定的字符串排序后是否⼀致
- 11.代码编写题--字符串替换
- 12.代码编写题--机器人坐标问题
- 13.代码编写题--实现两个channel打印五个随机数。生产消费模型
- 14.代码编写题--补全代码,要求每秒钟调用一次proc并保证程序不退出
1.代码编写题--统计文本行数-bufio
func demo1() {
file, err := os.Open("./Atest/1.txt")
if err != nil {
return
}
fd := bufio.NewScanner(file)
count := 0
for fd.Scan() {
count++
}
fmt.Println(count)
}
2.代码编写题--多协程收集错误信息-channel
版本1
func demo1(num int) (string, error) {
if num%2 == 0 {
return "", fmt.Errorf("错误,num=%d", num)
}
return fmt.Sprintf("成功,num=%d", num), nil
}
func main() {
wg := sync.WaitGroup{}
errChan := make(chan error)
for i := 0; i < 10; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
_, err := demo1(index)
if err != nil {
errChan <- err
}
}(i)
}
go func() {
wg.Add(1)
for {
errStr, ok := <-errChan
if ok {
fmt.Println(errStr)
} else {
break
}
}
wg.Done()
close(errChan)
}()
time.Sleep(time.Second)
}
版本2
多协程收集错误信息升级,类型断言
func demo1(num int) (string, error) {
if num%2 == 0 {
return "", fmt.Errorf("错误,num=%d", num)
}
return fmt.Sprintf("成功,num=%d", num), nil
}
func main() {
wg := sync.WaitGroup{}
retChan := make(chan interface{})
for i := 0; i < 10; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
data, err := demo1(index)
if err != nil {
retChan <- err
} else {
retChan <- data
}
}(i)
}
go func() {
wg.Add(1)
count := 0
for {
errStr, ok := <-retChan
if ok {
_, ok2 := errStr.(error)
if ok2 {
fmt.Println(errStr)
count++
}
} else {
break
}
if count >= 2 {
break
}
}
wg.Done()
//close(retChan)
}()
time.Sleep(time.Second)
}
3.代码编写题--超时控制,内存泄露
版本1
版本1:会造成内训泄漏,阻塞在done <- struct{}{}
解决:使用缓存chan,因为有缓冲的chan是非阻塞的,直到写满缓冲长度才阻塞。可以适当的缓冲长度调大
done := make(chan struct{},1)
func demo() error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*1)
done := make(chan struct{})
go func() {
//模拟业务
time.Sleep(time.Millisecond * 1200)
done <- struct{}{}
}()
select {
case <-ctx.Done():
return fmt.Errorf("超时")
case <-done:
return nil
}
}
func main() {
for i := 0; i < 100; i++ {
go func() {
demo()
}()
}
for {
time.Sleep(time.Second * 2)
fmt.Println(runtime.NumGoroutine()) //打印当前运行的协程数量
}
}
////////////////
101
101
101
101
版本2
func demo() error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*1)
done := make(chan struct{},1)
go func() {
//模拟业务
time.Sleep(time.Millisecond * 1200)
done <- struct{}{}
}()
select {
case <-ctx.Done():
return fmt.Errorf("超时")
case <-done:
return nil
}
}
func main() {
for i := 0; i < 100; i++ {
go func() {
demo()
}()
}
for {
time.Sleep(time.Second * 2)
fmt.Println(runtime.NumGoroutine()) //打印当前运行的协程数量
}
}
///////////////
1
1
1
4.代码编写题--单例模式
方式1
type Person struct {
Name string
}
var person *Person
var mu sync.Mutex
func NewPerson2(name string) *Person {
if person != nil {
//pass
} else {
mu.Lock()
defer mu.Unlock()
person = &Person{Name: name}
}
return person
}
func main() {
p1 := NewPerson2("hallen1")
p2 := NewPerson2("hallen2")
fmt.Printf("%p\n", p1) // 0xc00008e1e0
fmt.Printf("%p\n", p2) // 0xc00008e1e0
}
方式2:once.Do
var once sync.Once
var person *Person
type Person struct {
Name string
}
func NewPerson2(name string) *Person {
once.Do(func() {
person = new(Person)
person.Name = name
})
return person
}
func main() {
p1 := NewPerson2("hallen1")
p2 := NewPerson2("hallen2")
fmt.Printf("%p\n", p1) // 0xc00008e1e0
fmt.Printf("%p\n", p2) // 0xc00008e1e0
}
5.代码编写题--九九乘法表
func main() {
for i := 1; i <= 9; 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
6.代码编写题--交替打印数字和字⺟
问题描述:使⽤两个 goroutine 交替打印序列,⼀个 goroutine 打印数字, 另外⼀个goroutine 打印字⺟, 最终效果如下:
12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728
解体思路:
问题很简单,使⽤ channel 来控制打印的进度。使⽤两个 channel ,来分别控制数字和字⺟的打印序列, 数字打印完成后通过 channel 通知字⺟打印, 字⺟打印完成后通知数字打印,然后周⽽复始的⼯作。
func main() {
letter := make(chan bool)
number := make(chan bool)
wg := sync.WaitGroup{}
go func() {
i := 1
for {
select {
case <-number:
fmt.Print(i)
i++
fmt.Print(i)
i++
letter <- true
}
}
}()
wg.Add(1)
go func() {
i := 'A'
for {
select {
case <-letter:
if i >= 'Z' {
wg.Done()
return
}
fmt.Print(string(i))
i++
fmt.Print(string(i))
i++
number <- true
}
}
}()
number <- true
wg.Wait()
}
7.代码编写题--依次打印猫狗鱼
问题描述:3个协程依次打印猫狗鱼
func main() {
catChan := make(chan bool)
dogChan := make(chan bool)
fishChan := make(chan bool)
wg := sync.WaitGroup{}
go func() {
wg.Add(1)
for {
select {
case <-catChan:
fmt.Print("猫")
dogChan <- true
}
}
}()
go func() {
wg.Add(1)
for {
select {
case <-dogChan:
fmt.Print("狗")
fishChan <- true
}
}
}()
go func() {
wg.Add(1)
for {
select {
case <-fishChan:
fmt.Print("鱼")
catChan <- true
}
}
}()
catChan <- true
wg.Wait()
}
8.代码编写题--判断字符串中字符是否全都不同
问题描述:
请实现⼀个算法,确定⼀个字符串的所有字符【是否全都不同】。这⾥我们要求【不允许使⽤额外的存储结构】。给定⼀个string,请返回⼀个bool值,true代表所有字符全都不同,false代表存在相同的字符。保证字符串中的字符为【ASCII字符】。字符串的⻓度⼩于等于【3000】。
解题思路:
这⾥有⼏个重点,第⼀个是ASCII字符, ASCII字符字符⼀共有256个,其中128个是常⽤字符,可以在键盘上输⼊。128之后的是键盘上⽆法找到的。
然后是全部不同,也就是字符串中的字符没有重复的,再次,不准使⽤额外的储存结构,且字符串⼩于等于3000。
如果允许其他额外储存结构,这个题⽬很好做。如果不允许的话,可以使⽤golang内置的⽅式实现。
//判断s字符串有几个不重复的v子串
strings.Count(s, string(v))
func isUniqueString(s string) bool {
for _, v := range s {
if v > 127 {
return false
}
if strings.Count(s, string(v)) > 1 {
return false
}
}
return true
}
// strings.Index(s,string(v)) 判断字符串v在s字符串出现的位置,不存在返回-1
func isUniqueString2(s string) bool {
for k,v := range s {
if v > 127 {
return false
}
if strings.Index(s,string(v)) != k {
return false
}
}
return true
}
9.代码编写题--翻转字符串
问题描述:
翻转给定字符串,abc-->cba
解题思路:
以字符串长度1/2为轴,前后反转赋值
func reverString(s string) string {
str := []rune(s)
l := len(str)
for i := 0; i < l/2; i++ {
str[i], str[l-1-i] = str[l-1-i], str[i]
}
return string(str)
}
10.代码编写题--判断两个给定的字符串排序后是否⼀致
问题描述:
给定两个字符串,请编写程序,确定其中⼀个字符串的字符重新排列后,能否变成另⼀个字符串。
这⾥规定【⼤⼩写为不同字符】,且考虑字符串重点空格。给定⼀个string s1和⼀个string s2,请返回⼀个bool,代表两串是否重新排列后可相同。
解决思路:
循环遍历s1,strings.Count数量在s2中是否相等
func isRegroup(s1, s2 string) bool {
for _, v := range s1 {
if strings.Count(s1, string(v)) != strings.Count(s2, string(v)) {
return false
}
}
return true
}
func main() {
s1 := "abc"
s2 := "cba"
boo := isRegroup(s1, s2)
fmt.Println(boo) //true
}
11.代码编写题--字符串替换
func replaceBlank(s, oldStr, newStr string) string {
return strings.Replace(s, oldStr, newStr, -1)
}
func main() {
s := "abcdeffff"
res := replaceBlank(s, "f", "k")
fmt.Println(res) //abcdekkkk
}
12.代码编写题--机器人坐标问题
问题描述:
有⼀个机器⼈,给⼀串指令,L左转 R右转,F前进⼀步,B后退⼀步,问最后机器⼈的坐标,最开始,机器⼈位于 0 0,⽅向为正Y。
可以输⼊重复指令n : ⽐如 R2(LF) 这个等于指令 RLFLF。
问最后机器⼈的坐标是多少?
//面朝方向: 1前 2右 3后 4左
// (0,0,1),x,y表示坐标,z表示面朝方向。支持的指令:L左转 R右转,F前进⼀步,B后退⼀步
func move(t [3]int, cmd string) [3]int {
for _, v := range cmd {
switch string(v) {
case "L":
//向左转
if t[2] == 1 {
t[2] = 4
} else {
t[2]--
}
case "R":
//向右转
if t[2] == 4 {
t[2] = 1
} else {
t[2]++
}
case "F":
//前进,看面朝方向
if t[2] == 1 {
//面朝前后改变y轴
t[1]++
} else if t[2] == 3 {
t[1]--
} else if t[2] == 2 {
//面朝前后改变x轴
t[0]++
} else if t[2] == 4 {
t[0]--
}
case "B":
//后退,看面朝方向,面朝前后改变y轴
if t[2] == 1 {
//面朝前后改变y轴
t[1]--
} else if t[2] == 3 {
t[1]++
} else if t[2] == 2 {
//面朝前后改变x轴
t[0]--
} else if t[2] == 4 {
t[0]++
}
}
}
return t
}
func main() {
t := [3]int{0, 0, 1} //初始值:机器人在原点,面朝前方
re := move(t, "FFFFRFFF")
fmt.Println(re)
}
13.代码编写题--实现两个channel打印五个随机数。生产消费模型
func main() {
out := make(chan int, 1)
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
defer close(out)
for i := 0; i < 5; i++ {
out <- rand.Intn(10)
}
}()
go func() {
defer wg.Done()
for i := range out {
fmt.Println(i)
}
}()
wg.Wait()
}
14.代码编写题--补全代码,要求每秒钟调用一次proc并保证程序不退出
package main
func main() {
go func() {
// 1 在这⾥需要你写算法
// 2 要求每秒钟调⽤⼀次proc函数
// 3 要求程序不能退出
}()
select {}
}
func proc() {
panic("ok")
}
解析:
题⽬主要考察了两个知识点:
1. 定时执⾏执⾏任务
2. 捕获 panic 错误
题⽬中要求每秒钟执⾏⼀次,⾸先想到的就是 time.Ticker 对象,该函数可每秒钟往chan 中放⼀个Time ,正好符合我们的要求。
在 golang 中捕获 panic ⼀般会⽤到 recover() 函数。
编写代码:
func main() {
go func() {
// 1 在这⾥需要你写算法
// 2 要求每秒钟调⽤⼀次proc函数
// 3 要求程序不能退出
t := time.NewTicker(1 * time.Second)
for {
select {
case <-t.C:
go func() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
proc()
}()
}
}
}()
select {}
}
func proc() {
panic("ok")
}
golang面试-代码编写题1-14的更多相关文章
- python面试的100题(14)
32.请写出一个函数满足以下条件 该函数的输入是一个仅包含数字的list,输出一个新的list,其中每一个元素要满足以下条件: 1.该元素是偶数 2.该元素在原list中是在偶数的位置(index是偶 ...
- 这些HTML、CSS知识点,面试和平时开发都需要 No10-No11(知识点:表格操作、代码编写规则)
系列知识点汇总 1.基础篇 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5- ...
- 14条最佳JS代码编写技巧
http://gaohaixian.blog.163.com/blog/static/123260105201142645458315/写任何编程代码,不同的开发者都会有不同的见解.但参考一下总是好的 ...
- leecode刷题(14)-- 有效的字母异位词
leecode刷题(14)-- 有效的字母异位词 有效的字母异位词 描述: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词. 示例 1: 输入: s = " ...
- LeetCode面试常见100题( TOP 100 Liked Questions)
LeetCode面试常见100题( TOP 100 Liked Questions) 置顶 2018年07月16日 11:25:22 lanyu_01 阅读数 9704更多 分类专栏: 面试编程题真题 ...
- 为代码编写稳定的单元测试 [Go]
为代码编写稳定的单元测试 本文档配套代码仓库地址: https://github.com/liweiforeveryoung/curd_demo 配合 git checkout 出指定 commit ...
- Android面试一天一题(1Day)
写在前面 该博客思路源于在简书看到goeasyway博主写的Android面试一天一题系列,无copy之意,仅为让自己总结知识点,成长一点点.先感谢各位大神的无私分享~! 关于题目,大部分则出自And ...
- .NET代码编写规范 整理
.NET代码编写规范 整理 .NET代码编写规范 - [ASP.NET] 2009-02-26 | Tag: 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://lensp ...
- 代码编写规范说明书(c#.net与asp.net)
代码编写规范说明书(c#.net与asp.net) 目 录1 目的2 范围3 注释规范3.1 概述3.2 自建代码文件注释3.3 模块(类)注释3.4 类属性注释3.5 方法注释3.6 代码间注释4 ...
随机推荐
- MongoDB排序时内存大小限制和创建索引的注意事项!
线上服务的MongoDB中有一个很大的表,我查询时使用了sort()根据某个字段进行排序,结果报了下面这个错误: [Error] Executor error during find command ...
- Python图像处理:如何获取图像属性、兴趣ROI区域及通道处理
摘要:本篇文章主要讲解Python调用OpenCV获取图像属性,截取感兴趣ROI区域,处理图像通道. 本文分享自华为云社区<[Python图像处理] 三.获取图像属性.兴趣ROI区域及通道处理 ...
- 1903021121—刘明伟—Java第三周作业—学习在eclipse上创建并运行java程序
项目 内容 课程班级博客链接 19信计班(本) 作业要求链接 第三周作业 作业要求 每道题要有题目,代码,截图 扩展阅读 eclipse如何创建java程序 java语言基础(上) 扩展阅读心得: 想 ...
- CesiumJS 2022^ 原理[5] - 着色器相关的封装设计
目录 1. 对 WebGL 接口的封装 1.1. 缓冲对象封装 1.2. 纹理与采样参数封装 1.3. 着色器封装 1.4. 上下文对象与渲染通道 1.5. 统一值(uniform)封装 1.6. 渲 ...
- 使用BGP-blackhole解决IDC频繁遭受DDOS攻击困扰
项目背景 该项目位于某市级BGP IDC机房,机房客户多为web业务,遭受小流量攻击(10G量级)较为频繁,针对这一现象在机房core旁路部署ADS系统,牵引异常流量清洗后进行回源,该清洗方案在此不再 ...
- 渗透:winpcap
winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统.开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力.它提供 ...
- 【leetcode】239. 滑动窗口最大值
目录 题目 题解 三种解法 "单调队列"解法 新增.获取最大值 删除 代码 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以 ...
- 第6组 Beta冲刺 总结
目录 1. 基本情况 2. 思考与总结 2.1. 设想和目标 2. 计划 3. 资源 4. 变更管理 5. 设计/实现 6. 测试/发布 7. 团队的角色,管理,合作 8. 总结 3. 敏捷开发 1. ...
- 【clickhouse专栏】新建库角色用户初始化
一.创建新的database clickhouse创建数据库的语法几乎和其他的关系型数据库是一样的,区别就是clickhouse存在集群cluster和库引擎engine的概念,可以根据需要进行指定. ...
- 6.文本三剑客之sed
文本三剑客之sed 目录 文本三剑客之sed sed编辑器 sed概述 sed工作流程 sed用法 sed打印 sed删除 sed替换 sed增加行内容 sed剪切粘贴与复制粘贴 sed字符/字符串交 ...