经典Go知识点总结

news2024/11/20 14:29:07

开篇推荐

来来来,老铁们,男人女人都需要的技术活 拿去不谢:远程调试,发布网站到公网演示,远程访问内网服务,游戏联机
推荐链接

1.无论sync.Mutex还是其衍生品都会提示不能复制,但是能够编译运行

加锁后复制变量,会将锁的状态也复制,所以 mu1 其实是已经加锁状态,再加锁会死锁.
所以此题的答案是 fatal error;

type MyMutex struct {
    count int
    sync.Mutex
}

func main() {
    var mu MyMutex
    mu.Lock()
    var mu1 = mu
    mu.count++
    mu.Unlock()
    mu1.Lock()
    mu1.count++
    mu1.Unlock()
    fmt.Println(mu.count, mu1.count)
}

2.defer对于有返回变量的函数,它的生命其可以保留到return之后.

func main() {
	fmt.Println(doubleScore(0)) //0
	fmt.Println(doubleScore(20.0)) //40
	fmt.Println(doubleScore(50.0)) //100
}
func doubleScore(source float32) (score float32) {
	defer func() {
		if score < 1 || score >= 100 {
			score = source //最终还能修改返回值
		}
	}()
	return source * 2
}

3.sync.Mutex不能重复加锁

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() //A处还没有UnLock,此处又加锁,所以出现deadlock
    defer mu.Unlock()
    chain = chain + " --> C"
}

3.go的for语句几大特别之处

a.break到指定的层级


func main() {
OuterLoop:
	for i := 0; i < 2; i++ {
	InLoop:
		for j := 0; j < 5; j++ {
			switch j {
			case 2:
				fmt.Println(i, j)
				break InLoop
			case 3:
				fmt.Println(i, j)
				break OuterLoop
			}
		}
	}
}

b.类似于while

for true{
	//do sth.
}
for{
	//do sth.
}

c.三分号的用法和c++类似

for ; step > 0; step-- {
    fmt.Println(step)
}

for ; ; i++ {
    if i > 10 {
        break
    }
}


func main() {
    v := []int{1, 2, 3}
    for i, n := 0, len(v); i < n; i++ {
        v = append(v, i)
    }
    fmt.Println(v)
}

4.go的一些预定义字符

这些不是关键字,但最好不要拿去用,面试出这样的题的话,意义不大,只能拿来搞怪.

true /false

append 函数
append 函数用于向切片中添加元素,并返回新的切片。

make 函数
make 函数用于创建切片、映射和通道。

new 函数
new 函数用于分配内存并返回指向新分配的零值对象的指针。

len 函数
len 函数用于返回字符串、切片、映射、通道、数组等的长度。

cap 函数
cap 函数用于返回切片、数组、通道等的容量。

copy 函数
copy 函数用于复制切片中的元素。

delete 函数
delete 函数用于从映射中删除指定的键值对。

print 和 println 函数
print 和 println 函数用于打印输出信息。

panic 和 recover 函数
panic 函数用于引发运行时错误,recover 函数用于捕获并处理运行时错误。

close 函数
close 函数用于关闭通道。

5.有参返回类型可以直接return

以下等价,但是return的作用域内(代码块内)必须有ret变量的存在,
下图中ret被新的ret隐藏了,导致return所在作用域丢失ret.所以无法编译.

func add1(a, b int) (ret int) {
	ret = a + b
	return
}

func add2(a, b int) (ret int) {
	ret = a + b
	return ret
}

6.json.Unmarshal必须传入目标指针

虽然map的根本就是hmap指针,但是 reflect.ValueOf(v).Kind()获取到的不是指针,所以也必须传入指针.

func (d *decodeState) unmarshal(v any) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Pointer || rv.IsNil() {//!!
		return &InvalidUnmarshalError{reflect.TypeOf(v)}
	}

	d.scan.reset()
	d.scanWhile(scanSkipSpace).
	err := d.value(rv)
	if err != nil {
		return d.addErrorContext(err)
	}
	return d.savedError
}

