golang笔试题
moboyou 2025-06-12 13:11 7 浏览
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := slice[2:5]
s2 := s1[2:6:7]
s2 = append(s2, 100)
s2 = append(s2, 200)
s1[2] = 20
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(slice)
}
答案:
[2 3 20]
[4 5 6 7 100 200]
[0 1 2 3 20 5 6 7 100 9]
题目2:
package main
func main() {
s := []int{1, 1, 1}
f(s)
fmt.Println(s)
}
func f(s []int) {
for i := range s {
s[i] += 1
}
}
答案:[2 2 2]
题目3:
package main
import "fmt"
func myAppend(s []int) []int {
s = append(s, 100)
return s
}
func myAppendPtr(s *[]int) {
*s = append(*s, 100)
return
}
func main() {
s := []int{1, 1, 1}
newS := myAppend(s)
fmt.Println(s)
fmt.Println(newS)
s = newS
myAppendPtr(&s)
fmt.Println(s)
}
结果:[1 1 1] [1 1 1 100] [1 1 1 100 100]
题目4:
func test() int {
x := 1
defer func() {
x = 2
}()
return x
}
func main() {
fmt.Println(test())
}
/*
return x 先计算 x 的值,即 1,但还未真正返回。
defer 执行,将 x 赋值为 2,但不会影响已计算的返回值。
最终返回 1。
*/
题目5:
func test() (x int) {
x = 1
defer func() {
x = 2
}()
return x
}
func main() {
fmt.Println(test())
}
/*
x 是命名返回值,return x 计算时
x=1,但未立即返回。
defer 执行,把 x 改为 2。
return 返回 x=2,最终返回值是 2。
*/
题目6:
func deferFunc() int {
fmt.Println("defer func called")
return 0
}
func returnFunc() int {
fmt.Println("return func called")
return 0
}
func returnAndDefer() int {
defer deferFunc()
return returnFunc()
}
func main() {
returnAndDefer()
}
/*
结果:return func called
defer func called
结论为:return之后的语句先执行,defer后的语句后执行*/
题目7:
func main() {
defer fmt.Println("defer 1")
defer fmt.Println("defer 2")
panic("发生 panic 了!") // 触发 panic
defer fmt.Println("defer 3") // 这行不会执行
}
/*
结果:
defer 2
defer 1
panic: 发生 panic 了!
*/
func main() {
defer_call()
fmt.Println("main 正常结束")
}
func defer_call() {
defer func() {
fmt.Println("defer: panic 之前1, 捕获异常")
if err := recover(); err != nil {
fmt.Println(err)
}
}()
defer func() { fmt.Println("defer: panic 之前2, 不捕获") }()
panic("异常内容") //触发defer出栈
defer func() { fmt.Println("defer: panic 之后, 永远执行不到") }()
}
/*
结果:
defer: panic 之前2, 不捕获
defer: panic 之前1, 捕获异常
异常内容
main 正常结束
*/
func main() {
defer fmt.Println("defer 1")
defer func() {
if r := recover(); r != nil {
fmt.Println("捕获 panic:", r)
}
}()
defer fmt.Println("defer 2")
panic("触发 panic")
defer fmt.Println("defer 3") // 不会执行
}
/*
结果:
defer 2
捕获 panic: 触发 panic
defer 1
*/
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
} else {
fmt.Println("fatal")
}
}()
defer func() {
panic("defer panic")
}()
panic("panic")
}
/*
结果:
defer panic
recover() 只能捕获最近的 panic,不会捕获被后续 panic 覆盖的 panic。
后进先出(LIFO)执行 defer 语句,所以 defer panic 发生后,原来的 panic("panic") 就被丢弃了。
如果 recover() 能捕获 panic,则程序不会崩溃。*/
题目8:
func function(index int, value int) int {
fmt.Println(index)
return index
}
func main() {
defer function(1, function(3, 0))
defer function(2, function(4, 0))
}
/*
结果:
3
4
2
1
这里面有两个defer, 所以defer一共会压栈两次,先进栈1,后进栈2。
那么在压栈function1的时候,需要连同函数地址、函数形参一同进栈,
那么为了得到function1的第二个参数的结果,所以就需要先执行function3将第二个参数算出,
那么function3就被第一个执行。同理压栈function2,就需要执行function4算出function2第二个参数的值。
然后函数结束,先出栈fuction2、再出栈function1.
*/
题目9:
package main
import "fmt"
func DeferFunc1(i int) (t int) {
t = i // t = 1
defer func() {
t += 3 // t = t + 3 = 1 + 3 = 4
}()
return t // 先计算返回值 t=1,然后执行 defer 修改 t=4
}
func DeferFunc2(i int) int {
t := i // t = 1 (局部变量)
defer func() {
t += 3 // 由于 t 不是命名返回值,对返回值无影响
}()
return t // 直接返回 t=1,defer 修改的是局部变量,不影响返回值
}
func DeferFunc3(i int) (t int) {
defer func() {
t += i // t = t + i = 2 + 1 = 3
}()
return 2 // 先计算返回值 t=2,再执行 defer 修改 t=3
}
func DeferFunc4() (t int) {
defer func(i int) {
fmt.Println(i) // 0 (因为 defer 传递的是 t 的拷贝)
fmt.Println(t) // 2 (defer 运行时 t 已被 return 修改)
}(t)
t = 1
return 2 // 先计算返回值 t=2,再执行 defer
}
func main() {
fmt.Println(DeferFunc1(1)) // 1 -> 4
fmt.Println(DeferFunc2(1)) // 1
fmt.Println(DeferFunc3(1)) // 3
DeferFunc4() // 0, 2
}
/*
结果:
4
1
3
0
2
*/
题目10:
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func main() {
//定义map
m := make(map[string]*student)
//定义student数组
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
//将数组依次添加到map中
for _, stu := range stus {
m[stu.Name] = &stu
}
//打印map
for k,v := range m {
fmt.Println(k ,"=>", v.Name)
}
}
/*
结果:
遍历结果出现错误,输出结果为
zhou => wang
li => wang
wang => wang
map 中的 3 个 key 均指向数组中最后一个结构体。
*/
题目11:
func main() {
s := make(map[string]int)
delete(s, "h")
fmt.Println(s["h"])
}
A. runtime panic
B. 0
C. compilation error
/*
删除 map 不存在的键值对时,不会报错,相当于没有任何作用;
获取不存在的减值对时,返回值类型对应的零值,所以返回 0。
*/
题目12:
func main() {
i := -5
j := +5
fmt.Printf("%+d %+d", i, j)
}
A. -5 +5
B. +5 +5
C. 0 0
/*
A,%d表示输出十进制数字,+表示输出数值的符号。
*/
题目13:
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowB()
}
/*
teacher showB。
*/
题目14:
定义一个包内全局字符串变量,下面语法正确的是(多选):
A. var str string
B. str := ""
C. str = ""
D. var str = ""
/*
AD。
B 只支持局部变量声明;C 是赋值,str 必须在这之前已经声明。
*/
题目15:
func hello(i int) {
fmt.Println(i)
}
func main() {
i := 5
defer hello(i)
i = i + 10
}
/*
5。即使 hello 函数被延迟执行,它所获取的 i 参数的值会在 defer 语句被执行时已经确定
*/
题目16:
func incr(p *int) int {
*p++
return *p
}
func main() {
p :=1
incr(&p)
fmt.Println(p)
}
A. 1
B. 2
C. 3
/*
B。指针,incr() 函数里的 p 是 *int 类型的指针,指向的是 main() 函数的变量 p 的地址。
第 2 行代码是将该地址的值执行一个自增操作,incr() 返回自增后的结果。
*/
题目17:
对add()函数调用正确的是?
func add(args ...int) int {
sum := 0
for _, arg := range args {
sum += arg
}
return sum
}
A. add(1, 2)
B. add(1, 3, 7)
C. add([]int{1, 2})
D. add([]int{1, 3, 7}...)
/*
ABD。可变函数,因为它要求传递若干 int,A、B 显然正确;
C 是数组或切片,不对;D 把切片展开,其实就是若干 int,也对
*/
题目18:
func main() {
ch1 := make(chan int)
go fmt.Println(<-ch1)
ch1 <- 5
time.Sleep(1 * time.Second)
}
A:5、
B:不能编译;
C:运行时死锁
/*
C。go 语句后面的函数调用,其参数会先求值,这和普通的函数调用求值一样。go fmt.Println(<-ch1) 语句中的 <-ch1 是在 main goroutine 中求值的。这相当于一个无缓冲的 chan,发送和接收操作都在一个 goroutine 中(main goroutine)进行,因此造成死锁。
defer 语句也要注意。比如下面的做法是不对的:defer recover()
而应该使用这样的方式:
defer func() {
recover()
}()
*/
题目19:
func main() {
ch1 := make(chan int)
go func(){
fmt.Println(<-ch1)
}()
ch1 <- 5
time.Sleep(1 * time.Second)
}
A:5、
B:不能编译;
C:运行时死锁
/*
A。当 ch1 <- 5 执行时,主 goroutine 会阻塞在这一行,
直到另一个 goroutine 开始执行并准备好接收数据为止。
因为在这个例子中,接收操作是由匿名 goroutine 执行的,
所以发送和接收操作是在不同的 goroutine 中执行的,不会发生死锁
*/
题目20:
func main() {
// 创建一个 map
m := map[string]int{"a": 1, "b": 2, "c": 3}
// 保存要删除的键
keysToDelete := []string{}
// 遍历 map
for key, value := range m {
fmt.Println(key, value)
// 满足某个条件时,保存要删除的键
if value == 2 {
keysToDelete = append(keysToDelete, key)
}
}
// 在遍历完成后删除元素
for _, key := range keysToDelete {
delete(m, key)
}
/*
A 21
B 22
C 23
counter is 3
或
B 22
C 23
counter is 2
取决于 map 的遍历顺序。
*/
题目21:
关于switch语句,下面说法正确的有?
A. 条件表达式必须为常量或者整数;
B. 单个case中,可以出现多个结果选项;
C. 需要用break来明确退出一个case;
D. 只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case;
/*
参考答案及解析:BD。
switch 的条件表达式可以是任意类型(不限于常量或整数)
switch x {
case 1, 2, 3: // 匹配 1、2 或 3
fmt.Println("x is 1, 2, or 3")
case 4, 5:
fmt.Println("x is 4 or 5")
}
Go 的 switch 默认自动 break,不需要手动写 break。
如果想继续执行下一个 case,必须显式使用 fallthrough:
switch x {
case 1:
fmt.Println("1") // 默认 break,不会进入 case 2
case 2:
fmt.Println("2")
}
switch x {
case 1:
fmt.Println("1")
fallthrough // 强制进入 case 2
case 2:
fmt.Println("2") // 会执行
default:
fmt.Println("default")
}
*/
题目22:
func main() {
defer_call()
}
func defer_call() {
defer func() { fmt.Println("打印前") }()
defer func() { fmt.Println("打印中") }()
panic("触发异常")
defer func() { fmt.Println("打印后") }()
}
/*
打印中
打印前
panic: 触发异常
*/
题目23:
func main() {
var i interface{}
if i == nil {
fmt.Println("nil")
return
}
fmt.Println("not nil")
}
A. nil B. not nil C. compilation error
/*
B. not nil
*/
题目24:
func main() {
var b *int = nil
var i interface{} = b
if i == (*int)(nil){
fmt.Println("nil")
return
}
fmt.Println("not nil")
}
A. nil B. not nil C. compilation error
/*
A. nil
*/
题目25:
// 1.
func main() {
s := make([]int, 5)
s = append(s, 1, 2, 3)
fmt.Println(s)
}
// 2.
func main() {
s := make([]int,0)
s = append(s,1,2,3,4)
fmt.Println(s)
}
/*
[0 0 0 0 0 1 2 3]
[1 2 3 4]
*/
题目26:
通过指针变量 p 访问其成员变量 name,有哪几种方式?
A.p.name
B.(&p).name
C.(*p).name
D.p->name
/*
AC。& 取址运算符,* 指针解引用
*/
题目27:
下面这段代码能否编译通过?如果可以,输出什么?
const (
x = iota
_
y
z = "zz"
k
p = iota
)
func main() {
fmt.Println(x,y,z,k,p)
}
/*
0 2 zz zz 5
_: 是一个空白标识符,用于占位,它会使 iota 增加,但不会创建一个命名常量。
k: 没有显式赋值,因此会重复上一个非空白标识符的值,即 "zz"
p: 被赋值为当前 iota 的值。由于 iota 在上一行定义时未被使用(显式赋值中断了 iota 的递增),
所以 iota 会继续递增
*/
题目28:
下面这段代码能否编译通过?如果可以,输出什么?
func GetValue() int {
return 1
}
func main() {
i := GetValue()
switch i.(type) {
case int:
println("int")
case string:
println("string")
case interface{}:
println("interface")
default:
println("unknown")
}
}
/*
编译错误,正确写法如下
func GetValue() interface{} {
return 1
}
func main() {
i := GetValue()
switch v := i.(type) {
case int:
println("int")
case string:
println("string")
case interface{}:
println("interface")
default:
println("unknown")
}
}
*/
题目29:
type person struct {
name string
}
func main() {
var m map[person]int
p := person{"mike"}
fmt.Println(m[p])
}
A.0
B.1
C.Compilation error
/*
A。打印一个 map 中不存在的值时,返回元素类型的零值。
这个例子中,m 的类型是 map[person]int,因为 m 中不存在 p,所以打印 int 类型的零值,即 0。
*/
题目30:
func main() {
a := 5
b := 8.1
fmt.Println(a + b)
}
A.13.1
B.13
C.compilation error
/*
C。a 的类型是 int,b 的类型是 float,两个不同类型的数值不能相加,编译报错
*/
题目31:
func main() {
a := [5]int{1, 2, 3, 4, 5}
t := a[3:4:4]
fmt.Println(t[0])
}
A.3
B.4
C.compilation error
/*
B。[i,j,k],长度:j-i,容量:k-i。
*/
题目32:
func main() {
a := [2]int{5, 6}
b := [3]int{5, 6}
if a == b {
fmt.Println("equal")
} else {
fmt.Println("not equal")
}
}
A. compilation error
B. equal
C. not equal
/*
A。Go 中的数组是值类型,可比较,另外一方面,数组的长度也是数组类型的组成部分,
所以 a 和 b 是不同的类型,是不能比较的,所以编译错误。
*/
题目33:
关于 cap() 函数的适用类型,下面说法正确的是()
A. array
B. slice
C. map
D. channel
/*
ABD
len() 和 cap() 的区别:
len() 适用于 array、slice、map、channel,返回当前元素数量。
cap() 适用于 array、slice、channel,返回底层存储容量。
对 map 使用 cap() 会直接导致编译错误。
*/
题目34:
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowA()
}
/*
showA showB
结构体嵌套。Teacher 没有自己 ShowA(),所以调用内部类型 People 的同名方法,
需要注意的是第 5 行代码调用的是 People 自己的 ShowB 方法。
*/
题目35:
下面代码下划线处可以填入哪个选项?
func main() {
var s1 []int
var s2 = []int{}
if __ == nil {
fmt.Println("yes nil")
}else{
fmt.Println("no nil")
}
}
A. s1
B. s2
C. s1、s2 都可以
/*
A
s1 被声明为一个切片类型,但没有被初始化。在这种情况下,s1 的默认值是 nil。
s2 被声明为一个空的切片。虽然 s2 是空的,但它已经被初始化,不是 nil。
一个空切片的长度和容量为零,但它不等于 nil。
*/
题目36:
func main() {
i := 65
fmt.Println(string(i))
}
A. A
B. 65
C. compilation error
/*
A。UTF-8 编码中,十进制数字 65 对应的符号是 A。
*/
题目37:
func main() {
var i interface{}
if i == nil {
fmt.Println("nil")
return
}
fmt.Println("not nil")
}
A. nil
B. not nil
C. compilation error
/*
A。当且仅当接口的动态值和动态类型都为 nil 时,接口类型值才为 nil。
*/
题目38:
const (
a = iota
b = iota
)
const (
name = "name"
c = iota
d = iota
)
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
/*
参考答案及解析:0 1 1 2。
知识点:iota 的用法。
iota 是 golang 语言的常量计数器,只能在常量的表达式中使用。
iota 在 const 关键字出现时将被重置为0,const中每新增一行常量声明将使 iota 计数一次。
*/
题目39:
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
}
A. 4
B. compilation error
/*
参考答案及解析:B,编译报错 cannot assign to struct field m["foo"].x in map。
错误原因:对于类似 X = Y的赋值操作,必须知道 X 的地址,才能够将 Y 的值赋给 X,
但 go 中的 map 的 value 本身是不可寻址的。
有两个解决办法:
a.使用临时变量
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
tmp := m["foo"]
tmp.x = 4
m["foo"] = tmp
fmt.Println(m["foo"].x)
}
b.修改数据结构
type Math struct {
x, y int
}
var m = map[string]*Math{
"foo": &Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
fmt.Printf("%#v", m["foo"]) // %#v 格式化输出详细信息
}
*/
题目40:
var p *int
func foo() (*int, error) {
var i int = 5
return &i, nil
}
func bar() {
//use p
fmt.Println(*p)
}
func main() {
p, err := foo()
if err != nil {
fmt.Println(err)
return
}
bar()
fmt.Println(*p)
}
A. 5 5
B. runtime error
/*
参考答案及解析:B。知识点:变量作用域。问题出在操作符:=,对于使用:=定义的变量,
如果新变量与同名已定义的变量不在同一个作用域中,那么 Go 会新定义这个变量。
对于本例来说,main() 函数里的 p 是新定义的变量,会遮住全局变量 p,导致执行到bar()时程序,
全局变量 p 依然还是 nil,程序随即 Crash。
func main() {
var err error
p, err = foo() // 使用赋值(=)而不是短声明(:=)
if err != nil {
fmt.Println(err)
return
}
bar() // 现在全局 p 有效,输出 5
fmt.Println(*p) // 输出 5
}
*/
题目41:
A、B、C、D 哪些选项有语法错误?
type S struct {
}
func f(x interface{}) {
}
func g(x *interface{}) {
}
func main() {
s := S{}
p := &s
f(s) //A
g(s) //B
f(p) //C
g(p) //D
}
/*
语法错误的选项:B 和 D
*interface{} 是一种特殊的指针类型,不能直接从其他类型的值或指针隐式转换。
var i interface{} = s
g(&i)
var i interface{} = p
g(&i)
*/
题目42:
下面 A、B 两处应该填入什么代码,才能确保顺利打印出结果?
type S struct {
m string
}
func f() *S {
return __ //A
}
func main() {
p := __ //B
fmt.Println(p.m) //print "foo"
}
/*
参考答案及解析:
A. &S{"foo"}
B. *f() 或者 f()
f() 函数返回参数是指针类型,所以可以用 & 取结构体的指针;B 处,
如果填 *f(),则 p 是 S 类型;如果填 f(),则 p 是 *S 类型,
不过都可以使用 p.m 取得结构体的成员
*/
题目43:
实现使用字符串函数名,调用函数。
思路:采用反射的Call方法实现。
package main
import (
"fmt"
"reflect"
)
type Animal struct{
}
func (a *Animal) Eat(){
fmt.Println("Eat")
}
func main(){
a := Animal{}
reflect.ValueOf(&a).MethodByName("Eat").Call([]reflect.Value{})
}
题目44:
有三个函数,分别打印"cat", "fish","dog"要求每一个函数都用一个goroutine,按照顺序打印100次。
package main
import (
"fmt"
"time"
)
var dog = make(chan struct{})
var cat = make(chan struct{})
var fish = make(chan struct{})
func Dog() {
<-fish
fmt.Println("dog")
dog <- struct{}{}
}
func Cat() {
<-dog
fmt.Println("cat")
cat <- struct{}{}
}
func Fish() {
<-cat
fmt.Println("fish")
fish <- struct{}{}
}
func main() {
for i := 0; i < 100; i++ {
go Dog()
go Cat()
go Fish()
}
fish <- struct{}{}
time.Sleep(10 * time.Second)
}
题目45:
两个协程交替打印10个字母和数字
思路:采用channel来协调goroutine之间顺序。
package main
import (
"fmt"
"time"
)
var word = make(chan struct{}, 1)
var num = make(chan struct{}, 1)
func printNums() {
for i := 0; i < 10; i++ {
<-word
fmt.Println(1)
num <- struct{}{}
}
}
func printWords() {
for i := 0; i < 10; i++ {
<-num
fmt.Println("a")
word <- struct{}{}
}
}
func main() {
num <- struct{}{}
go printNums()
go printWords()
time.Sleep(time.Second * 1)
}
题目46:
启动 2个groutine 2秒后取消, 第一个协程1秒执行完,第二个协程3秒执行完。
思路:采用ctx, _ := context.WithTimeout(context.Background(), time.Second*2)
实现2s取消。协程执行完后通过channel通知,是否超时。
package main
import (
"context"
"fmt"
"time"
)
func f1(in chan struct{}) {
time.Sleep(1 * time.Second)
in <- struct{}{}
}
func f2(in chan struct{}) {
time.Sleep(3 * time.Second)
in <- struct{}{}
}
func main() {
ch1 := make(chan struct{})
ch2 := make(chan struct{})
ctx, _ := context.WithTimeout(context.Background(), 2*time.Second)
go func() {
go f1(ch1)
select {
case <-ctx.Done():
fmt.Println("f1 timeout")
break
case <-ch1:
fmt.Println("f1 done")
}
}()
go func() {
go f2(ch2)
select {
case <-ctx.Done():
fmt.Println("f2 timeout")
break
case <-ch2:
fmt.Println("f2 done")
}
}()
time.Sleep(time.Second * 5)
}
相关推荐
- linux下C++ socket网络编程——即时通信系统(含源码)
-
一:项目内容本项目使用C++实现一个具备服务器端和客户端即时通信且具有私聊功能的聊天室。目的是学习C++网络开发的基本概念,同时也可以熟悉下Linux下的C++程序编译和简单MakeFile编写二:需...
- Workerman的使用(workerman教程)
-
Workerman是什么?Workerman是一款纯PHP开发的开源高性能的PHPsocket服务框架。Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的socket服...
- 百万人在线的直播间实时聊天消息分发技术实践
-
本文由融云技术团队原创分享,原题“聊天室海量消息分发之消息丢弃策略”,内容有修订。1、引言随着直播类应用的普及,尤其直播带货概念的风靡,大用户量的直播间场景已然常态化。大用户量直播间中的实时互动是非常...
- 省钱兄JAVA 直播源码开发(省钱快报源码)
-
在现代社会,直播已经成为一种流行的社交和商业形式。越来越多的人通过直播平台展示自己的才艺、分享生活、进行教学,甚至进行产品销售。随着直播行业的发展,许多人希望能够参与到这一领域中,尤其是开发自己的直播...
- 编程革命彻底爆发,OpenAI最强智能体上线ChatGPT
-
OpenAI最强AI编程智能体真的来了!Codex震撼上线,由o3优化版codex-1加持,多任务并行,半小时干完数天软件工程任务。从今天起,AI编程正式开启新时代!刚刚,GregBrockman...
- Springboot下的WebSocket开发(springboot websock)
-
今天遇到一个需求,需要对接第三方扫码跳转。一种方案是前端页面轮询后端服务,但是这种空轮询会虚耗资源,实时性比较差而且也不优雅。所以决定使用另一种方案,websocket。以前就知道websocket,...
- epoll聊天室的实现(epoll使用详解(精髓))
-
1.服务端a.支持多个用户接入,实现聊天室的基本功能b.使用epoll机制实现并发,增加效率2.客户端a.支持用户输入聊天消息b.显示其他用户输入的信息c.使用fork创建两个进程子进程有...
- 自建娱乐聊天室—一起听歌吧!属于自己的交友聊天房
-
前言该项目算是老项目了,但最近粉丝群里的友友都让我写一下,那就写一下吧。项目类似于现在各大直播平台的聊天室,但又不像。它更加的自由开放,没有平台的礼物以及各种限制,如果你有来自五湖四海的朋友,想一起聊...
- 定时任务框架选型Quartz/Xxl-Job(定时任务调度框架)
-
以前公司平台中集成了定时任务功能,但平台内部实现比较简单,使用方式有些受限,比如说无法跟踪定时任务执行状态,无法自动解决集群状态下的任务争抢问题,因此考虑升级一下任务实现方式,搜集一番后,Quartz...
- 【推荐】一款开源免费的 ChatGPT 聊天管理系统,支持PC、H5等多端
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍GPTCMS是一款开源且免费(基于GPL-3.0协议开源)的ChatGPT聊天管理系统,它基于先进的GPT...
- 现在页面实时聊天都使用Websocket技术实现吗?
-
是的,现在实现页面实时聊天主要使用Websocket,在此之前,还有其它的一些技术,比如:AJAX轮询、FlashXMLSocket等。其中Ajax轮询就是定时向服务器发起请求,例如1秒钟请求一...
- 一对一源码开发,九大方面完善基础架构
-
以往的直播大多数都是一对多进行直播社交,弊端在于不能满足到每个用户的需求,会降低软件的体验感。伴随着用户需求量的增加,一对一直播源码开始出现。一个完整的一对一直播流程即主播发起直播→观看进入房间观看→...
- 揭秘PHP8.4的新特性,帮助您提高开发效率
-
PHP8.4作为一次重大版本更新,引入了多项提升开发效率和代码性能的新特性,以下是核心功能的总结:一、属性钩子(PropertyHooks)-功能描述:允许通过语法直接为类的属性定义get...
- 【验证码逆向专栏】某验三代、四代一键通过模式逆向分析
-
声明本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!本文章未经许可禁止转载,禁止任...
- 如何申请SourceForge免费PHP空间(国内免费php空间申请)
-
SF.net,即Sourceforge.net,是国外一个开源软件分享及管理平台,也是全球最大开源软件开发平台和仓库。Sourceforge.net为广大的开发者提供了软件发布平台,同时又提供了个人免...
- 一周热门
- 最近发表
-
- linux下C++ socket网络编程——即时通信系统(含源码)
- Workerman的使用(workerman教程)
- 百万人在线的直播间实时聊天消息分发技术实践
- 省钱兄JAVA 直播源码开发(省钱快报源码)
- 编程革命彻底爆发,OpenAI最强智能体上线ChatGPT
- Springboot下的WebSocket开发(springboot websock)
- epoll聊天室的实现(epoll使用详解(精髓))
- 自建娱乐聊天室—一起听歌吧!属于自己的交友聊天房
- 定时任务框架选型Quartz/Xxl-Job(定时任务调度框架)
- 【推荐】一款开源免费的 ChatGPT 聊天管理系统,支持PC、H5等多端
- 标签列表
-
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- oracle两个表 (20)
- oracle 数据库 字符集 (20)
- matlab化简多项式 (20)
- 多线程的创建方式 (29)
- 多线程 python (30)
- java多线程并发处理 (32)
- 宏程序代码一览表 (35)
- c++需要学多久 (25)
- css class选择器用法 (25)
- css样式引入 (30)
- css教程文字移动 (33)
- php简单源码 (36)
- php个人中心源码 (25)
- php小说爬取源码 (23)
- 云电脑app源码 (22)
- html画折线图 (24)
- docker好玩的应用 (28)
- linux有没有pe工具 (34)
- mysql数据库源码 (21)
- php开源万能表单系统源码 (21)