golang面试题

目录

go版本新增功能

Go 1.11

Go 1.18

Go 1.5

go关键字 :

1. 用于声明的关键字

2. 控制流关键字

3. 包相关关键字

4. 并发相关关键字

5. 异常处理关键字

6. 接口和类型断言关键字

go数据类型: 

复合数据类型

引用数据类型

接口类型

GC垃圾回收机制

工作流程

采用的方法

触发时机

 深拷贝与浅拷贝

 函数和方法的区别:

 Go函数参数传递到底是值传递还是引用传递

为什么map遍历是无序的:

 slice扩容机制

 方法值类型接收者和指针类型接收者的区别

 go的互斥锁抢锁的两种模式(sync.Mutex)

正常模式

饥饿模式

 goroutine和线程的区别

1. 内存占用

2. 创建销毁开销

3. 调度

4. 通信

5. 并发规模

 goroutine泄露

原因

危害

解决办法

 GMP调度原理

基本概念

调度流程

1. 启动阶段

2. 创建 Goroutine

3. 调度执行

4. 阻塞和唤醒

5. 系统调用

调度优势

 什么是通道,它的底层是什么

通道是什么

通道底层结构

 生产者和消费者怎么关闭管道

基本规则

不同场景关闭方式

 如何检测通道关闭

 通道和锁的区别

设计理念

使用场景

并发控制

代码复杂度

性能表现

 数组和切片的区别

 定义和长度特性

内存分配

长度和容量

使用灵活性


go版本新增功能

Go 1.11 、Go 1.18、Go 1.5

Go 1.11

  • 核心亮点:正式推出了模块(Module)系统,这是 Go 语言依赖管理的重大变革。在此之前,Go 语言的依赖管理比较混乱,模块系统的引入解决了依赖管理的难题,使得 Go 项目的依赖管理更加简单、可靠和可复现。
  • 其他特性:支持 WebAssembly(Wasm),允许 Go 代码在浏览器和其他支持 Wasm 的环境中运行,拓宽了 Go 语言的应用场景

Go 1.18

  • 核心亮点:这一版本最大的亮点是引入泛型,这是 Go 语言发展历程中的一个重大里程碑。泛型允许开发者编写与具体类型无关的代码,极大提高了代码复用性,减少了代码冗余。例如,开发者可以编写一个通用的排序函数,用于对不同类型的切片进行排序,而无需为每种类型都编写一个特定的排序函数。
    // 泛型函数:返回两个同类型值中的最大值
    func Max[T int | float64](a, b T) T {if a > b {return a}return b
    }
  • 其他特性:还引入了模糊测试(Fuzzing)功能,帮助开发者更有效地发现代码中的潜在漏洞;工作区模式(Workspace Mode)则方便了多模块项目的管理;切片扩容机制也得到了优化,提升了内存使用效率和性能。

Go 1.5

  • 核心亮点:实现了自举(Self - Bootstrapping),即 Go 编译器完全用 Go 语言重写,摆脱了对 C 语言的依赖。这不仅简化了 Go 语言的编译过程,也让 Go 语言的开发和维护更加独立和灵活。
  • 其他特性:引入了全新的垃圾回收器(GC),大幅降低了垃圾回收时的停顿时间,提高了程序的响应性能和吞吐量。同时,Go 运行时(runtime)的调度器也得到了改进,优化了 goroutine 的调度算法,提高了并发性能。

go关键字 

1. 用于声明的关键字
  • var:用于声明变量,如 var num int = 10
  • const:用于声明常量,如 const Pi = 3.14
  • type:用于声明自定义类型,如 type Person struct { Name string; Age int }
  • func:用于声明函数,如 func add(a, b int) int { return a + b }
2. 控制流关键字
  • ifelseelse if:用于条件判断。
  • for:用于循环操作,Go 语言中只有 for 一种循环结构,但可实现多种循环形式。
  • switchcasedefault:用于多条件分支判断。
  • break:用于跳出循环或 switch 语句。
  • continue:用于跳过当前循环的剩余部分,直接进入下一次循环。
  • goto:用于无条件跳转到指定的标签处,不过在实际编程中应谨慎使用,以免导致代码可读性变差。
