Golang远程后端软件开发者招聘

Golang远程后端软件开发者招聘 成立于2018年,我们快速发展的虚拟电话平台已吸引了来自欧洲各地投资者的数百万美元资金。我们是一个以远程为导向的国际团队,致力于为客户提供卓越的产品,并为同事创造优秀的工作环境。为此,我们制定了一套丰厚的福利方案(包括无限带薪假期!),并从新员工入职第一天起即可享受。

CloudTalk 是一家即使在艰难时期你也可以依靠的公司。

我们所有的工程团队都为一个产品贡献力量。在一个工程团队中,你会找到10-15名同事。每个团队由后端和前端开发人员、质量保证工程师、产品经理、技术负责人和工程经理组成(Spotify模型)。我们的团队专注于不同领域的各种项目。你不仅将负责核心功能的维护或升级(新技术、版本、兼容性问题、架构变更),还将参与创建新功能。我们采用SCRUM模式运作,每两周进行一次冲刺,并在合并请求前进行代码审查。

这是我们的故事。你想成为其中的一部分吗?

你将要做的事情:

  • 在一个小团队中工作,开发市场上最好的产品
  • 实现一个可扩展、稳定且用户友好的产品,以应对我们当前的业务增长
  • 在现代敏捷软件工程环境中高效工作
  • 解决具有挑战性的技术问题,每天让你的技能得到考验
  • 提升 CloudTalk 的可用性
  • 负责以下功能:
    • 实时通话路由引擎
    • WebRTC 通话解决方案
    • 集成或公共 API
    • 语音识别
    • 情绪检测
  • 参与新解决方案和功能的决策

我们正在寻找的人才:

  • 拥有3年 Go 编程经验
  • 具备软件工程背景和面向对象编程经验
  • 一流的编程技能,能够编写可维护、高效、可靠且安全的高质量代码
  • 勇于学习新技术和应用开发的新技术方法
  • 有第一份工作经验,尤其是在初创公司,是加分项,但我们也会考虑你的个人项目
  • 最后但同样重要的是——热情和积极的态度

我们的技术栈:

  • 编程语言:Go、Node.js、Angular 或 React
  • 核心技术:Asterisk、Redis、Amazon AWS、MariaDB、Cloudflare、Nginx、Kafka、Electron、WebRTC、Kamailio、ElasticSearch
  • 监控和备份工具:Zabbix、Grafana

你会爱上成为 CloudTalker 的原因:

  • 无限带薪休假
  • 完全远程工作或从我们的任何办公室(马拉加/布拉格/布拉迪斯拉发)工作
  • 灵活的工作时间(无固定核心工作时间)
  • 高达5000欧元的推荐奖金
  • 员工持股计划
  • 根据公司业绩发放的季度奖金
  • 自由职业 / 全职
  • Multisport 健身卡(仅限捷克和斯洛伐克市场)

更多让你无法抗拒我们的理由:

  • 团队建设和研讨会
  • 沟通教练
  • 生日时自选书籍
  • 英语和德语语言课程
  • 斯洛伐克语和捷克语语言课程
  • 公司周边商品

关于 CloudTalk: CloudTalk 是一个现代化、用户友好的云电话解决方案,它颠覆了价值500亿美元停滞不前的电话市场。我们易于集成的特性和先进功能,平均为我们的客户每次电话通话节省2-3分钟!我们的解决方案深受全球客户支持和销售团队的喜爱。当然,我们可以用数据来支持这一大胆的声明——请查看我们在 [Capterra] 上的评论和荣誉。

我们相信,连接世界不仅通过技术,也通过人。CloudTalk 的230多名员工代表超过22个国籍,在欧洲、亚洲和南美洲远程工作。我们的客户遍及SaaS、电子商务、科技和金融等行业。我们的一些重要合作伙伴包括富士通、梅赛德斯、Oyo 和斯洛伐克共和国卫生部。

我们非常高兴地宣布,我们已经完成了A轮融资。此轮A轮融资由 henQ VC 领投,Point Nine Capital 跟投,加上我们2019年从 Presto Ventures 获得的160万美元种子轮投资。


更多关于Golang远程后端软件开发者招聘的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我们仍在寻找高级 Golang 开发者和技术负责人。您有什么想问的吗?请随时通过 www.linkedin.com/in/𝓩𝓭𝓮𝓷𝓴𝓪-gillarová-b32a7b130 联系。或者,也可以收听由 Josef Podany 作为嘉宾的播客 ‎CZPodcast: CZPodcast 253 - Cloudtalk on Apple Podcasts

更多关于Golang远程后端软件开发者招聘的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个非常吸引人的Go后端开发职位。从技术栈和要求来看,这是一个对Go语言深度和实践经验有较高要求的岗位。以下是一些针对该职位技术要求的专业分析和示例,供潜在申请者参考:

1. 关于“3年Go编程经验”与“高质量代码” 这通常意味着需要深入理解Go的并发模型、接口设计和错误处理机制。例如,在处理“实时通话路由引擎”时,可能会大量使用goroutine和channel。

// 一个简化的路由引擎工作池示例,展示并发模式
package main

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

type CallRequest struct {
    CallID string
    Data   string
}

func worker(ctx context.Context, id int, jobs <-chan CallRequest, results chan<- string, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        select {
        case job, ok := <-jobs:
            if !ok {
                return
            }
            // 模拟路由处理逻辑
            result := fmt.Sprintf("Worker %d routed call %s: %s", id, job.CallID, job.Data)
            results <- result
        case <-ctx.Done():
            return
        }
    }
}