7.slice因为切片底层公用数组,容易导致数据共享和不能内存不能及时释放

func get() []byte {
    raw := make([]byte, 10000)
    fmt.Println(len(raw), cap(raw), &raw[0])
    return raw[:3]
}

func main() {
    data := get()
    fmt.Println(len(data), cap(data), &data[0])
}

8.go 语言中的可比较类型和不可比较类型

注意不可比较类型就三个:map slice func,可nil类型还包括chan,指针
但是chan,指针可以用于等值比较

操作符变量类型
等值操作符 (==、!=)整型、浮点型、字符串、布尔型、复数、
指针、管道、接口、结构体、数组
排序操作符 (<、<=、> 、 >=)整型、浮点型、字符串
不可比较类型map、slice、function

所以下面代码结果为false,同一类型指针是可以进行相等比较的

type foo struct{ Val int }

type bar struct{ Val int }

func main() {
	a := &foo{Val: 5}
	b := &foo{Val: 5}

	fmt.Print(a == b)
}

9.go每个case上的表达式都会执行,但只有一个chan可以读取或设置值

https://xie.infoq.cn/article/49526fb0dde758d663dfe0cd0 完整地介绍chan使用

func A() int {
	fmt.Println("A", GoID())
	time.Sleep(500 * time.Millisecond)

	return 1
}

func B() int {
	fmt.Println("B", GoID())
	time.Sleep(1000 * time.Millisecond)

	return 2
}

func GoID() uint64 {
	b := make([]byte, 64)
	b = b[:runtime.Stack(b, false)]
	b = bytes.TrimPrefix(b, []byte("goroutine "))
	b = b[:bytes.IndexByte(b, ' ')]
	n, _ := strconv.ParseUint(string(b), 10, 64)
	return n
}

func main() {
	ch := make(chan int, 1)
	go func() {
		select {
		case ch <- A():
			{
				fmt.Println("caseA")
			}
		case ch <- B():
			{
				fmt.Println("caseB")
			}
		default:
			ch <- 3
		}
	}()
	for v := range ch {
		fmt.Println(v)
	}
}

10.基础类型的map可以++,非基础类型不行.

这种差异造成诡异的心智负担.

func main() {
	m := make(map[string]int)
	m["foo"]++ //基础类型没有问题
	fmt.Println(m["foo"])

	m2 := map[string]Person{}
	m2["foo"] = Person{1}
	m2["foo"].Age = 22 //非法操作

}

type Person struct {
	Age int
}

11.一个接口是否==nil,要看其类型和数值是否同时为nil

打印则看数值

func Foo() error {
	var err *os.PathError = nil
	return err
}

func main() {
	err := Foo()
	fmt.Println(err) //nil,打印则看数值
	fmt.Println(err == nil) //false
}

func main() {
    x := interface{}(nil)
    y := (*int)(nil)
    a := y == x //类型不一样
    b := y == nil //y不是接口,所以直接看值.如果var y any = (*int)(nil)就变成接口了.最后接口就是false.
    _, c := x.(interface{}) //没有类型,断言失败
    println(a, b, c) //flase true false
}

12.在go里面0开始的数字是八进制

const (
	Decade = 010
)

func main() {
	fmt.Println(Decade) //8
}

13.字符串Trim操作注意

Trim结尾处的字符串,对应其他语言的TrimEnd

TrimSuffix
切勿使用TrimRight,会将第二个参数字符串里面所有的字符拿出来处理,只要与其中任何一个字符相等,便会将其删除

    fmt.Println(strings.TrimRight("ABBA", "BA")) //最后全部被删了

Trim以某段开始的字符串,对应其他语言的TrimStart

TrimPrefix

    fmt.Println(strings.TrimLeft("ABBAC", "BA")) //最后只会剩下C

14.关于for range