3. 包相关关键字
  • package:用于声明当前文件所属的包,每个 Go 文件都必须以 package 声明开头。
  • import:用于导入其他包,以便使用该包中导出的函数、变量等。
4. 并发相关关键字
  • chan:用于声明通道(channel),通道是 Go 语言中用于在 goroutine 之间进行通信和同步的重要工具。
  • select:用于处理多个通道的并发操作,类似于 switch 语句,但用于通道的读写操作。
5. 异常处理关键字
  • defer:用于延迟函数的执行,无论包含 defer 语句的函数是正常返回还是发生异常,defer 后的函数都会在该函数返回前执行。
  • panic:用于触发一个运行时错误,程序会停止正常的执行流程,开始回溯调用栈并执行 defer 函数,直到程序崩溃。
  • recover:用于从 panic 中恢复,通常在 defer 函数中使用。
6. 接口和类型断言关键字
  • interface:用于声明接口类型。
  • struct:用于声明结构体类型。
  • map:用于声明映射类型。
  • fallthrough:在 switch 语句中使用,用于强制执行下一个 case 分支,而不进行条件判断。

go数据类型

  • 布尔型bool
  • 数值型
    • 整数intint8int16int32int64uintuint8uint16uint32uint64uintptr
    • 浮点数float32float64
    • 复数complex64complex128
    • 字节byte
    • 符文rune
  • 字符串型string

复合数据类型

  • 数组[n]Tn 为数组长度,T 为元素类型)
  • 结构体struct{...}

引用数据类型

  • 切片[]TT 为元素类型)
  • 映射map[K]VK 为键类型,V 为值类型)
  • 通道chan TT 为通道传递的数据类型)

接口类型

  • 接口interface{...}

GC垃圾回收机制

工作流程

  • 标记阶段:想象 GC 是一个拿着 “标记笔” 的人,从一些固定的地方(像全局变量、正在运行的函数里的变量等)开始找东西。找到一个能用的东西(对象)就给它做个标记,然后顺着这个东西里面的线索(引用)继续找下一个,直到把所有能找到的东西都标记好。
  • 清除阶段:标记完后,GC 会再走一遍所有的地方,看看哪些东西没有被标记,这些没标记的就是没人用的 “垃圾”,GC 就会把它们清理掉,让这些被占用的空间可以被重新使用。

采用的方法

  • 三色标记法:GC 把所有东西分成白色、灰色和黑色。刚开始所有东西都是白色,不知道有没有用。然后从一些确定有用的地方开始找,找到的白色东西就变成灰色,放到一个 “待办清单” 里。接着 GC 会从 “待办清单” 里拿出灰色的东西,把它引用的白色东西也变成灰色,然后把自己变成黑色,表示已经检查过了。最后剩下的白色东西就是没用的 “垃圾”。
  • 分代回收:GC 把内存里的东西分成年轻的和年老的。新产生的东西一般放在年轻组,因为新东西很可能很快就没用了,所以会经常检查年轻组,把没用的清理掉。有些东西一直没被清理,就会被放到年老组,年老组检查的次数会少一些。这样可以提高清理效率。
  • 并发回收:GC 不会一直让程序停下来等它清理垃圾,而是会在程序运行的时候,找机会一起做清理工作。就像一个人一边做自己的事情,一边利用空闲时间打扫卫生,这样不会耽误太多正常做事的时间。

