栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

golang面试题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang面试题

一、闭包(打印输出什么?)

1、

package main

import "fmt"

func func1() func(int) int {
	sum:=0
	return func(val int) int {
		sum+=val
		return sum
	}
}
func printFunc1()  {
	sumFunc:=func1()
	fmt.Println(sumFunc(1))
	fmt.Println(sumFunc(2))
}
func main() {
	printFunc1()
}

结果:结果保留在闭包函数中,

1
3

2、

package main

import "fmt"

func func2() (val int) {
	val = 10
	defer func() {
		val+=1
	}()
	return val
}
func printFunc2()  {
	fmt.Println(func2())
}
func main() {
	printFunc2()
}

结果:

11

3、

package main

import "fmt"

func func3() int {
	val := 10
	defer func() {
		val+=1
	}()
	return val
}
func printFunc3()  {
	fmt.Println(func3())
}

func main() {
	printFunc3()
}

结果:

10
二、goroutine

打印出什么?为什么?怎么解决?

package main

import (
	"fmt"
	"time"
)

func main() {
	data := make(map[int]int , 10)
	for i:=1;i<=10;i++ {
		data[i] = i
	}
	for key,value := range data{
		go func() {
			fmt.Println("k ->",key,"v ->",value)
		}()
	}
	time.Sleep(time.Second*1)
}

结果:输出同个数据多次,原因是goroutine栈没有刷新导致的问题

k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 10 v -> 10
k -> 5 v -> 5
k -> 10 v -> 10

解决方法:

for key,value := range data{
	go func(key,value int) {
		fmt.Println("k ->",key,"v ->",value)
	}(key,value)
}
三、defer

1、

package main

import "fmt"

func main() {
	m:=10
	defer fmt.Printf("first defer : %dn",+m)
	m=100
	defer fmt.Printf("second defer : %dn",+m)
}

结果:

second defer : 100
first defer : 10

2、

package main

import "fmt"

func func1() func() {
	defer fmt.Println("before return")
	return func(){
		defer fmt.Println("in the return")
	}
}
func main() {
	m:=10
	defer fmt.Printf("first defer : %dn",m)    //5 10
	m=100
	defer func() {
		fmt.Printf("second defer : %dn",m)     //4   1000*10=10000
	}()
	m *= 10
	defer fmt.Printf("second defer : %dn",m)   //3   100*10=1000
	funcVal := func1()     //1  调用函数将返回的闭包函数赋给funcVal
	funcVal()         	   //2   
}

结果:

before return
in the return
second defer : 1000
second defer : 1000
first defer : 10

3、

package main

import "fmt"

func func2() (sum int){
	sumA := 100
	sumB := 100
	sum = sumA +sumB

	defer func(){
		defer fmt.Printf("func2 first : %dn",sum)   //2000
	}()
	defer fmt.Printf("func2 second : %dn", sum)  //200
	return sum*10   //2000
}
func main() {
	defer fmt.Printf("main : %dn",func2())  //1
}

结果:

func2 second : 200
func2 first : 2000
main : 2000

总结: defer是在return之前执行,defer 闭包函数内的值为指针。

四、slice扩容

1、int64的

package main

import "fmt"

func main() {
	var arr1 []int64
	for i:=0; i<512; i++ {
		arr1 = append(arr1,int64(i))
	}
	fmt.Printf("len = %d, cap = %dn",len(arr1),cap(arr1))
}

结果:

len = 512, cap = 512
当i<513的时候输出   len = 513, cap = 1024
当i<1024的时候输出  len = 1024, cap = 1024
当i<1025的时候输出  len = 1025, cap = 1280

2、int32

//int32: 1024*1.25*4=5120  查表大于5120且最接近的是5376,则5376/4=1344
func main() {
	var arr1 []int32
	for i:=0; i<1025; i++ {
		arr1 = append(arr1,int32(i))
	}
	fmt.Printf("len = %d, cap = %dn",len(arr1),cap(arr1))
}

