【Go面试】工作经验篇 (持续整合)

这里写目录标题

什么是逃逸分析

其核心目的是确定在程序执行过程中,对象的引用是否"逃逸"出了其创建的作用域

1.减少逃逸就可以把对象分配到栈上,减少垃圾回收的压力

2.没逃逸出线程就不用对这个对象做支持多线程的处理

3.如果创建后没有外部引用就会被视为死代码消除

逃逸的情况:

全局变量,传参,返回值,多线程,外部数据结构(全局数据结构或指针)

服务端怎么接受客户端上传的文件

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
	//创建gin框架的路由引擎
	
    r := gin.Default()

//定义一个处理post请求的路由,并尝试获取名为file的文件,如果出现错误就返回对应错误信息
	
    r.POST("/upload", func(c *gin.Context) {
        // 声明接收文件的变量
        file, err := c.FormFile("file")
        if err!= nil {
            c.String(http.StatusBadRequest, "接收文件出错: %v", err)
            return
        }

        // 保存文件
        err = c.SaveUploadedFile(file, "./"+file.Filename)
        if err!= nil {
            c.String(http.StatusInternalServerError, "保存文件出错: %v", err)
            return
        }

        c.String(http.StatusOK, "文件上传成功: %s", file.Filename)
    })

    // 启动服务
    r.Run(":8080")
}

说一下对gin框架的理解

gin是一个厉害的Go语言web框架

从路由上说利用Trie树算法快速匹配路由,

中间件上可以像链条穿起来,和工作流一样,内置Logger等中间件,

社区活跃,提供丰富解决思路和插件

基于httprouter构建,底层实现高效,高并发优秀,资源占用少

gin有哪些常用中间件

日志,跨域,权限

gin怎么用swagger写接口文档

1.引入所需包(gin-swagger和其他包)

2.根目录下swag init,生成配置文件

3.在go文件中用特定格式写路由,函数,参数,返回值等信息

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/swaggo/files"
    "github.com/swaggo/gin-swagger"
    _ "your-project-name/docs" // 这里导入生成的 docs 包,注意要替换为实际项目名
)

// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost:8080
// @BasePath /api/v1
func main() {
    r := gin.Default()

    // 路由组
    v1 := r.Group("/api/v1")
    {
        // @Summary 获取用户信息
        // @Description 根据用户 ID 获取用户信息
        // @Tags 用户管理
        // @Accept  json
        // @Produce  json
        // @Param   id     path    int     true        "用户 ID"
        // @Success 200 {object} User "成功获取用户信息"
        // @Failure 400 {object} gin.H "无效的请求参数"
        // @Failure 404 {object} gin.H "用户未找到"
        // @Router /users/{id} [get]
        v1.GET("/users/:id", func(c *gin.Context) {
            // 函数体
        })

        // @Summary 创建用户
        // @Description 创建一个新用户
        // @Tags 用户管理
        // @Accept  json
        // @Produce  json
        // @Param   user     body    User     true        "用户信息"
        // @Success 201 {object} User "成功创建用户"
        // @Failure 400 {object} gin.H "无效的用户信息"
        // @Router /users [post]
        v1.POST("/users", func(c *gin.Context) {
            // 函数体
        })
    }

    // 配置 Swagger UI 路由
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    r.Run(":8080")
}

// User 结构体,用于示例
type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

再用swag init 生成docs目录和文件

nginx一般是用来做什么

作为反向代理服务器,

1.可以把客户端的请求转发到后端的多个服务器上实现负载均衡,

2.可以直接提供静态资源

3.或者配置SSL证书实现HTTPS,加密传输

4.配置缓存,减少服务器负担

Traefik和nginx类似,但是traefik是一个反向代理和负载均衡器,为k8s环境设计.动态服务发现,自动更新路由规则

如果调用方法经常超时怎么办

1.超时重试

2.拉长超时时间

3.检查网络状态,带宽,打日志检查请求的服务有没接收到请求

4.缓存和负载均衡

gin中怎么和mysql通信

1.引入依赖

2.配置数据库连接

3.定义数据模型

4.编写增删改查操作sql

从mysql调数据到redis,如何同步

https://www.ppmy.cn/news/1564625.html?action=onClick

分为 一致性要求较高 允许延迟一致

1.一致性要求较高:使用共享锁和排他锁或者延时双删策略,确保缓存和数据库数据一致性,(对性能有影响)

2.允许延迟一致:使用消息队列,异步更新缓存,保证最终的一致性,(有延迟)

延时双删

场景:

  • 当有多个线程或进程可能同时操作数据时,为了避免缓存和数据库的数据不一致,延时双删可以发挥重要作用。
  • 例如,在一个电商系统中,当更新商品信息时,可能会出现以下情况:
    • 线程 A 更新商品信息到数据库,同时删除缓存。
    • 线程 B 此时读取商品信息,由于缓存已删除,它会从数据库读取旧信息并写入缓存。
    • 线程 A 后续的更新操作完成,但是线程 B 写入的旧信息仍在缓存中,导致数据不一致。