触发时机

  • 定时触发:GC 有个 “闹钟”,每隔一段时间就会响,响了之后 GC 就会开始工作,检查有没有垃圾要清理。
  • 内存分配触发:当程序要分配新的内存空间,如果发现已经用掉的内存太多了,达到了一个规定的数量,就会马上让 GC 来清理垃圾,腾出空间

 深拷贝与浅拷贝

  • 浅拷贝:浅拷贝只复制对象的一层属性。对于基本数据类型(如整数、字符串、布尔值等),会直接复制其值;而对于引用数据类型(如对象、数组),复制的是该引用数据类型的内存地址,而不是对象本身。这意味着浅拷贝后,新对象和原对象会共享引用数据类型的内部对象,修改其中一个对象的引用类型属性,另一个对象也会受到影响。
  • 深拷贝:深拷贝会递归地复制对象的所有层级属性。它会创建一个完全独立的新对象,新对象和原对象在内存中是完全分离的,拥有各自独立的属性值。对于引用数据类型,深拷贝会深入到对象内部,将其所有嵌套的对象也复制一份,因此对新对象的任何修改都不会影响原对象,反之亦然

 函数和方法的区别

  函数是独立的代码单元,不与特定类型绑定,直接通过函数名调用以完成通用任务;而方法是与特定类型关联的函数,需通过该类型的实例调用,用于操作该类型实例并处理其相关逻辑

 Go函数参数传递到底是值传递还是引用传递

  值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数

  Go 语言中有一些数据类型,如切片(slice)、映射(map)、通道(channel)等,当它们作为参数传递时,看起来好像是引用传递,但实际上仍然是值传递。这些类型本身是引用类型,它们的值包含了一个指向底层数据结构的指针,当作为参数传递时,传递的是这个指针的副本

为什么map遍历是无序的:

  Go 语言的设计者有意让 map 遍历时无序,这主要是为了避免开发者在代码里依赖 map 元素的顺序。因为在不同版本的 Go 编译器或者运行环境下,map 内部的实现细节可能会发生变化,如果代码依赖了 map 元素的顺序,就可能导致程序行为不稳定。

map 底层是使用哈希表实现的,当你向 map 里插入元素时,元素会依据哈希函数的计算结果被放置到不同的桶(bucket)中。在遍历 map 时,Go 语言并不会按照元素插入的顺序或者键的顺序来访问,而是随机选择一个起始位置,然后按照内部的哈希表结构依次访问各个桶中的元素。并且,每次遍历 map 时,起始位置都是随机的,这就使得每次遍历的顺序都可能不同

 slice扩容机制

 array:指向底层数组的指针

   len:切片的长度,表示切片当前包含的元素个数        

   cap:切片的容量,表示切片底层数组的长度

  扩容的触发条件:

  当向切片中添加元素时,如果切片的长度 len 等于其容量 cap,此时再添加元素就会触发扩容操作。常见的触发场景是使用 append 函数向切片中追加元素

go1.18之前:

  • 如果新的元素数量(即原切片长度加上要追加的元素数量)大于原切片容量的 2 倍,则直接将容量扩容为新元素数量。
  • 如果原切片容量小于 1024,则将容量翻倍。
  • 如果原切片容量大于等于 1024,则每次增加原容量的 1/4,直到容量足够为止

go1.18之后:

  • 如果新的元素数量大于原切片容量的 2 倍,则直接将容量扩容为新元素数量。
  • 否则,若原切片长度小于 256,则将容量翻倍。
  • 若原切片长度大于等于 256,则按照公式 newcap = oldcap + (oldcap + 3*256) / 4 进行扩容,直到容量足够为止

 方法值类型接收者和指针类型接收者的区别

方法值类型接收者传递对象副本,方法内修改不影响原对象,调用时值和指针类型对象通用,适合无需修改接收者或对象较小场景;指针类型接收者传递对象地址,方法内修改影响原对象,虽值和指针类型对象通常都能调用但语义上指针更直接,适用于需修改接收者或对象较大场景

 go的互斥锁抢锁的两种模式(sync.Mutex)

正常模式

  • 竞争规则:多个 goroutine 竞争锁时,新请求锁的 goroutine 与被唤醒等待锁的 goroutine 一起竞争。由于新请求锁的 goroutine 正在 CPU 上运行,在竞争中更具优势,能优先获得锁。
  • 性能特点:吞吐量较高,因为减少了 goroutine 进入和退出等待队列的上下文切换开销,但在高并发场景下,可能导致部分等待中的 goroutine 长时间获取不到锁,出现 “饥饿” 现象。