输出:

len = 1025, cap = 1344

3、批量append

//批量append
//1025*8=8200  查表 9472/8=1184
func main() {
	var arr1 []int64
	var arr2 []int64
	for i:=0; i<1025; i++ {
		arr1 = append(arr1,int64(i))
	}
	fmt.Printf("len = %d, cap = %dn",len(arr1),cap(arr1))
	arr2 = append(arr2,arr1...)
	fmt.Printf("len = %d, cap = %dn",len(arr2),cap(arr2))
}

输出

len = 1025, cap = 1280
len = 1025, cap = 1184

总结:

少于1024的双倍扩容,大于1024的1.25倍扩容

网上结论:1024*1.25=1280

实际结论与位数相关
一个一个append
int32: 1024*1.25*4=5120  查表大于5120且最接近的是5376,则5376/4=1344
int64: 1024*1.25*8=10240  查表为10240,则10240/8=1280

批量append
1025*8=8200  查表 9472/8=1184

查表在runtime包下的sizeclasses.go下,查找的是左侧的第二栏,如下:

// Code generated by mksizeclasses.go; DO NOT EDIT.
//go:generate go run mksizeclasses.go

package runtime

// class  bytes/obj  bytes/span  objects  tail waste  max waste  min align
//     1          8        8192     1024           0     87.50%          8
//     2         16        8192      512           0     43.75%         16
//     3         24        8192      341           8     29.24%          8
//     4         32        8192      256           0     21.88%         32
//     5         48        8192      170          32     31.52%         16
//     6         64        8192      128           0     23.44%         64
//     7         80        8192      102          32     19.07%         16
//     8         96        8192       85          32     15.95%         32
//     9        112        8192       73          16     13.56%         16
//    10        128        8192       64           0     11.72%        128
//    11        144        8192       56         128     11.82%         16
//    12        160        8192       51          32      9.73%         32
//    13        176        8192       46          96      9.59%         16
//    14        192        8192       42         128      9.25%         64
//    15        208        8192       39          80      8.12%         16
//    16        224        8192       36         128      8.15%         32
//    17        240        8192       34          32      6.62%         16
//    18        256        8192       32           0      5.86%        256
//    19        288        8192       28         128     12.16%         32
//    20        320        8192       25         192     11.80%         64
//    21        352        8192       23          96      9.88%         32
//    22        384        8192       21         128      9.51%        128
//    23        416        8192       19         288     10.71%         32
//    24        448        8192       18         128      8.37%         64
//    25        480        8192       17          32      6.82%         32
//    26        512        8192       16           0      6.05%        512
//    27        576        8192       14         128     12.33%         64
//    28        640        8192       12         512     15.48%        128
//    29        704        8192       11         448     13.93%         64
//    30        768        8192       10         512     13.94%        256
//    31        896        8192        9         128     15.52%        128
//    32       1024        8192        8           0     12.40%       1024
//    33       1152        8192        7         128     12.41%        128
//    34       1280        8192        6         512     15.55%        256
//    35       1408       16384       11         896     14.00%        128
//    36       1536        8192        5         512     14.00%        512
//    37       1792       16384        9         256     15.57%        256
//    38       2048        8192        4           0     12.45%       2048
//    39       2304       16384        7         256     12.46%        256
//    40       2688        8192        3         128     15.59%        128
//    41       3072       24576        8           0     12.47%       1024
//    42       3200       16384        5         384      6.22%        128
//    43       3456       24576        7         384      8.83%        128
//    44       4096        8192        2           0     15.60%       4096
//    45       4864       24576        5         256     16.65%        256
//    46       5376       16384        3         256     10.92%        256
//    47       6144       24576        4           0     12.48%       2048
//    48       6528       32768        5         128      6.23%        128
//    49       6784       40960        6         256      4.36%        128
//    50       6912       49152        7         768      3.37%        256
//    51       8192        8192        1           0     15.61%       8192
//    52       9472       57344        6         512     14.28%        256
//    53       9728       49152        5         512      3.64%        512
//    54      10240       40960        4           0      4.99%       2048
//    55      10880       32768        3         128      6.24%        128
//    56      12288       24576        2           0     11.45%       4096
//    57      13568       40960        3         256      9.99%        256
//    58      14336       57344        4           0      5.35%       2048
//    59      16384       16384        1           0     12.49%       8192
//    60      18432       73728        4           0     11.11%       2048
//    61      19072       57344        3         128      3.57%        128
//    62      20480       40960        2           0      6.87%       4096
//    63      21760       65536        3         256      6.25%        256
//    64      24576       24576        1           0     11.45%       8192
//    65      27264       81920        3         128     10.00%        128
//    66      28672       57344        2           0      4.91%       4096
//    67      32768       32768        1           0     12.50%       8192