解决:

1.写数据库前删除缓存的数据,(确保后续操作不会读到旧缓存)

2.更新数据库

3.延时后第二次删除缓存(确保之前因为并发读取而写入的旧数据被清除)

延迟时间短可能无法清除旧数据

为了避免sleep的性能影响可以使用消息队列延迟删除

redis ,mysql都不存在用户请求的数据怎么办(缓存穿透)

就是缓存穿透

1.缓存空值

2.布隆过滤器

3.前置业务校验

4.黑名单限制特殊IP或用户

redis大Key问题

大Key问题就是redis的键值(key,value)对中,Key或Value很大.导致redis在处理这个数据时IO耗时很高或者费内存,再由于redis单线程导致redis会处于长时阻塞,甚至不可用.

检测 redis-cli --bigkeys 扫描所有的键识别大Key,大致检测大Key

解决

1.避免大量数据存在一个键上

2.数据拆分,把列表,哈希或者集合 中元素拆成多个子元素

3.数据压缩,或者缩减储存数据大小(优化数据结构)

你们小组有哪些人,都是怎么工作的

1.表达人数,和对应职位人数(5人,2后端,1前端,1测试,1产品)

2.个人负责哪部分,表达出个人的重要程度,以及自己职责

3.表达团结一致和融入小组迅速

4.可以反问HR贵公司组织架构是否类似,并且回复和自己之前的架构很像可以快速融入

最有成就感的事

待补充...

发展方向

待补充...

看重公司哪一点

待补充

业务和技术哪个重要

待补充

遇到过什么困难,怎么解决

待补充

反问内容

待补充

prompt书写有什么技巧

1.易读易知官方友善

2.指定角色,不同角色对事物认知不同

3.指定生成的结果格式(json)

4.重要要求的放在前面,末尾重复再次强调

5.减少幻觉(幻觉就是不能让他跳出角色设定,例如:作为一个AI我拒绝回答...)设置在没把握回答或者拒绝回答时,回复提问者固定格式的格式回答

6.可以动态设置多个标签枚举,让AI回答固定标签内容

你认为为什么prompt会有很多不同的模板,不同业务场景适合用不同的与大模型交互的方式吗

对大模型的认识以及自己的运用或者工作时的运用

使用大模型的时候大交互拆成小交互会对token优化多少

简单任务不会优化多少,复杂任务会优化一点,但是连贯性和网络,时间开销会更大

怎么样排查慢查询

1.最简单:慢查询日志. 设置超过多少秒认为慢查询 这个一般是运维在设置

2.找到问题sql 查慢查询原因: EXPLAIN 查询执行计划

查看是否命中索引,扫描行数

3.优化查询条件,使得命中索引,避免select * ,避免Where子句使用函数(可能导致索引失效)

4.加索引,或者分区分表

5.提升内存,磁盘或CPU

k8s了解嘛?

开源容器编排平台,用于自动化容器部署管理的,

主从架构:

主: 配置,控制,管理,调度

从:执行实际的任务,管理容器生命周期,管理网络代理,负载均衡,

主要单元:

pod:一个pod对应一个或多个容器,

service:服务 包含多个pod

场景:微服务部署,持续部署和集成(CI/CD) ,开发云原生应用

优势:高可用,弹性,资源合理管理

一个地方Post请求过多怎么处理(或者消息过多)

消息风暴

0.nginx负载均衡(post请求时)

1.消息队列缓冲,削峰填谷(如果实时性不高)

2.熔断和限流(如果数据不是很重要)

3.合并和压缩(如果重复消息较多)

4.分布式处理负载

5.创建协程异步处理

相关推荐
liuyunshengsir12 分钟前
Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能
java·spring boot·prometheus
路上阡陌21 分钟前
Java学习笔记(二十四)
java·笔记·学习
何中应31 分钟前
Spring Boot中选择性加载Bean的几种方式
java·spring boot·后端
苏苏大大33 分钟前
zookeeper
java·分布式·zookeeper·云原生
wclass-zhengge1 小时前
03垃圾回收篇(D3_垃圾收集器的选择及相关参数)
java·jvm
涛ing1 小时前
23. C语言 文件操作详解
java·linux·c语言·开发语言·c++·vscode·vim
5xidixi1 小时前
Java TCP协议(2)
java·tcp/ip
2013crazy1 小时前
Java 基于 SpringBoot+Vue 的校园兼职平台(附源码、部署、文档)
java·vue.js·spring boot·兼职平台·校园兼职·兼职发布平台
小高不明1 小时前
仿 RabbitMQ 的消息队列3(实战项目)
java·开发语言·spring·rabbitmq·mybatis
兩尛1 小时前
订单状态定时处理、来单提醒和客户催单(day10)
java·前端·数据库