饥饿模式

  • 触发条件:当一个 goroutine 等待锁的时间超过 1 毫秒,互斥锁会从正常模式切换到饥饿模式。
  • 竞争规则:锁的所有权直接交给等待队列中最早等待的 goroutine,新请求锁的 goroutine 不会尝试获取锁,而是直接加入等待队列尾部。
  • 性能特点:保证了每个等待锁的 goroutine 最终都能获取到锁,避免了 “饥饿” 问题,但会降低系统整体吞吐量,因为新请求锁的 goroutine 无法立即获取锁,增加了上下文切换次数。

当等待队列中没有等待的 goroutine 或者最后一个等待的 goroutine 等待时间小于 1 毫秒时,互斥锁会从饥饿模式切换回正常模式

 goroutine和线程的区别

1. 内存占用

  • 线程:栈空间初始固定且大,一般几兆,易造成内存浪费。
  • goroutine:栈空间动态分配,初始小(约 2KB),按需伸缩,节省内存。

2. 创建销毁开销

  • 线程:涉及内核操作,开销大。
  • goroutine:由 Go 运行时管理,开销极小。

3. 调度

  • 线程:由操作系统内核抢占式调度,上下文切换开销大。
  • goroutine:Go 运行时调度,用户态切换,开销小。

4. 通信

  • 线程:多靠共享内存,需同步机制,易有安全问题。
  • goroutine:用通道通信,避免数据竞争,更安全简单。

5. 并发规模

  • 线程:数量受限,几百到几千。
  • goroutine:可轻松创建数万个甚至更多

 goroutine泄露

原因

  • 无限循环:Goroutine 里无退出条件的循环,持续运行不停止。
  • 通道阻塞:发送数据到已满通道且无接收操作,或从空且未关闭通道接收数据。
  • 锁未释放:加锁后没解锁,使其他等锁的 Goroutine 阻塞。

危害

  • 耗尽内存和 CPU 资源。
  • 增加调度负担,降低程序性能。
  • 严重时导致程序崩溃。

解决办法

  • 给循环设退出条件,可用通道控制。
  • 合理处理通道收发,避免阻塞。
  • 确保锁正确加锁和解锁

 GMP调度原理

GMP 是 Go 语言运行时(runtime)实现的一种调度模型,用于高效地管理和调度 goroutine,其中 G 代表 goroutine,M 代表操作系统线程,P 代表处理器(逻辑处理器)。以下详细介绍 GMP 调度原理。

基本概念

  • G(Goroutine):Go 语言中轻量级的执行单元,由 Go 运行时管理,初始栈空间小且可动态伸缩,创建和销毁开销低。
  • M(Machine):对应一个操作系统线程,是执行计算的实际载体,负责执行 G。
  • P(Processor):处理器,它提供了执行 G 所需的上下文环境,每个 P 都有一个本地的运行队列,用于存放待执行的 G。

调度流程

1. 启动阶段
  • 程序启动时,Go 运行时会创建一定数量的 M 和 P,M 的数量通常由操作系统的线程数和 Go 程序的配置决定,P 的数量默认等于 CPU 的核心数,可以通过 GOMAXPROCS 环境变量或 runtime.GOMAXPROCS 函数进行调整。
2. 创建 Goroutine
  • 当使用 go 关键字创建一个新的 goroutine 时,这个新的 G 会被放入当前 P 的本地运行队列中。如果本地运行队列已满,G 会被放入全局运行队列中。
3. 调度执行
  • 本地队列调度:M 会从关联的 P 的本地运行队列中取出一个 G 并执行。当一个 M 执行完一个 G 后,会继续从本地队列中获取下一个 G 执行。
  • 全局队列调度:如果 P 的本地运行队列为空,M 会尝试从全局运行队列中获取 G。为了保证公平性,全局队列中的 G 会被均摊到各个 P 的本地队列中。
  • 偷取调度:如果全局运行队列也为空,M 会随机选择一个其他的 P,并从其本地队列中 “偷取” 一半的 G 到自己关联的 P 的本地队列中执行,这种机制保证了各个 P 的负载均衡。