// alignment  bits  min obj size
//         8     3             8
//        16     4            32
//        32     5           256
//        64     6           512
//       128     7           768
//      4096    12         28672
//      8192    13         32768

const (
	_MaxSmallSize   = 32768
	smallSizeDiv    = 8
	smallSizeMax    = 1024
	largeSizeDiv    = 128
	_NumSizeClasses = 68
	_PageShift      = 13
)

var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}
var class_to_allocnpages = [_NumSizeClasses]uint8{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 2, 3, 1, 3, 2, 3, 4, 5, 6, 1, 7, 6, 5, 4, 3, 5, 7, 2, 9, 7, 5, 8, 3, 10, 7, 4}
var class_to_divmagic = [_NumSizeClasses]uint32{0, ^uint32(0)/8 + 1, ^uint32(0)/16 + 1, ^uint32(0)/24 + 1, ^uint32(0)/32 + 1, ^uint32(0)/48 + 1, ^uint32(0)/64 + 1, ^uint32(0)/80 + 1, ^uint32(0)/96 + 1, ^uint32(0)/112 + 1, ^uint32(0)/128 + 1, ^uint32(0)/144 + 1, ^uint32(0)/160 + 1, ^uint32(0)/176 + 1, ^uint32(0)/192 + 1, ^uint32(0)/208 + 1, ^uint32(0)/224 + 1, ^uint32(0)/240 + 1, ^uint32(0)/256 + 1, ^uint32(0)/288 + 1, ^uint32(0)/320 + 1, ^uint32(0)/352 + 1, ^uint32(0)/384 + 1, ^uint32(0)/416 + 1, ^uint32(0)/448 + 1, ^uint32(0)/480 + 1, ^uint32(0)/512 + 1, ^uint32(0)/576 + 1, ^uint32(0)/640 + 1, ^uint32(0)/704 + 1, ^uint32(0)/768 + 1, ^uint32(0)/896 + 1, ^uint32(0)/1024 + 1, ^uint32(0)/1152 + 1, ^uint32(0)/1280 + 1, ^uint32(0)/1408 + 1, ^uint32(0)/1536 + 1, ^uint32(0)/1792 + 1, ^uint32(0)/2048 + 1, ^uint32(0)/2304 + 1, ^uint32(0)/2688 + 1, ^uint32(0)/3072 + 1, ^uint32(0)/3200 + 1, ^uint32(0)/3456 + 1, ^uint32(0)/4096 + 1, ^uint32(0)/4864 + 1, ^uint32(0)/5376 + 1, ^uint32(0)/6144 + 1, ^uint32(0)/6528 + 1, ^uint32(0)/6784 + 1, ^uint32(0)/6912 + 1, ^uint32(0)/8192 + 1, ^uint32(0)/9472 + 1, ^uint32(0)/9728 + 1, ^uint32(0)/10240 + 1, ^uint32(0)/10880 + 1, ^uint32(0)/12288 + 1, ^uint32(0)/13568 + 1, ^uint32(0)/14336 + 1, ^uint32(0)/16384 + 1, ^uint32(0)/18432 + 1, ^uint32(0)/19072 + 1, ^uint32(0)/20480 + 1, ^uint32(0)/21760 + 1, ^uint32(0)/24576 + 1, ^uint32(0)/27264 + 1, ^uint32(0)/28672 + 1, ^uint32(0)/32768 + 1}
var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
var size_to_class128 = [(_MaxSmallSize-smallSizeMax)/largeSizeDiv + 1]uint8{32, 33, 34, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}
五、nil是否一定相等
package main