如果是chan则,没有k,只有v;

	for v := range ch {
		fmt.Println(v)
	}

15.关于切片两个冒号的说明

https://segmentfault.com/a/1190000018356577

注意

我们潜意识觉得cap就是底层数组的长度,但是在尽显冒号切片时,cap的长度是有max-low得到的,max的默认值为源切片(或源数组)的cap.

通过两个冒号创建切片,slice[x:y:z]切片实体[x:y]切片长度len = y-x,切片容量cap = z-x\

data := [...]int{0, 1, 2, 3, 4, 5, 6} //初始化一个数组
slice := data[1:4:5] // [low : high : max]  通过两个冒号创建切片

使用两个冒号[1:4:5] 从数组中创建切片,长度为4-1=3,也就是索引从1到3 的数据(1,2,3)

然后,后面是最大是5,即容量是5-1=4,即,创建的切片是长度为从索引为 1、2、3 的切片,底层数组为[ 1,2,3,4]

data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

data[:6:8] [0 1 2 3 4 5]         //默认low为0
data[5:] [5 6 7 8 9]             //省略 high、 max,默认值为源切片(或源数组)的cap
data[:3] [0 1 2]                 //low=0,max=默认值为源切片(或源数组)的cap
data[:] [0 1 2 3 4 5 6 7 8 9]    //10 10 全部省略。

一道题懂了,那真懂了.

func main() {
	a := []int{0, 1, 2, 3}
	s := a[1:3]  //1,2,[3]
	s2 := s[1:2] //2,[3]
	fmt.Println(cap(s), len(s))
	fmt.Println(cap(s2), len(s2))
	fmt.Println("--------------------------------")
	s2 = append(s2, 333)

	fmt.Println(a)
	fmt.Println(s)
	fmt.Println(s2)
}
3 2
2 1
--------------------------------
[0 1 2 333]
[1 2]
[2 333]

16.关于切片的一些手法

创建空切片

// 使用 make 创建空的整型切片
slice := make([]int, 0)
// 使用切片字面量创建空的整型切片
slice := []int{}

17.for range 常数

for i := range 10 {
		fmt.Println(i)
}

18.关于一切等值运算的根本是比较补码


func main() {
	count := 0
	for i := range [256]struct{}{} {
		m, n := byte(i), int8(i)
		if n == -n {
			count++
			fmt.Println("n==-n", n, -n, i)
		}
		if m == -m {
			count++
			fmt.Println("m==-m", m, -m, i)
		}
	}
	fmt.Println(count)

}

n==-n 0 0 0
m==-m 0 0 0
n==-n -128 -128 128
m==-m 128 128 128
4

-128 的补码:

首先,我们需要知道 -128 的原码。原码是表示数值的二进制形式,其中最高位表示符号位(0 表示正数,1 表示负数),其余位表示数值部分。对于 -128,其原码为 1000 0000。

接下来,我们求出 -128 的反码。反码是将原码的除符号位外的各位取反。对于 -128,其反码为 1111 1111。

最后,我们计算 -128 的补码。补码是在反码的末位加1,从而使后7位再次发生溢出,进位丢弃,符号位不变。因此,-128 的补码为 1000 0000。

需要注意的是,-128 是一个特殊的数,因为它的绝对值比最小的32位整数还要大1,所以在计算机中表示为 -128 的补码时,我们直接使用其反码加1的结果。

128的补码
128 的原码是 10000000。三码都是这个,所以也是 10000000。

19.多重赋值的优先级

多重赋值分为两个步骤,有先后顺序:

  • 计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式;
  • 赋值;
func main() {
    var a []int = nil
    a, a[0] = []int{1, 2}, 9
    fmt.Println(a)
}

解析:运行时错误。知识点:多重赋值。