4. 阻塞和唤醒
  • 阻塞:当一个 G 发生阻塞操作(如进行 I/O 操作、加锁等)时,M 会将当前 G 挂起,然后从本地队列或全局队列中选择另一个 G 继续执行。如果本地队列和全局队列都为空,M 会进入休眠状态。
  • 唤醒:当阻塞的 G 操作完成后,它会被唤醒,并被放入某个 P 的本地队列中等待再次执行。
5. 系统调用
  • 当 G 进行系统调用时,M 会和 P 分离,带着进行系统调用的 G 一起进入系统调用状态。如果此时还有其他可运行的 G 在 P 的本地队列中,会有新的 M 被调度来和这个 P 绑定,继续执行队列中的 G。当系统调用完成后,进行系统调用的 G 会尝试重新找一个空闲的 P 继续执行,如果没有空闲的 P,这个 G 会被放入全局队列中。

调度优势

  • 高效并发:通过轻量级的 goroutine 和 M:N 的调度模型,避免了频繁的内核态和用户态切换,减少了上下文切换的开销,提高了并发性能。
  • 负载均衡:偷取调度机制保证了各个 P 的负载均衡,充分利用了多核 CPU 的计算能力。
  • 灵活调度:能够根据 goroutine 的状态和系统资源的使用情况,动态地调整调度策略,提高了系统的整体性能和资源利用率

什么是通道,它的底层是什么

通道是什么

通道(channel)是 Go 语言用于 goroutine 间通信和同步的工具。就像一个传送带,一端的 goroutine 可以把数据放上去(发送数据),另一端的 goroutine 能从上面取走数据(接收数据),保障数据安全有序传递,避免数据竞争问题。

通道底层结构

通道底层是个结构体,关键部分及作用如下:

  • 缓冲区:类似传送带的承载区域,有大小限制。无缓冲通道就像没有承载区域的传送带,数据得立刻被取走;有缓冲通道则能暂存一定数量的数据。
  • 队列:有两个队列,一个存等待发送数据的 goroutine,另一个存等待接收数据的 goroutine。当通道条件不满足(如满了或空了),goroutine 会进入对应队列等待。
  • :好比传送带的安全开关,保证同一时间只有一个 goroutine 能操作通道,避免混乱。
  • 状态标记:记录通道是否关闭等状态信息

 生产者和消费者怎么关闭管道

基本规则

Go 里通常由生产者关闭管道,因为它知道何时不再产生数据,消费者能通过管道关闭信号得知数据传输结束。

不同场景关闭方式

  1. 单生产者单消费者:生产者完成数据发送后,用 close(chan) 关闭管道。消费者用 for...range 接收数据,管道关闭且数据取完,循环自动结束。例如面包师傅做完面包就关店门,顾客看到店门关且没面包就不再等。
  2. 需外部控制时:创建信号通道,生产者用 select 监听。收到关闭信号就关闭数据管道。如面包师傅收到停电通知就停止做面包并关店。
  3. 多生产者单 / 多消费者:用 sync.WaitGroup 跟踪生产者。所有生产者完成后,通过一个 goroutine 关闭管道。像多个送报小组都送完报,统一锁报箱

 如何检测通道关闭

在 Go 里检测通道关闭有三种常用办法:

  1. for...range 循环:用 for num := range ch 接收数据,通道关闭且数据收完,循环自动结束,很适合持续从通道取数据的场景。
  2. 多值接收:使用 v, ok := <-ch ,ok 为 true 表示正常收到数据,为 false 说明通道已关且无数据。
  3. select 语句:在 select 里结合多值接收,case v, ok := <-ch ,依据 ok 值判断通道是否关闭

 通道和锁的区别

 设计理念

  • 通道:以通信方式共享内存,通过传递数据协调并发。
  • 锁:共享内存来通信,用加解锁控制对共享资源的访问。

  使用场景

  • 通道:适合数据传递、多协程协作和同步场景。
  • 锁:用于保护共享资源,避免多协程同时读写引发冲突。

并发控制 

  • 通道:自动处理阻塞和同步,协程通过通道收发数据。
  • 锁:需手动控制加锁和解锁,易出现死锁问题。

代码复杂度 

  • 通道:代码简洁,逻辑清晰,提高可读性。
  • 锁:复杂场景下需精细管理,增加代码维护难度。

