Redbrain招聘高级Golang软件工程师(远程/伯明翰)

Redbrain招聘高级Golang软件工程师(远程/伯明翰) 薪资 每年 60,000 至 80,000 英镑 公司网站 https://redbrain.com

职位描述

我们正在寻找一位希望做出非凡成就的全栈开发人员/软件工程师。我们以推动工程、技术和客户体验的边界为荣。

您需要对卓越的编码充满热情,具备规划和处理海量数据的能力,以加入我们不断壮大的现有开发团队!

总而言之,我们每天处理超过 40 亿个产品,产生的数据量、深度和复杂性鲜有匹敌。通过获得的洞察,我们使用尖端技术构建可扩展、高性能的产品,推动在线零售增长。

Redbrain,欧洲最大的 Google Shopping 合作伙伴。我们在英国和整个欧洲表现出色,仅去年一年就为超过 5,000 家零售商带来了超过 5 亿英镑的增量销售额。

这是一个加入才华横溢的问题解决者团队的机会,致力于解决复杂问题并找到简单的解决方案。通过您的工作,您将直接影响世界领先零售商如何增长其在线销售额。

我们相信工程师是为其他工程师编写代码,而不仅仅是为机器,因此我们推崇简洁而智能的代码!

如果您渴望支持我们构建世界上最好的增量销售引擎的使命,请看看我们提供的条件。

此职位与我们的伯明翰办公室相关联,我们采用远程优先的工作方式,每两周有一个办公室工作日。

以下是我们使用的一些工具和方法论:

基础设施: GCP, Kubernetes, 微服务

平台: Elasticsearch, PostgresDB, Vault, PubSub, GCS, Spanner

工具: GRPC, Protobuf, Terraform, Gitlab, Kibana, Golang

工作方式: 敏捷, Scrum, 结对编程

职位:

作为高级软件工程师,您将成为我们其中一个工程团队的一员,通过遵循最佳实践架构和工程原则、操作框架以及新的和改进的技术应用和解决方案,创造出优秀的产品。

您将负责使用 Golang 和 Kubernetes 等技术设计和开发大规模高性能服务。

您将是一位出色的团队成员,向团队其他成员提供并寻求有用的反馈,并寻找机会在更广泛的业务范围内提供帮助。

软件工程师将能够管理自己的工作量,良好地估算任务,并在出现问题时确定优先级。

我们正在寻找一位深切关注构建完美产品功能,同时挑战我们在软件架构方面思维的人。

您将不断努力改进团队的工作方式,作为工程团队的一名进步成员做出贡献。

一位热衷于构建高性能和可靠系统,并且总是乐于接受挑战的人。

我们正在寻找具备以下条件的工程师:

  • 精通一种或多种编程语言,例如 Go、Java、C++、C#、Python 或 Typescript,并且热衷于学习新语言。
  • 精通工程实践,包括工程和架构原则知识
  • 拥有软件设计和实现、安全性、云、基础设施即代码、CI/CD 以及任何相关硬件的经验
  • 自我驱动,并不断努力改进您的团队、部门和同事
  • 倡导敏捷/精益交付方法
  • 热衷于增强知识,并对新兴技术表现出好奇心
  • 在支持团队同事完成任务时表现出同理心和理解

除了大量的在职培训和无限的机会,您还将获得:

  • 有竞争力的薪资(根据经验最高可达 80,000 英镑)
  • 远程优先的工作环境
  • 公司养老金
  • 团体人寿保险,保额为固定年薪的 10 倍,最高可达 500,000 英镑
  • 用于内部和外部培训及会议的培训预算
  • 25 天年假加上所有英国公共假期
  • 最新的工具和技术
  • 灵活的工作时间

无中介 - 请注意,我们不接受来自中介机构的申请。我们将把所有提交的简历视为直接申请人。


更多关于Redbrain招聘高级Golang软件工程师(远程/伯明翰)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Redbrain招聘高级Golang软件工程师(远程/伯明翰)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个非常吸引人的Golang高级工程师职位。Redbrain的技术栈与当前云原生和微服务架构的趋势高度一致,尤其是对GCP、Kubernetes和Golang的深度使用。每年处理超过4000亿个产品,这要求系统必须具备极高的并发处理能力和数据吞吐量,这正是Golang的强项。

从职位描述来看,他们需要的工程师不仅要能写代码,更要能设计和维护高性能、可扩展的分布式系统。以下是一些与职位要求相关的Golang技术点示例:

1. 高性能微服务与gRPC: 职位中提到了gRPC和Protobuf,这是构建高效内部服务通信的黄金标准。一个典型的服务定义和实现可能如下:

// product.proto 定义 (Protocol Buffers)
syntax = "proto3";
package product;

service ProductService {
    rpc GetProduct(ProductRequest) returns (ProductResponse) {}
    rpc StreamProducts(StreamRequest) returns (stream Product) {}
}

message ProductRequest {
    string id = 1;
}

message ProductResponse {
    Product product = 1;
}

// Go 服务端实现
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "your_project/gen/proto" // 生成的Go代码
)

type server struct {
    pb.UnimplementedProductServiceServer
}