import "fmt"

func main() {
	var x *int = nil
	var y interface{} = x
	fmt.Println(x == y)      //true
	fmt.Println(x == nil)	//true
	fmt.Println(y == nil)	//false

	var z interface{} = nil
	fmt.Println(z == nil)	//true
	fmt.Println(y == z)		//false   由于type不同导致他们不相等
}

y == nil 为false的原因:

由于y被x强制转化为int类型,且值为nil,因此在比较y是否等于nil的时候,由于type为int,导致其为false。

总结:
interface的底层结构为:(在runtime包下的runtime2.go)

空接口是eface,非空接口是iface
例如:iface是带function的,eface是不带function的。

type iface struct {
	tab  *itab
	data unsafe.Pointer
}
type eface struct {
	_type *_type
	data  unsafe.Pointer
}
六、并发测试

互斥锁不可重复上锁

package main

import (
	"fmt"
	"sync"
)
//互斥锁,不可重入锁   在一个goroutine下,重复上锁的话,就会发生panic
var mu sync.Mutex
var chain string
func main() {
	chain = "main"
	A()
	fmt.Println(chain)
}
func A()  {
	mu.Lock()
	defer mu.Unlock()
	chain = chain + " --> A"
	B()
}
func B()  {
	chain = chain + " --> B"
	C()
}
func C()  {
	mu.Lock()
	defer mu.Unlock()
	chain = chain + " --> C"
}

结果:panic
原因:互斥锁,不可重入锁 在一个goroutine下,重复上锁的话,就会发生panic

七、如何调用panic
package main

import (
	"fmt"
	"time"
)

func proc()  {
	panic("ok")
}
func main() {
	go func() {
		//1、在这里需要你写算法
		//2、要求每秒调用一次proc函数
		//3、要求程序不能退出
		t := time.NewTicker(time.Second)
		for  {
			select {
			case <-t.C:
				go func() {
					defer func() {
						if err := recover(); err!=nil{
							fmt.Println(err)
						}
					}()
					fmt.Println(time.Now())
					proc()
				}()
			}
		}
	}()
	select {}
}

输出

2022-06-01 19:43:09.9668789 +0800 CST m=+1.016162401
ok
2022-06-01 19:43:10.9661258 +0800 CST m=+2.015409301
ok
2022-06-01 19:43:11.9635083 +0800 CST m=+3.012791801
ok
八、LRU缓存(leetcode算法题)

LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

解答:

//双向链表
type DLinkNode struct {
	key,val int
	pre,next *DLinkNode
}

type LRUCache struct {
	size,capacity int
	cache map[int]*DLinkNode
	head,tail *DLinkNode
}
//初始化
func initDLinkNode(key,val int) *DLinkNode {
	return &DLinkNode{key: key,val: val}
}
//构造
func Constructor(capacity int) LRUCache {
	l := LRUCache{
		capacity: capacity,
		size: 0,
		cache: map[int]*DLinkNode{},
		head: initDLinkNode(0,0),
		tail: initDLinkNode(0,0),
	}
	l.head.next = l.tail
	l.tail.pre = l.head
	return l
}
//移除节点
func removeNode(node *DLinkNode)  {
	node.pre.next = node.next
	node.next.pre = node.pre
}
//移除尾部节点
func (this *LRUCache)removeTail()  *DLinkNode{
	node := this.tail.pre
	removeNode(node)
	return node
}
//添加节点到头部
//头指针(head)为空
func (this *LRUCache)addHead(node *DLinkNode)  {
	node.next = this.head.next
	node.pre = this.head
	this.head.next.pre = node
	this.head.next = node
}
//移除头个节点
func (this *LRUCache)movetoHead(node *DLinkNode)  {
	removeNode(node)
	this.addHead(node)
}
//获取节点的值
func (this *LRUCache) Get(key int) int {
	if node,ok := this.cache[key]; ok{
		this.movetoHead(node)
		return node.val
	}
	return -1
}