func main() {
    const numWorkers = 5
    jobs := make(chan CallRequest, 100)
    results := make(chan string, 100)
    var wg sync.WaitGroup
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // 启动工作池
    for w := 1; w <= numWorkers; w++ {
        wg.Add(1)
        go worker(ctx, w, jobs, results, &wg)
    }

    // 发送任务
    go func() {
        for i := 1; i <= 10; i++ {
            jobs <- CallRequest{CallID: fmt.Sprintf("CALL-%d", i), Data: "some SIP data"}
        }
        close(jobs)
    }()

    // 收集结果
    go func() {
        wg.Wait()
        close(results)
    }()

    for result := range results {
        fmt.Println(result)
    }
}

2. 技术栈整合示例 职位要求与Asterisk、Kafka、Redis等核心技术集成。以下是一个模拟处理通话事件的Go服务片段,它消费Kafka消息并更新Redis状态:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/confluentinc/confluent-kafka-go/kafka"
    "github.com/go-redis/redis/v8"
    "golang.org/x/net/context"
)

type CallEvent struct {
    EventType string `json:"event_type"` // e.g., "call_started", "call_ended"
    CallID    string `json:"call_id"`
    Timestamp int64  `json:"timestamp"`
}

func main() {
    // 初始化Kafka消费者
    c, err := kafka.NewConsumer(&kafka.ConfigMap{
        "bootstrap.servers": "localhost:9092",
        "group.id":          "call-event-processor",
        "auto.offset.reset": "earliest",
    })
    if err != nil {
        panic(err)
    }
    defer c.Close()

    // 初始化Redis客户端
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })
    ctx := context.Background()

    // 订阅主题
    c.SubscribeTopics([]string{"call-events"}, nil)

    for {
        msg, err := c.ReadMessage(-1)
        if err != nil {
            fmt.Printf("Consumer error: %v\n", err)
            continue
        }

        var event CallEvent
        if err := json.Unmarshal(msg.Value, &event); err != nil {
            fmt.Printf("Failed to unmarshal event: %v\n", err)
            continue
        }

        // 根据事件类型更新Redis状态
        key := fmt.Sprintf("call:%s", event.CallID)
        switch event.EventType {
        case "call_started":
            // 设置呼叫开始状态,过期时间设为1小时防止内存泄漏
            rdb.Set(ctx, key, "active", time.Hour)
        case "call_ended":
            // 呼叫结束,更新状态并设置较短的过期时间
            rdb.Set(ctx, key, "ended", time.Minute*5)
        }
        fmt.Printf("Processed event %s for call %s\n", event.EventType, event.CallID)
    }
}

3. 公共API开发 “集成或公共API”是职责之一。以下是一个使用Go标准库net/http构建的符合RESTful风格的API端点示例,用于管理通话记录:

package main

import (
    "encoding/json"
    "net/http"
    "strconv"
)

type CallRecord struct {
    ID        string `json:"id"`
    From      string `json:"from"`
    To        string `json:"to"`
    Duration  int    `json:"duration_seconds"`
    Timestamp int64  `json:"timestamp"`
}

var callRecords = map[string]CallRecord{
    "1": {ID: "1", From: "+1234567890", To: "+0987654321", Duration: 300, Timestamp: 1672531200},
}

func getCallRecords(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    records := make([]CallRecord, 0, len(callRecords))
    for _, record := range callRecords {
        records = append(records, record)
    }
    json.NewEncoder(w).Encode(records)
}

func getCallRecordByID(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    record, exists := callRecords[id]
    if !exists {
        http.Error(w, "Call record not found", http.StatusNotFound)
        return
    }
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(record)
}

func createCallRecord(w http.ResponseWriter, r *http.Request) {
    var newRecord CallRecord
    if err := json.NewDecoder(r.Body).Decode(&newRecord); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    // 模拟生成ID并存储
    newID := strconv.Itoa(len(callRecords) + 1)
    newRecord.ID = newID
    callRecords[newID] = newRecord

    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(newRecord)
}

func main() {
    // 使用Go 1.22+的增强型路由模式
    http.HandleFunc("GET /api/v1/calls", getCallRecords)
    http.HandleFunc("GET /api/v1/calls/{id}", getCallRecordByID)
    http.HandleFunc("POST /api/v1/calls", createCallRecord)

    http.ListenAndServe(":8080", nil)
}

4. 与WebRTC集成 虽然WebRTC主要是前端技术,但后端需要提供信令服务。以下是一个简单的WebSocket服务器示例,用于交换WebRTC信令数据:

package main

import (
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}

func handleSignaling(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("Upgrade failed:", err)
        return
    }
    defer conn.Close()

    for {
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            log.Println("Read error:", err)
            break
        }
        // 这里应包含业务逻辑:将信令消息(offer/answer/candidate)路由给正确的对等端
        log.Printf("Received signaling message: %s", message)
        // 示例:回声消息
        err = conn.WriteMessage(messageType, message)
        if err != nil {
            log.Println("Write error:", err)
            break
        }
    }
}

func main() {
    http.HandleFunc("/ws", handleSignaling)
    log.Fatal(http.ListenAndServe(":8081", nil))
}

这个职位涉及的技术挑战非常全面,从底层的基础设施集成(Asterisk/Kamailio)到高并发服务开发,再到对外API设计。对于拥有3年以上Go经验的开发者来说,这是一个能充分运用Go在并发、网络编程和系统集成方面优势的绝佳机会。

回到顶部