性能表现 

  • 通道:高并发时避免锁竞争,但有一定通信开销。
  • 锁:操作轻量,高并发竞争激烈时性能下降

数组和切片的区别

 定义和长度特性

  • 数组:定义时必须明确指定长度,且该长度固定,不可更改。数组长度属于其类型的一部分,不同长度的数组属于不同类型。
  • 切片:是对数组的抽象,长度可在运行时动态改变。它本身不存储数据,而是指向一个底层数组。

内存分配

  • 数组:定义时会分配连续的内存空间来存储所有元素,内存大小在编译时就已确定。作为函数参数传递时,会复制整个数组,可能造成较大内存开销。
  • 切片:是轻量级数据结构,由指向底层数组的指针、切片长度和容量构成。内存分配主要取决于底层数组。作为函数参数传递时,传递的是切片结构体本身,不复制底层数组,开销小。

长度和容量

  • 数组:只有长度概念,即元素数量,没有容量概念,因为长度固定。
  • 切片:有长度和容量两个属性。长度指当前元素数量,容量是底层数组从切片起始位置开始的最大元素数量。向切片追加元素,长度超容量时会自动扩容,通常重新分配更大底层数组并复制原元素。

使用灵活性

  • 数组:因长度固定,使用不够灵活,若要存储不同数量元素,可能需重新定义数组。
  • 切片:动态长度特性使其使用更灵活,可方便进行元素追加、删除和修改操作。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ5-死信队列

目录 死信的概念 死信的来源 死信实战 死信之TTl 死信之最大长度 死信之消息被拒 死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或直接到queue 里了&#xff0c;consumer 从 queue 取出消息进…

【项目初始化】

项目初始化 使用脚手架创建项目Vite创建项目推荐拓展 使用脚手架创建项目 Vite Vite 是一个现代的前端构建工具&#xff0c;它提供了极速的更新和开发体验&#xff0c;支持多种前端框架&#xff0c;如 Vue、React 等创建项目 pnpm create vuelatest推荐拓展

一文读懂 Faiss:开启高维向量高效检索的大门

一、引言 在大数据与人工智能蓬勃发展的当下&#xff0c;高维向量数据如潮水般涌现。无论是图像、音频、文本&#xff0c;还是生物信息领域&#xff0c;都离不开高维向量来精准刻画数据特征。然而&#xff0c;在海量的高维向量数据中进行快速、准确的相似性搜索&#xff0c;却…

基于Django的Boss直聘IT岗位可视化分析系统的设计与实现

【Django】基于Django的Boss直聘IT岗位可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言&#xff0c;利用Django这一高效、安全的W…

python 语音识别

目录 一、语音识别 二、代码实践 2.1 使用vosk三方库 2.2 使用SpeechRecognition 2.3 使用Whisper 一、语音识别 今天识别了别人做的这个app,觉得虽然是个日记app 但是用来学英语也挺好的,能进行语音识别,然后矫正语法,自己说的时候 ,实在不知道怎么说可以先乱说,然…

栈和队列特别篇:栈和队列的经典算法问题