//插入节点
func (this *LRUCache) Put(key int, value int)  {
	if node,ok := this.cache[key];ok {
		node.val = value
		this.movetoHead(node)
	}else {
		newNode := initDLinkNode(key,value)
		this.addHead(newNode)
		this.cache[key] = newNode
		this.size++
		if this.size > this.capacity {
			tail :=this.removeTail()
			this.size--
			delete(this.cache,tail.key)
		}
	}
}

总结:LRU算法核心在于置换的实现

九、无重复最长子串


解答:

func lengthOfLongestSubstring(s string) int {
	start := 0
	end := 0
	for i := 0; i< len(s);i++{
		index := strings.Index(s[start:i],string(s[i]))
		if index == -1 && (i+1)>end {
			end = i + 1
		}else {
			start += index + 1
			end += index + 1
		}
	}
	return end -start
}
十、快速排序


解答:

package main

import (
	"fmt"
)

func main() {
	fmt.Println(QuickSort([]int{5,2,3,9,1,4,8,7}))
}

func QuickSort(nums []int) []int {
	if len(nums) <=1 {
		return nums
	}
	low := make([]int,0,0)
	high := make([]int,0,0)
	mid := make([]int,0,0)
	flag := nums[0]
	mid = append(mid,flag)
	for i :=1; i
		if nums[i]
			low = append(low,nums[i])
		}else if nums[i] >flag {
			high = append(high,nums[i])
		}else {
			mid = append(mid,nums[i])
		}
	}
	low,high = QuickSort(low),QuickSort(high)
	return append(append(low,mid...),high...)
}

输出:

[1 2 3 4 5 7 8 9]
十一、反转链表

解答:

func reverseList(head *ListNode) *ListNode {
	cur := head
	var pre *ListNode = nil

	for cur != nil {
		pre,cur,cur.Next = cur,cur.Next,pre   //核心,记住下一个
	}
	return pre
}
十二、内存对齐

这两个结构体占用的内存大小一样吗?

package main

import (
	"fmt"
	"unsafe"
)

type DemoA struct {
	A int8
	B int64
	C int16
}

type DemoB struct {
	A int8
	C int16
	B int64
}

func main() {
	fmt.Println(unsafe.Sizeof(DemoA{}))
	fmt.Println(unsafe.Sizeof(DemoB{}))
}

输出:

24
16

原因:

解析:链接

十三、翻转字符串

翻转字符串,可能包含有中文、数字、英文。(要求翻转原有字符串,不创建新的存储空间。

解答:

package main

import "fmt"

func main() {
	fmt.Println(reverse("dlrow olleh"))
}

//翻转字符串,可能包含有中文、数字、英文。(要求翻转原有字符串,不创建新的存储空间)
func reverse(str string) string  {
	s := []rune(str)
	for i,j :=0, len(s)-1; i
		s[i],s[j] = s[j],s[i]
	}
	return string(s)
}

输出:

hello world
十四、协程顺序执行问题

使用三个协程,每秒钟打印cat、dog、fish
顺序不能变化(协程1打印cat、协程2打印dong、协程3打印fish)
无限循环即可

解答:

package main

import (
	"fmt"
	"sync"
	"time"
)

