【GoLand】GoLand练习题目

【GoLand】GoLand练习题目,第1张

文章目录 (一)数组切片 *** 作1.两个slice之间找出交集、并集2.slice赋值 *** 作(output? why?)思考:切片底层原理?值传递的区别指针传递 (二)树 *** 作(三)协程 *** 作(起协程并发轮流打印两个数组内容)(四)channel *** 作(五)设计模式

(一)数组切片 *** 作 1.两个slice之间找出交集、并集

思路是利用map的映射关系来求交并集

package main

import "fmt"

//假设两个集合没有重复元素
//slice1 = [1, 2, 3, 4, 5]
//slice2 = [3, 4, 5, 6, 7]
func intersection(slice1 []int,slice2 []int) []int{
	//1.
	m:=make(map[int]int)
	for _,val:=range slice1{
		m[val]=1
	}
	//2.
	var ans []int
	for _,val:=range slice2{
		times := m[val]
		if times!=0 {
			ans=append(ans,val)
		}
	}
	return ans
}
func union_set(slice1 []int,slice2 []int) []int{
	//1.
	m:=make(map[int]int)
	for _,val:=range slice1{
		m[val]=1
	}
	//2.
	for _,val:=range slice2{
		times:=m[val]
		if times==0 {
			slice1=append(slice1,val)
		}
	}
	return slice1
}

func main() {
	intersection:=intersection([]int{1,2,3,4,5},[]int{3,4,5,6,7})
	UnionSet:=union_set([]int{1, 2, 3, 4, 5}, []int{3, 4, 5, 6, 7})
	for _,val:=range intersection{
		fmt.Println(val)
	}
	for _,val:=range UnionSet{
		fmt.Println(val)
	}
}


2.slice赋值 *** 作(output? why?)
func assigned(){
	slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := slice[2:5] // slice[2,3,4,x5,x6,x7,x8,x9]
	s2 := s1[2:6:7]  // s1[4,5,6,7,x8]

	s2 = append(s2, 100)  // s1[4,5,6,7,100]
	s2 = append(s2, 200)  // ns1[4,5,6,7,100,200]

	s1[2] = 20       // slice[2,3,20,x5,x6,x7,x8,x9]

	fmt.Println(s1)    //[2 3 20]
	fmt.Println(s2)    //[4 5 6 7 100 200]
	fmt.Println(slice) //[0 1 2 3 20 5 6 7 100 9]
}


思考:切片底层原理?值传递的区别指针传递

1.切片底层原理,切片其实就是一个对底层数组的一种有限的访问方式的抽象,每个切片都有指针字段,长度字段,容量字段,通过这三个字段来控制对底层数组的访问
2.切片传递给函数使用的是值传递,也就是实参到形参完成了一次切片复制,这是由于切片本身不是数组,复制一份依然指向原来的数组,所以依然可以对原来的底层数组进行 *** 作
3.如果是指针传递那就是传递原来切片的指针,函数通过指针访问原来的切片再访问底层数组,这样对于大的数据结构比较合适,由于切片本身很小,所以不如直接值传递,复制一份



(二)树 *** 作

思考:复杂度、内存空间大小,如何分配内存。栈空间堆空间
1.时间复杂度就相当于遍历一整颗树o(n)
2.内存大小,由于每一层递归只用到常数级别内存,假设这颗树深度n,那么递归深度为n,所以系统栈所用空间为o(n)
3.每一层函数的局部变量以及递归参数信息的保存都是在系统栈中,所以设计栈空间,但是由于没有对象的创建,所以没有堆空间的分配

type MyStruct struct {
	Name       string
	DownStream []*MyStruct
}

//implement me
func isExist(root *MyStruct, name string) bool {
	//1.
	if root==nil {
		return false
	}
	//2.
	if root.Name==name {
		return true
	}
	//3.
	for _,son:=range root.DownStream{
		if isExist(son,name)==true {
			return true
		}
	}
	return false
}



(三)协程 *** 作(起协程并发轮流打印两个数组内容)
package main

import "fmt"

func func1(l1 []int,ch chan string){
	for _, val := range l1 {
		if "ok"==<-ch{
			fmt.Println(val)
			ch<-"ok"
		}
	}
	//这个最后结束的接收,是由于func2的最后一个ch<-"ok"如果没有一个接收会阻塞
	//那么func2的协程就没办法结束,造成死锁
	<-ch
}
func func2(l2 []int,ch chan string){
	//这个发送是为了先打印l1
	ch<-"ok"
	for _, val := range l2 {
		if "ok"==<-ch{
			fmt.Println(val)
			//容易死锁
			ch<-"ok"
		}
	}
}

func main() {
	// 起协程并发轮流打印两个数组内容
	// output
	// 1,3,2,4,3,5,4,6
	l1 := []int{1,2,3,4}
	l2 := []int{3,4,5,6}

	ch:=make(chan string)
	go func1(l1,ch)
	func2(l2,ch)
}



(四)channel *** 作

1.c := make(chan int) 和 c1 := make(chan int, 1) 有什么区别?
前者是无缓冲通道,后者是缓冲区大小为1的通道


2.起一个goroutine,怎么从main goroutine杀掉启动的goroutine?

思路就是使用一个通道作为协程关闭的标志,当main协程执行close(done)时,其他协程就会接收到一个空值进而关闭

package main

import (
	"fmt"
	"time"
)

func funcName(done chan string){
	for true {
		select {
		case <-done:
			return
		default:
			fmt.Println("1")
		}
	}
}
func main() {
	done:=make(chan string)
	go funcName(done)
	go funcName(done)
	go funcName(done)
	time.Sleep(time.Second*3)
	close(done)
	time.Sleep(time.Second*3)
	fmt.Println("main协程")
}



(五)设计模式

Golang中有继承吗?实现一个Son类继承Father

Golang中没有继承,结构体与结构体之间只能采用以往oop中的组合关系,即将一个结构体注入另外一个结构体中

package main

import "fmt"

type Father struct {
	name_f string

}
func (f Father)show(){
	fmt.Println("my name is "+f.name_f)
}

type Son struct {
	Father
	name_s string
}
//少写一个show可以测试show方法在有没有绑定到Son中来
func (s Son)show(){
	fmt.Println("my name is "+s.name_s)
}

func main() {
	father:=Father{"father"}
	son:=Son{father,"son"}
	//Son可以直接取到father的属性,由于Father是匿名注入的方式
	fmt.Println(son.name_f)
	father.show()
	son.show()
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/994857.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存