19.sync.WaitGroup不能复制值,且需要在启动协程前Add

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 5; i++ {
        go func(wg sync.WaitGroup, i int) {
            wg.Add(1)
            fmt.Printf("i:%d\n", i)
            wg.Done()
        }(wg, i)
    }
    wg.Wait()
    fmt.Println("exit")
}

20.chan的基本数据结构

ype hchan struct {
  qcount   uint  // 队列中的总元素个数
  dataqsiz uint  // 环形队列大小,即可存放元素的个数
  buf      unsafe.Pointer // 环形队列指针
  elemsize uint16  //每个元素的大小
  closed   uint32  //标识关闭状态
  elemtype *_type // 元素类型
  sendx    uint   // 发送索引,元素写入时存放到队列中的位置

  recvx    uint   // 接收索引,元素从队列的该位置读出
  recvq    waitq  // 等待读消息的goroutine队列
  sendq    waitq  // 等待写消息的goroutine队列
  lock mutex  //互斥锁,chan不允许并发读写
}

21.cap 关于 cap 函数适用下面哪些类型?

A. 数组;
B. channel;
C. map;
D. slice;

func main() {
	c := make(chan int, 2)
	c <- 11
	fmt.Println(len(c)) //1
	fmt.Println(cap(c)) //2
}

22.启动一个goroutine的前提是,还有数

func main() {
    runtime.GOMAXPROCS(1)

    go func() {
        for i:=0;i<10 ;i++  {
            fmt.Println(i)
        }
    }()

    for {}
}

23.接收器方法在defer时也会优先求值

type Slice []int

func NewSlice() Slice {
    return make(Slice, 0)
}
func (s *Slice) Add(elem int) *Slice {
    *s = append(*s, elem) //!! 注意无名类型的特别之处.
    fmt.Print(elem)
    return s
}
func main() {
    s := NewSlice()
    defer s.Add(1).Add(2)
    s.Add(3)
}
//1 3 2

24.闭包引用相同变量,那么他们的作用效果都在这个变量上

func test(x int) (func(), func()) {
    return func() {
        println(x)
        x += 10
    }, func() {
        println(x)
    }
}

func main() {
    a, b := test(100)
    a()
    b()
}
// 100 110

25.range相当于一个函数,会对传入的数据进行拷贝.

因此,下面切片和数组的场景会产生不同的值

type T struct {
	n int
}

func main() {
	ts := [2]T{}
	//ts := make([]T, 2)
	for i, t := range ts {
		switch i {
		case 0:
			t.n = 3
			ts[1].n = 9 //改变了ts,但t的数据,源头是range产生的拷贝
		case 1:
			fmt.Print(t.n, " ")
		}
	}
	fmt.Print(ts)
}

// 数组 0 [{0} {9}]
// 切片 9 [{0} {9}]


//--------------
func main() {
     var a = []int{1, 2, 3, 4, 5}
     var r = make([]int, 0)
     for i, v := range a { //这里产生了新的副本,所以下面的添加操作不影响遍历.
         if i == 0 {
             a = append(a, 6, 7)
         }
        r = append(r, v)
    }
    fmt.Println(r)
}

25.关于defer func recover panic

  • panic会将恐慌压入一个后进先出的栈里面;
  • recover 必须内置于defer func 内才有效;
  • recover从panic栈中取值;
func main() {
    defer func() {
        fmt.Print(recover())
    }()
    defer func() {
        defer func() {
            fmt.Print(recover())
        }()
        panic(1)
    }()
    defer recover() //这里的recover没有效果,因为没有在defer func内部
    panic(2)
}

上面的代码panic依次入站 2 ,1,出栈为1 ,2,所以结果 1 2

func main() {
    defer func() {
        fmt.Print(recover())
    }()
    defer func() {
        defer fmt.Print(recover()) //首先参数需要求值,所以在当前执行func完毕时要打印2
        panic(1) //压入栈中,当前有没有机会了,上级会捕捉到.
    }()
    defer recover() //这里的recover没有效果,因为没有在defer func内部
    panic(2)
}

