golang常见笔试题


前言

本文整理了golang面试中比较常见的几个笔试题。

一、控制goroutine数量

题目:实现一个批处理任务,list=[1,2,3,4,5,6,7,8],对list中的元素进行平方运算,要求goroutine数量最多3个。


func power(num int) int {
	return num * num
}

func main() {
	runner := NewParallelRunner(3)

	list := []int{1, 2, 3, 4, 5, 6, 7, 8}
	for _, v := range list {
		runner.Run(v)
	}
	runner.Wait()

	dict := runner.Result()
	var result []int
	for _, v := range list {
		result = append(result, dict[v])
	}
	fmt.Println(result)
}

type ParallelRunner struct {
	wg     sync.WaitGroup
	sendQ  chan int
	result map[int]int
	mutex  sync.Mutex
}

func NewParallelRunner(parallel int) *ParallelRunner {
	sendQ := make(chan int)

	runner := &ParallelRunner{
		sendQ:  sendQ,
		result: make(map[int]int),
	}

	for i := 0; i < parallel; i++ {
		runner.wg.Add(1)
		go func() {
			defer runner.wg.Done()

			for v := range sendQ {
				runner.mutex.Lock()
				runner.result[v] = power(v)
				runner.mutex.Unlock()
			}
		}()
	}

	return runner
}

func (runner *ParallelRunner) Run(num int) {
	runner.sendQ <- num
}

func (runner *ParallelRunner) Wait() {
	close(runner.sendQ)
	runner.wg.Wait()
}

func (runner *ParallelRunner) Result() map[int]int {
	return runner.result
}

二、信号通知

题目:使用两个goroutine,交替打印数字和字母

func main() {
	digit := make(chan struct{})
	letter := make(chan struct{})
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		defer wg.Done()

		startIndex := 1
		for {
			if _, ok := <-digit; !ok {
				break
			}

			if startIndex >= 10 {
				close(letter)
				break
			}

			fmt.Printf("%d", startIndex)
			startIndex++
			letter <- struct{}{}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()

		startIndex := 'a'
		for {
			if _, ok := <-letter; !ok {
				break
			}

			fmt.Printf("%c", startIndex)
			startIndex++
			digit <- struct{}{}
		}
	}()

	digit <- struct{}{}
	wg.Wait()
}

这里的技巧就是:打印数字的goroutine判断终止条件,并关闭打印字母的通道。

三、并发请求

题目:通过goroutine发送多个请求,只要其中一个返回结果,立即结束其他的请求。


func main() {
	ctx, cancel := context.WithCancel(context.Background())

	recv := make(chan int)
	for i := 0; i < 10; i++ {
		go func(ctx context.Context, index int) {
			ch := make(chan int)
			go func() {
				// 模拟请求耗时
				time.Sleep(time.Duration(rand.Intn(10) * 1000))

				fmt.Println("返回结果", index)
				ch <- index
			}()

			res := <-ch
			select {
			case <-ctx.Done():
				break
			case recv <- res:
				fmt.Printf("gouroutine %d 返回结果\n", index)
				break
			}

			fmt.Printf("gouroutine %d 结束\n", index)
		}(ctx, i)
	}

	v := <-recv
	cancel()
	fmt.Println(v)
}
### 开发工程师笔试题与准备资料 开发工程师的笔试题通常涵盖多个领域,包括但不限于编程语言基础、算法设计、数据结构以及特定领域的知识。以下是一些常见开发工程师笔试题类型及相关准备资料。 #### 一、C语言基础 C语言是许多硬件和嵌入式开发的基础。汇顶科技的固件开发工程师笔试卷中,C语言基础占据了重要部分[^1]。以下是可能涉及的题目类型: - **单选题**:如指针操作、内存管理、数据类型转换等。 - **填空题**:涉及字符串处理、数组操作或函数实现细节。 - **编程题**:要求编写一个简单的程序来解决实际问题,例如排序算法或链表操作。 示例代码(C语言): ```c #include <stdio.h> int main() { int arr[] = {5, 3, 8, 6, 7}; int n = sizeof(arr) / sizeof(arr[0]); int max = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > max) { max = arr[i]; } } printf("最大值: %d\n", max); return 0; } ``` #### 二、异常处理设计 在软件开发中,异常处理是一个重要的概念。Golang开发工程师的笔试题中提到,异常设计的关键在于开发阶段和部署阶段的不同策略[^2]。以下是相关知识点: - **速错原则**:在开发阶段,让程序快速崩溃以暴露问题。 - **恢复异常**:在部署后,避免因异常导致程序终止。 - **分支处理**:对于不应该出现的逻辑分支,使用异常机制进行处理。 #### 三、算法与数据结构 算法和数据结构是开发工程师笔试的核心内容之一。常见的题目包括: - **排序算法**:如快速排序、归并排序等。 - **搜索算法**:如深度优先搜索(DFS)、广度优先搜索(BFS)。 - **动态规划**:用于解决最优化问题。 示例代码(Python): ```python def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1 ``` #### 四、准备资料推荐 为了更好地准备开发工程师的笔试,可以参考以下资料: 1. **书籍**:《C程序设计语言》、《Effective C++》、《算法导论》。 2. **在线资源**:LeetCode、HackerRank、Codeforces 提供了丰富的算法练习题。 3. **官方文档**:如 Golang 官方文档[^2],深入理解语言特性。 4. **模拟试题**:通过模拟真实的笔试环境,提升解题速度和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值