func cat(fishCH,catCH chan struct{}, wg *sync.WaitGroup)  {
	wg.Add(1)
	go func() {
		for  {
			fmt.Println("cat")
			catCH <- struct{}{}
			<- fishCH
		}
		wg.Done()
	}()
}

func dog(catCH,dogCH chan struct{}, wg *sync.WaitGroup)  {
	wg.Add(1)
	go func() {
		for  {
			<- catCH
			fmt.Println("dog")
			dogCH <- struct{}{}
		}
		wg.Done()
	}()
}

func fish(dogCH,fishCH chan struct{}, wg *sync.WaitGroup)  {
	wg.Add(1)
	go func() {
		for  {
			<- dogCH
			fmt.Println("fish")
			time.Sleep(time.Second)
			fishCH <- struct{}{}
		}
		wg.Done()
	}()
}
func main() {
	catCH := make(chan struct{})
	dogCH := make(chan struct{})
	fishCH := make(chan struct{})
	wg := sync.WaitGroup{}
	cat(fishCH,catCH,&wg)
	dog(catCH,dogCH,&wg)
	fish(dogCH,fishCH,&wg)
	wg.Wait()
}

输出:

cat
dog
fish
cat
dog
fish
cat
dog
fish
cat
dog
fish
十五、Tag原理
package main

import (
	"fmt"
	"reflect"
)

type UserInfo struct {
	Name string `bilibili:"BILIBLI_NAME" abc:"abc_name"`
	PublicWX string `bilibili:"BILIBILI_PUBLICWX" abc:"abc_publicwx"`
}

func PrintTag(ptr interface{})  {
	reType := reflect.TypeOf(ptr)
	if reType.Kind() != reflect.Ptr || reType.Elem().Kind() != reflect.Struct {
		panic("传入的参数不是结构体指针")
		return
	}
	v := reflect.ValueOf(ptr).Elem()
	fmt.Println(v)
	for i := 0; i
		field := v.Type().Field(i)
		tag := field.Tag
		labelTag := tag.Get("bilibili")
		fmt.Println(labelTag)
		labelTag = tag.Get("abc")
		fmt.Println(labelTag)
	}
}

func main() {
	userInfo := &UserInfo{
		Name: "golang",
		PublicWX: "goland",
	}
	PrintTag(userInfo)
}

输出:

{golang goland}
BILIBLI_NAME
abc_name
BILIBILI_PUBLICWX
abc_publicwx
十六、golang中不会回收线程

原因:这是golang遗留下来的一个问题,解决这个问题相对比较麻烦,目前还没有解决

例子:

package main

import (
	"fmt"
	"net"
	"runtime"
	"runtime/pprof"
	"sync"
)

var threadProfile = pprof.Lookup("threadcreate")

func main() {
	fmt.Printf("协程执行之前的线程数:%dn",threadProfile.Count())
	var wg sync.WaitGroup
	wg.Add(100)
	for i := 0; i < 100; i++{
		go func() {
			defer wg.Done()
			//以下语句进行强制回收线程,其实也就是将goroutine强制绑定在线程上,
			//goroutine在退出的时候,如果没有去解锁线程,则线程会被操作系统终止
			runtime.LockOSThread()
			for j := 0;j<100;j++ {
				_,err := net.LookupHost("www.baidu.com")
				if err != nil {
					panic(err)
				}
			}
		}()
	}
	wg.Wait()
	fmt.Printf("协程执行之后所剩下的线程数:%dn",threadProfile.Count())
}

强制回收:将goroutine强制绑定在线程上,goroutine在退出的时候,如果没有去解锁线程,则线程会被操作系统终止,因此调用多少次绑定,就要调用多少次解锁

未加时输出:

协程执行之前的线程数:6
协程执行之后所剩下的线程数:104

加之后输出:回收部分线程

协程执行之前的线程数:6
协程执行之后所剩下的线程数:54

参考视频:链接

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/946984.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号