结果为 2 1

26. 当闭包含有外层变量时,会让外面的变量一直活着

func F(n int) func() int {
    return func() int {
        n++
        return n
    }
}

func main() {
    f := F(5) //参数为5
    defer func() {
        fmt.Println(f())
    }()
    defer fmt.Println(f()) //需要立即求值,所以最后打印6,参数变成为了6
    i := f() //参数变成了7,
    fmt.Println(i)//打印7
}

//最后结果768

27.关于for,range对枚举器的赋值

func main() {
	var k = 9
	for k = range []int{} { //没有数据,所以对k的赋值,没能执行
	}
	fmt.Println(k)

	for k = 0; k < 3; k++ {
	}
	fmt.Println(k) //很明显上面导致k变成了3

	for k = range (*[3]int)(nil) { //一个[三个数据的数组]的指针,虽然是nil,但是在go里面这是合法的,最终k变成2
	}
	fmt.Println(k)
}

28.关于继承的本质问题



type T struct{}

func (*T) foo() {
}

func (T) bar() {
}

type S struct {
    *T //注意指针也可以,也即,没有名称只有类型,那么我们就可以通过语法糖的方式,好像调用自己的方法一样调用
}

func main() {
    s := S{}
    _ = s.foo
    s.foo() //这个是没有问题的.虽然就nil,但因为没有发生调用nil,所以没有问题
    _ = s.bar // (* s.T).bar,但指针s.T为nil,解引用失败报错
}

//---------------这是可以的
type X struct {}
func (x *X) test()  {
   println(x)
}
func main() {
    var a *X
    a.test()//nil,不是null
    X{}.test() //这里有问题,右值不可寻址
}
//--------------------------------------

type Father struct{ Name string }
type Monther struct {
    Name string
}

func (m Monther) World() {

}

type Child struct {
    Father
    Monther
}

func (entity Father) Hello() {

}
func (entity Father) World() {

}

func main() {
    child := Child{}
    child.World() //二义性语法糖就用不了,需要指明Father or Monther的方法
}

//-----------------------


- 匿名字段的本质字段名是
S *S
S S

- 然后调用他们对应的接收器方法。
- 如果T为指针,则全有,不问上面的两种情况了

- 能不能改变原有数据,取决于接收器是不是指针类型
 
func main() {
   var v T
   t := &v
   fmt.Printf("%p\n", t.S)
   t.SPtr(1) //因为t指针类型,所以拥有S,*S的接收器方法
   t.SPtr(1)
   fmt.Println(t.S.Age)
}
type S struct {
   Age int
}
type T struct {
   S
}
func (s S) SVal(dd int) {
   s.Age = 10
   fmt.Printf("%p\n", &s)
}
func (s *S) SPtr(dd int) {
   fmt.Printf("%p\n", s)
   s.Age = 100
}
func (t T) TVal(dd int) {
}
func (t *T) TPtr(dd int) {
}
func methodSet(arg interface{}) {
   argType := reflect.TypeOf(arg)
   fmt.Println(argType.NumMethod())
   for i := 0; i < argType.NumMethod(); i++ {
      m := argType.Method(i)
      fmt.Printf("%s: %v\n", m.Name, m.Type)
   }
}
//----------
type Fragment interface {
        Exec(transInfo *TransInfo) error
}
type GetPodAction struct {
}
func (g GetPodAction) Exec(transInfo *TransInfo) error {
        ...
        return nil
}
指针接收器拥有值接口器的方法
var fragment Fragment = new(GetPodAction)


图片名称

##29.关于map的怪异之处,面试时尤其注意

func main() {
	var m map[int]bool // nil
	var a = m[123]
	fmt.Println(a)//false,原因很简单,nil不是null,map不仅允许读取没有的key,还允许读取nil的map
}

30.关于切片

  • 关于切片之前的理解是有问题的,我们切片的对象是底层真实的数组长度(即:容量)
  • low,high,max high默认是slice的长度,max则为容量