图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 数据结构:队列篇 文章目录 系列文章目录前言一.有效的括号(leetcode 20)二.用队列实现栈(leetcode…

使用 OpenResty 构建高效的动态图片水印代理服务20250127

使用 OpenResty 构建高效的动态图片水印代理服务 在当今数字化的时代&#xff0c;图片在各种业务场景中广泛应用。为了保护版权、统一品牌形象&#xff0c;动态图片水印功能显得尤为重要。然而&#xff0c;直接在后端服务中集成水印功能&#xff0c;往往会带来代码复杂度增加、…

C++并行化编程

C并行化编程 C 简介 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xff0c;支持过程化编程、面向对象编程和泛型编程。 C 被认为是一种中级语言&#xff0c;它综合了高级语言和低级语言的特点。 C 是由 Bjarne Stroustrup 于 1979 年在新泽西州美…

Java开发vscode环境搭建

1 几个名词 JDK Java Development Kit JRE Java Runtion Environment JVM JDK 包括 Compiler,debugger,JRE等。JRE包括JVM和Runtime Library。 2 配置环境 2.1 安装JDK 类比 C/C的 g工具 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/ 根据自己使…

pytorch基于FastText实现词嵌入

FastText 是 Facebook AI Research 提出的 改进版 Word2Vec&#xff0c;可以&#xff1a; ✅ 利用 n-grams 处理未登录词 比 Word2Vec 更快、更准确 适用于中文等形态丰富的语言 完整的 PyTorch FastText 代码&#xff08;基于中文语料&#xff09;&#xff0c;包含&#xff1…

riscv xv6学习笔记

文章目录 前言util实验sleeputil实验pingpongutil实验primesxv6初始化代码分析syscall实验tracesyscall实验sysinfoxv6内存学习笔记pgtbl实验Print a page tablepgtbl实验A kernel page table per processxv6 trap学习trap实验Backtracetrap实验Alarmlazy实验Lazy allocationxv…

FFmpeg(7.1版本)编译:Ubuntu18.04交叉编译到ARM

一、本地编译与交叉编译 1.本地编译 ① 本地编译&#xff1a;指的是在目标系统上进行编译的过程 , 生成的可执行文件和函数库只能在目标系统中使用。 如 : 在 Ubuntu中&#xff0c;本地编译的可执行文件只能在Ubuntu 系统中执行 , 无法在 Windows / Mac / Android / iOS 系…

创新创业计划书|建筑垃圾资源化回收

目录 第1部分 公司概况........................................................................ 1 第2部分 产品/服务...................................................................... 3 第3部分 研究与开发.................................................…

如何利用天赋实现最大化的价值输出

这种文章&#xff0c;以我现在的实力很难写出来。所以需要引用一些视频。 上92高校容易吗 如果基于天赋努力&#xff0c;非常容易。 如果不是这样&#xff0c;非常非常难。 高考失败人生完蛋&#xff1f;复读考上交大&#xff0c;进入社会才发现学历只是一张纸&#xff0c;98…

LigerUI在MVC模式下的响应原则

LigerUI是基于jQuery的UI框架&#xff0c;故他也是遵守jQuery的开发模式&#xff0c;但是也具有其特色的侦听函数&#xff0c;那么当LigerUI作为View层的时候&#xff0c;他所发送后端的必然是表单的数据&#xff0c;在此我们以俩个div为例&#xff1a; {Layout "~/View…

【力扣】49.字母异位词分组

AC截图 题目 思路 由于互为字母异位词的两个字符串包含的字母相同&#xff0c;因此对两个字符串分别进行排序之后得到的字符串一定是相同的&#xff0c;故可以将排序之后的字符串作为哈希表的键。 可以遍历strs&#xff0c;将其中每一个str排序&#xff0c;然后用unodered_ma…

docker安装nacos2.2.4详解(含:nacos容器启动参数、环境变量、常见问题整理)

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull nacos:2.2.4 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜像到…

【图床配置】PicGO+Gitee方案

【图床配置】PicGOGitee方案 文章目录 【图床配置】PicGOGitee方案为啥要用图床图床是什么配置步骤下载安装PicGoPicGo配置创建Gitee仓库Typora中的设置 为啥要用图床 在Markdown中&#xff0c;图片默认是以路径的形式存在的&#xff0c;类似这样 可以看到这是本地路径&#x…

【C++】类与对象(下)

&#x1f984; 个人主页: 小米里的大麦-CSDN博客 &#x1f38f; 所属专栏: 小米里的大麦——C专栏_CSDN博客 &#x1f381; 代码托管: 小米里的大麦的Gitee仓库 ⚙️ 操作环境: Visual Studio 2022 文章目录 1. 再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit 关键…

SpringBoot笔记

1.创建 使用idea提供的脚手架创建springboot项目&#xff0c;选上需要的模块&#xff0c;会自动进行导包 打成jar包&#xff0c;之前直接用原生的maven打包的是一个瘦jar&#xff0c;不能直接跑&#xff0c;把服务器上部署的jar排除在外了&#xff0c;但是现在加上打包查件&am…