急招能在巴黎现场办公的Golang后端自由职业开发者

急招能在巴黎现场办公的Golang后端自由职业开发者 以下是法语职位描述:

Golang 后端自由职业开发者

任务

  • 与团队合作构建可扩展且稳健的解决方案
  • 与团队合作负责产品编码
  • 保持高质量的代码,并遵循团队的指导方针和约定,解决出现的挑战
  • 借助单元/集成测试,确保功能在功能和技术的合规性上达到高水平
  • 改善用户体验
  • 确保遵循 CI 流程,并关注应用程序整体的可用性、稳定性和性能水平。

必备技能

硬技能:

  • 拥有扎实的 Golang 后端经验(至少 3 年)(Postgres、Rabbitmq 更佳)
  • 有前端(Next.js)经验 ==> 优先考虑
  • 敏捷方法论
  • 对测试、持续集成和自动化有敏感性
  • 有多模态嵌入模型和大规模 AI 模型部署经验者优先
  • 必须会英语

更多关于急招能在巴黎现场办公的Golang后端自由职业开发者的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

您好,

希望您一切安好。我写此信是为了表达我对该空缺职位的兴趣。

私信已发送,请查收。

此致, Seth R

更多关于急招能在巴黎现场办公的Golang后端自由职业开发者的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好

希望你一切顺利

我可以帮助你满足相关需求,但以远程方式提供协助。 我们在该领域拥有超过5年的经验。 让我们建立联系,以便我能向你展示我们之前的工作成果。

谢谢

以下是一个符合该职位描述的Golang后端示例代码,展示了如何构建一个使用PostgreSQL、RabbitMQ和集成测试的可扩展服务:

// main.go - 可扩展的Golang后端服务示例
package main

import (
	"context"
	"database/sql"
	"encoding/json"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	_ "github.com/lib/pq"
	amqp "github.com/rabbitmq/amqp091-go"
)

// 数据库模型
type User struct {
	ID        int       `json:"id"`
	Name      string    `json:"name"`
	Email     string    `json:"email"`
	CreatedAt time.Time `json:"created_at"`
}

// 数据库层
type UserRepository struct {
	db *sql.DB
}

func NewUserRepository(db *sql.DB) *UserRepository {
	return &UserRepository{db: db}
}

func (r *UserRepository) CreateUser(ctx context.Context, user *User) error {
	query := `INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id, created_at`
	return r.db.QueryRowContext(ctx, query, user.Name, user.Email).Scan(&user.ID, &user.CreatedAt)
}

func (r *UserRepository) GetUser(ctx context.Context, id int) (*User, error) {
	user := &User{}
	query := `SELECT id, name, email, created_at FROM users WHERE id = $1`
	err := r.db.QueryRowContext(ctx, query, id).Scan(&user.ID, &user.Name, &user.Email, &user.CreatedAt)
	return user, err
}

// 消息队列服务
type MessageQueue struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

func NewMessageQueue(amqpURL string) (*MessageQueue, error) {
	conn, err := amqp.Dial(amqpURL)
	if err != nil {
		return nil, err
	}

	ch, err := conn.Channel()
	if err != nil {
		return nil, err
	}

	return &MessageQueue{conn: conn, channel: ch}, nil
}

func (mq *MessageQueue) PublishUserEvent(ctx context.Context, user *User) error {
	body, err := json.Marshal(user)
	if err != nil {
		return err
	}

	return mq.channel.PublishWithContext(ctx,
		"user_events",
		"",
		false,
		false,
		amqp.Publishing{
			ContentType: "application/json",
			Body:        body,
		})
}

// HTTP处理器
type UserHandler struct {
	repo *UserRepository
	mq   *MessageQueue
}

func NewUserHandler(repo *UserRepository, mq *MessageQueue) *UserHandler {
	return &UserHandler{repo: repo, mq: mq}
}

func (h *UserHandler) CreateUser(c *gin.Context) {
	var user User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	ctx := c.Request.Context()
	
	// 数据库操作
	if err := h.repo.CreateUser(ctx, &user); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 发布消息到RabbitMQ
	if err := h.mq.PublishUserEvent(ctx, &user); err != nil {
		log.Printf("Failed to publish event: %v", err)
	}

	c.JSON(http.StatusCreated, user)
}