func main() {
	x := make([]int, 2, 10)
	a := x[6:10]
	b := x[6:] //x[6:2],所以这里要报错
	c := x[2:] //2-2=0,所以最后是空的
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
}


31.不可比较类型 slice map func

func main() {

	var x interface{}
	var y interface{} = []int{3, 5}
	_ = x == x
	_ = y == x //注意虽然slice是不可以比较的类型,但是它可以和any nil比较
	println("end")
	_ = y == y //2 slice是不可以比较的
}

32.对于接收器方法的表达,我们都很陌生

type N int

func (n N) test() {
	fmt.Println(n)
}

func main() {
	var n N = 10
	fmt.Println(n)

	n++
	//func (N).test()
	f1 := N.test
	f1(n)

	n++
	//var f2 func(*N)
	f2 := (*N).test
	f2(&n)
}

33.读写nil类型的chan都会永远阻塞

func main() {
    var ch chan int
    select {
    case v, ok := <-ch:
        println(v, ok)
    default:
        println("default") 
    }
}

34.:=操作符不能给结构体字段赋值

type foo struct {
    bar int
}

func main() {
    var f foo
    f.bar, tmp := 1, 2
}

35.go中所有的变量申明了就必须用,但常量除外,常量不能取地址

func main() {
    const x = 123
    const y = 1.23
    fmt.Println(x)
}

36.byte在go中是uint8的别名,他们完全等价

type byte = uint8

func test(x byte)  {
    fmt.Println(x)
}

func main() {
    var a byte = 0x11 
    var b uint8 = a
    var c uint8 = a + b
    test(c)
}

37.关于给切片加索引赋值的注意项

  • 字面量初始化切片时候,可以指定索引,没有指定索引的元素,其索引=前一个索引+1,
  • 空缺的索引的位置,数据就是零值
var x = []int{2: 2, 3, 0: 1}

func main() {
    fmt.Println(x) // [1 0 2 3]
}

38.关于select

A. select机制用来处理异步IO问题;//输入输出,要读取或写入chan

B. select机制最大的一条限制就是每个case语句里必须是一个IO操作;

C. golang在语言级别支持select关键字;

39.指针类型的map和slice均不能使用索引

40.chan的写入方负责关闭,不然造成泄露

func main() {
     ch := make(chan int, 100)
     // A
     go func() {              
         for i := 0; i < 10; i++ {
             ch <- i
         }
     }()
     // B
    go func() {
        for {
            a, ok := <-ch
            if !ok {
                fmt.Println("close")
                return
            }
            fmt.Println("a: ", a)
        }
    }()
    close(ch)
    fmt.Println("ok")
    time.Sleep(time.Second * 10)
}

41. chan的几个特性

A. 给一个 nil channel 发送数据,造成永远阻塞

B. 从一个 nil channel 接收数据,造成永远阻塞

C. 给一个已经关闭的 channel 发送数据,引起 panic

D. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值

42.类型转换的方式和c系有差异需要注意

B.
type MyInt int
var i int = 1
var j MyInt = (MyInt)i //c系的方式,在go里面是非法的

C.

type MyInt int
var i int = 1
var j MyInt = MyInt(i)//在才是正确的方式.

43.关于for range枚举器,不同版本有不同定义

type Foo struct {
bar string
}
func main() {
s1 := []Foo{
{“A”},
{“B”},
{“C”},
}
s2 := make([]*Foo, len(s1))
for i, value := range s1 {
s2[i] = &value
}
fmt.Println(s1[0], s1[1], s1[2])
fmt.Println(s2[0], s2[1], s2[2])
}
1.22输出:
{A} {B} {C}
&{A} &{B} &{C}

1.22之前
s2 的输出是 &{C} &{C} &{C}

43.关于defer nil方法