func (s *server) GetProduct(ctx context.Context, req *pb.ProductRequest) (*pb.ProductResponse, error) {
    // 从数据库(如Spanner/Postgres)或缓存中获取产品数据
    product := fetchProductFromDB(req.Id)
    return &pb.ProductResponse{Product: product}, nil
}

func (s *server) StreamProducts(req *pb.StreamRequest, stream pb.ProductService_StreamProductsServer) error {
    // 处理海量数据流,非常适合每天数十亿产品的场景
    for product := range productChannel {
        if err := stream.Send(product); err != nil {
            return err
        }
    }
    return nil
}

func main() {
    lis, _ := net.Listen("tcp", ":50051")
    s := grpc.NewServer()
    pb.RegisterProductServiceServer(s, &server{})
    s.Serve(lis)
}

2. 并发数据处理与上下文控制: 处理海量数据需要卓越的并发模式。Golang的goroutine和channel是核心工具。

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func processProductBatch(ctx context.Context, productIDs []string) []Result {
    var wg sync.WaitGroup
    results := make(chan Result, len(productIDs))
    resultSlice := make([]Result, 0, len(productIDs))

    // 使用工作池模式控制并发度,防止资源耗尽
    semaphore := make(chan struct{}, 100) // 限制最大100个并发goroutine

    for _, id := range productIDs {
        wg.Add(1)
        go func(productID string) {
            defer wg.Done()
            semaphore <- struct{}{}        // 获取信号量
            defer func() { <-semaphore }() // 释放信号量

            select {
            case <-ctx.Done():
                // 上下文被取消(如超时),立即终止处理
                return
            default:
                // 执行实际的产品处理逻辑,如数据清洗、分析或写入Elasticsearch
                result := expensiveProcessingOperation(productID)
                results <- result
            }
        }(id)
    }

    // 等待所有goroutine完成,然后关闭结果channel
    go func() {
        wg.Wait()
        close(results)
    }()

    // 收集结果
    for result := range results {
        resultSlice = append(resultSlice, result)
    }
    return resultSlice
}

func expensiveProcessingOperation(id string) Result {
    // 模拟耗时操作
    time.Sleep(10 * time.Millisecond)
    return Result{ID: id}
}

3. 与基础设施集成(Pub/Sub, GCS): 职位要求熟悉GCP生态系统。以下是使用Golang与Pub/Sub和GCS交互的常见模式。

package main

import (
    "context"
    "fmt"
    "io"

    "cloud.google.com/go/pubsub"
    "cloud.google.com/go/storage"
)

// 发布事件到Pub/Sub
func publishProductEvent(ctx context.Context, client *pubsub.Client, topicID string, data []byte) error {
    topic := client.Topic(topicID)
    result := topic.Publish(ctx, &pubsub.Message{Data: data})
    id, err := result.Get(ctx) // 等待发布确认
    if err != nil {
        return fmt.Errorf("publish failed: %v", err)
    }
    fmt.Printf("Published message with ID: %s\n", id)
    return nil
}

// 从Google Cloud Storage读取数据
func readFromGCS(ctx context.Context, client *storage.Client, bucketName, objectName string) ([]byte, error) {
    bucket := client.Bucket(bucketName)
    obj := bucket.Object(objectName)
    reader, err := obj.NewReader(ctx)
    if err != nil {
        return nil, err
    }
    defer reader.Close()

    return io.ReadAll(reader)
}

4. 可观测性与弹性设计: 对于需要高可靠性的系统,必须包含监控、链路追踪和健康检查。

package main

import (
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    // 定义Prometheus指标
    httpRequestsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total number of HTTP requests.",
        },
        []string{"path", "method", "status"},
    )
    httpRequestDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "Duration of HTTP requests.",
            Buckets: prometheus.DefBuckets,
        },
        []string{"path", "method"},
    )
)

// 带指标收集的HTTP中间件
func metricsMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        // 使用自定义ResponseWriter捕获状态码
        rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
        next(rw, r)
        duration := time.Since(start).Seconds()

        // 记录指标
        httpRequestsTotal.WithLabelValues(r.URL.Path, r.Method, http.StatusText(rw.statusCode)).Inc()
        httpRequestDuration.WithLabelValues(r.URL.Path, r.Method).Observe(duration)
    }
}

// 健康检查端点
func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
    // 检查数据库连接、外部服务依赖等
    if isDatabaseHealthy() && isCacheHealthy() {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("OK"))
        return
    }
    w.WriteHeader(http.StatusServiceUnavailable)
}

func main() {
    // 暴露Prometheus指标端点
    http.Handle("/metrics", promhttp.Handler())
    http.Handle("/health", http.HandlerFunc(healthCheckHandler))
    http.Handle("/api/products", metricsMiddleware(productHandler))
    http.ListenAndServe(":8080", nil)
}

这个职位对工程师在分布式系统、数据密集型应用和云原生技术方面的经验有很高要求。成功的候选人很可能需要展示出使用Golang解决大规模并发、低延迟数据处理和系统可观测性等复杂问题的能力。技术栈的现代性和数据规模的挑战性,使得这是一个能够极大提升工程师技术深度的机会。

回到顶部