func (h *UserHandler) GetUser(c *gin.Context) {
	id := c.Param("id")
	
	ctx := c.Request.Context()
	user, err := h.repo.GetUser(ctx, id)
	if err != nil {
		if err == sql.ErrNoRows {
			c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, user)
}

// 健康检查端点
func HealthCheck(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status": "healthy",
		"timestamp": time.Now().Unix(),
	})
}

// 主函数
func main() {
	// 初始化数据库连接
	db, err := sql.Open("postgres", "host=localhost port=5432 user=postgres password=secret dbname=mydb sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 初始化RabbitMQ连接
	mq, err := NewMessageQueue("amqp://guest:guest@localhost:5672/")
	if err != nil {
		log.Fatal(err)
	}
	defer mq.conn.Close()

	// 初始化仓库和处理器
	userRepo := NewUserRepository(db)
	userHandler := NewUserHandler(userRepo, mq)

	// 设置Gin路由
	router := gin.Default()
	
	// API路由
	api := router.Group("/api/v1")
	{
		api.POST("/users", userHandler.CreateUser)
		api.GET("/users/:id", userHandler.GetUser)
		api.GET("/health", HealthCheck)
	}

	// 启动服务器
	log.Println("Server starting on :8080")
	if err := router.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}
// user_repository_test.go - 集成测试示例
package main

import (
	"context"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/stretchr/testify/assert"
)

func TestUserRepository_CreateUser(t *testing.T) {
	db, mock, err := sqlmock.New()
	assert.NoError(t, err)
	defer db.Close()

	repo := NewUserRepository(db)
	
	user := &User{
		Name:  "John Doe",
		Email: "john@example.com",
	}

	mock.ExpectQuery(`INSERT INTO users`).
		WithArgs(user.Name, user.Email).
		WillReturnRows(sqlmock.NewRows([]string{"id", "created_at"}).
			AddRow(1, time.Now()))

	ctx := context.Background()
	err = repo.CreateUser(ctx, user)
	
	assert.NoError(t, err)
	assert.Equal(t, 1, user.ID)
	assert.NoError(t, mock.ExpectationsWereMet())
}

func TestUserRepository_GetUser(t *testing.T) {
	db, mock, err := sqlmock.New()
	assert.NoError(t, err)
	defer db.Close()

	repo := NewUserRepository(db)
	
	expectedTime := time.Now()
	mock.ExpectQuery(`SELECT id, name, email, created_at FROM users WHERE id = \$1`).
		WithArgs(1).
		WillReturnRows(sqlmock.NewRows([]string{"id", "name", "email", "created_at"}).
			AddRow(1, "John Doe", "john@example.com", expectedTime))

	ctx := context.Background()
	user, err := repo.GetUser(ctx, 1)
	
	assert.NoError(t, err)
	assert.Equal(t, 1, user.ID)
	assert.Equal(t, "John Doe", user.Name)
	assert.Equal(t, "john@example.com", user.Email)
	assert.Equal(t, expectedTime, user.CreatedAt)
	assert.NoError(t, mock.ExpectationsWereMet())
}
# docker-compose.yml - 本地开发环境配置
version: '3.8'
services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: secret
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  rabbitmq:
    image: rabbitmq:3-management-alpine
    ports:
      - "5672:5672"
      - "15672:15672"
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest

  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: "postgres://postgres:secret@postgres:5432/mydb?sslmode=disable"
      RABBITMQ_URL: "amqp://guest:guest@rabbitmq:5672/"
    depends_on:
      - postgres
      - rabbitmq

volumes:
  postgres_data:
-- migrations/001_create_users.sql - 数据库迁移
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);

这个示例展示了符合职位要求的Golang后端开发能力:

  1. 使用PostgreSQL进行数据持久化
  2. 集成RabbitMQ进行消息队列处理
  3. 遵循RESTful API设计
  4. 包含单元测试和集成测试
  5. 使用Docker Compose进行容器化部署
  6. 实现了健康检查端点
  7. 遵循清晰的代码结构和分层架构
回到顶部