func f(n int) (r int) {
	defer func() {
		r += n
		recover() //这里捕捉了nil方法的调用
	}()

	var f func()

	defer f() //f是一个nil,所以没有机会执行下面的方法
	f = func() {
		fmt.Println("f called")
		r += 2
	}
	return n + 1
}

func main() {
	fmt.Println(f(3)) //7
}

https://www.topgoer.cn/docs/gomianshiti/mian28

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1475324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4核8G服务器并发数多少?性能如何?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

React Switch用法及手写Switch实现

问&#xff1a;如果注册的路由特别多&#xff0c;找到一个匹配项以后还会一直往下找&#xff0c;我们想让react找到一个匹配项以后不再继续了&#xff0c;怎么处理&#xff1f;答&#xff1a;<Switch>独特之处在于它只绘制子元素中第一个匹配的路由元素。 如果没有<Sw…

[极客大挑战 2019]LoveSQL1 题目分析与详解

一、题目简介&#xff1a; 二、通关思路&#xff1a; 1、首先查看页面源代码&#xff1a; 我们发现可以使用工具sqlmap来拿到flag&#xff0c;我们先尝试手动注入。 2、 打开靶机&#xff0c;映入眼帘的是登录界面&#xff0c;首先尝试万能密码能否破解。 username: 1 or 11…

IDEA如何开启Dashboard

普通的面板 Run Dashboard面板 修改配置文件 找到项目的.idea文件夹 点击编辑workspace.xml文件 添加下方代码 <component name"RunDashboard"><option name"ruleStates"><list><RuleState><option name"name" valu…

雾锁王国服务器配置怎么选择?阿里云和腾讯云

雾锁王国/Enshrouded服务器CPU内存配置如何选择&#xff1f;阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置&#xff0c;支持4人玩家畅玩&#xff0c;自带10M公网带宽&#xff0c;1个月90元&#xff0c;3个月271元&#xff0c;幻兽帕鲁服务器申请页面 https://t.aliyun.com…

通过QScrollArea寻找最后一个弹簧并且设置弹簧大小

项目原因&#xff0c;最近需要通过QScrollArea寻找其中最后一个弹簧并且设置大小和策略&#xff0c;因为无法直接调用UI指针&#xff0c;所以只能用代码寻找。 直接上代码&#xff1a; if (m_scrollArea){int iScrollWidth m_labelSelectedTitle->width();m_scrollArea-&g…

数据结构与算法(数组,栈,队列,链表,哈希表,搜索算法,排序算法,查找算法,策略算法,递归算法,二叉搜索树BST,动态规划算法)

文章目录 1 课程介绍1.1 前置知识1.2 为什么要学习算法1.3 大厂面试常见数据结构题目(基础)1.4 数据结构和算法的关系 2 数据结构2.1 数据结构概述2.1.1 数据结构是什么2.1.2 数据结构分类2.1.2.1 线性结构2.1.2.2 非线性结构2.1.2.3 小总结 2.1.3 数据结构范围 2.2 数组Array2…

前端基础面试题(二)

摘要&#xff1a;最近&#xff0c;看了下慕课2周刷完n道面试题&#xff0c;记录下... 1. offsetHeight scrollHeight clientHeight 区别 计算规则&#xff1a; offsetHeight offsetWidth : border padding content clientHeight clientWidth: padding content scrollHeight…

unity学习(42)——创建(create)角色脚本(panel)——UserHandler(收)+CreateClick(发)——服务器收包2

1.解决上一次留下的问题&#xff1a; log和reg的时候也有session&#xff0c;输出看一下这两个session是同一个不&#xff1a; 实测结果reg log accOnline中的session都是同一个对象&#xff0c;但是getAccid时候的session就是另一个了。 测试结果&#xff0c;说明在LogicHan…

lv21 QT对话框3

1 内置对话框 标准对话框样式 内置对话框基类 QColorDialog, QErrorMessage QFileDialog QFontDialog QInputDialog QMessageBox QProgressDialogQDialog Class帮助文档 示例&#xff1a;各按钮激发对话框实现基类提供的各效果 第一步&#xff1a;实现组件布局&…

水电表远程集中抄表管理系统

水电表远程集中抄表管理系统是当前水电行业智能化发展的关键技术之一&#xff0c;为水电企业和用户提供了便捷、高效的抄表管理解决方案。该系统结合了远程监控、自动抄表、数据分析等多种功能&#xff0c;实现了水电抄表的智能化和精准化&#xff0c;为用户节省了大量人力物力…

The authenticity of host ‘github.com (20.205.243.166)‘ can‘t be established.

1、运行git clone报错&#xff1a; The authenticity of host github.com (20.205.243.166) cant be established. ECDSA key fingerprint is SHA256:p2QAC1TJYererOttrVc98/R1BWERWu3/LiyFdHfQM. Are you sure you want to continue connecting (yes/no/[fingerprint])? 这个…

【六袆-Golang】Golang:安装与配置Delve进行Go语言Debug调试

安装与配置Delve进行Go语言Debug调试 一、Delve简介二、win-安装Delve三、使用Delve调试Go程序[命令行的方式]四、使用Golang调试程序 Golang开发工具系列&#xff1a;安装与配置Delve进行Go语言Debug调试 摘要&#xff1a; 开发环境中安装和配置Delve&#xff0c;一个强大的G…

2024年腾讯云4核8G12M配置的轻量服务器同时支持多大访问量?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

HUAWEI 华为交换机 配置基于VLAN的MAC地址学习限制接入用户数量 配置示例

组网需求 如 图 2-15 所示&#xff0c;用户网络 1 通过 LSW1 与 Switch 相连&#xff0c; Switch 的接口为 GE0/0/1 。用户网络2通过 LSW2 与 Switch 相连&#xff0c; Switch 的接口为 GE0/0/2 。 GE0/0/1 、 GE0/0/2 同属于 VLAN2。为控制接入用户数&#xff0c;对 VLAN2 进…

Eclipse是如何创建web project项目的?

前面几篇描述先后描述了tomcat的目录结构和访问机制&#xff0c;以及Eclipse的项目类型和怎么调用jar包&#xff0c;还有java的main函数等&#xff0c;这些是一些基础问题&#xff0c;基础高清出来才更容易搞清楚后面要说的东西&#xff0c;也就是需求带动学习&#xff0c;后面…

element el-table表格内容宽度自适应,不换行,不隐藏

2024.2.27今天我学习了如何用el-table实现表格宽度的自适应&#xff0c;当我们动态渲染表格数据的时候&#xff0c;有时候因为内容太多会出现挤压换行的效果&#xff1a; 我们需要根据内容的最大长度设置动态的宽度&#xff0c;这边我在utils里面封装了一个js&#xff1a; //…

OpenAI划时代大模型——文本生成视频模型Sora作品欣赏(八)

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…

数据界的达克摩斯之剑----深入浅出带你理解网络爬虫(Third)

目录 网络爬虫示例 1.爬行策略 1.1 选择策略&#xff1a; 1.1.1 限定访问链接 1.1.2 路径检索 1.1.3 聚焦抓取 1.1.5 WEB3.0检索 1.2重新访问策略 1.3 平衡礼貌策略 1.4 并行策略 2.网络爬虫体系结构 2.1 URL一般化 接上文数据界的达克摩斯之剑----深入浅出带你理解…

【主题广范|见刊快】2024年电力电气与机械,能源工程国际会议(ICPEMEE 2024)

【主题广范|见刊快】2024年电力电气与机械&#xff0c;能源工程国际会议&#xff08;ICPEMEE 2024&#xff09; 重要信息 会议官网&#xff1a;http://www.icpemee.com会议地址&#xff1a;合肥截稿日期&#xff1a;2024.03.10召开日期&#xff1a;2024.03.20 &#xff08;先投…