Golang全栈工程师招聘 - 100%远程工作

Golang全栈工程师招聘 - 100%远程工作 你好,我是 Customer.io 的工程经理 Julia。我正在寻找一名全栈工程师加入我们不断壮大的工程团队。

Customer.io 正在寻找以产品为中心、具有协作精神的全栈开发人员,他们喜欢解决有趣的难题,并渴望帮助我们构建一个客户喜爱的可扩展平台。在这个职位上,您将对产品产生直接影响,拥有高度的自主权和自由度。我们的小型、远程优先团队充满乐趣、热情且高效。我们提供大量机会来发展和完善您的技能,同时产生重大影响。我们团队的其他成员拥有从广告技术到游戏等各行各业的背景,我们相信,接纳我们独特的视角和专业知识是我们作为一个协作团队取得成功的关键。

我们重视多样性,作为一家分布式公司,我们致力于为您提供灵活性和自由度,让您可以在世界任何地方工作,工作时间适合您的家庭和生活。

您将要做的事情:

  • 成为使用 Go 编写架构良好、经过充分测试且易于理解的服务,以及使用 JavaScript (Ember.js) 构建用户界面的榜样和导师,帮助我们的客户轻松大规模地发送及时且相关的消息。
  • 运用您独特的视角,帮助我们定义和构建下一代功能和基础设施,以帮助我们的客户和公司蓬勃发展。
  • 为维护我们不断发展的设计系统做出贡献。
  • 通过代码审查、结对编程、团队协作和培训,与同事学习、实践和分享,共同提高我们的集体知识和最佳实践。
  • 与我们的技术支持团队合作,诊断运营问题,并帮助客户通过我们的产品实现他们的目标。
  • 在一个友好、支持性的团队中发挥积极作用,该团队鼓励您和整个公司作为个人、专业人士和团队共同成长。

我们正在寻找的人:

  • 具备协作精神,拥有出色的沟通技巧,并渴望以同理心和尊重的方式帮助我们做出明智的决策。
  • 具有与客户合作的经验,并能深刻理解他们的需求,为他们的实际问题提供及时的解决方案。
  • 具有使用 JavaScript 和 CSS 等前端技术构建复杂 Web 应用程序的经验。有 Ember.js 经验者优先,但我们的大多数工程师都是在工作中学会并取得成功的。
  • 深刻理解如何创建既易于访问又高性能的前端 Web 应用程序。
  • 深刻理解可扩展性问题,并具有在云基础设施上构建高性能分布式应用程序的经验。
  • 熟悉在 UNIX 环境中工作并应用现代协作开发实践。有 Go 经验者优先,但我们的大多数工程师都是在工作中学会并取得成功的。
  • 具有使用关系型数据库系统(最好是 MySQL)的经验。
  • 有在分布式公司工作的经验者优先。

关于 Customer.io

Customer.io 的使命是提供人们乐于接收的自动化通信服务。目前,超过 3,800 家互联网企业使用 Customer.io 来管理、发送和跟踪电子邮件、短信和推送通知的性能。与典型的营销平台不同,Customer.io 通过使用行为数据(即人们在登录 Web 或移动应用程序时做什么或不做什么)来帮助企业提高相关性。

Customer.io 的福利包括:

我们提供的起薪为 93,000 至 154,000 美元,具体取决于经验和市场行情。

  • 无限制带薪休假 - 我们建议 20 天假期(除节假日和病假外),以便您可以放松身心、断开连接并恢复活力。
  • 为您您的家属提供 100% 的医疗、牙科、视力和补充保险。
  • 12 周带薪育儿假 - 适用于生育、收养或寄养。
  • 401k 退休金匹配 - 退休金供款最高可获得 5% 的等额匹配。
  • 健康与保健津贴 - 每月最高 200 美元,可用于您的健康生活需求,包括健身房会员、针灸、按摩或自行车维修。
  • 家庭办公室津贴 - 最高 2,000 美元,用于帮助您设置家庭办公室,以便您能发挥最佳工作状态。
  • 互联网 + 手机报销 - 每月最高 200 美元,用于您的互联网和手机套餐。
  • 联合办公空间报销 - 每月最高 300 美元,用于您希望在工作环境中工作的时段。
  • 学习与发展 - 每年最高 2,000 美元的报销,用于参加会议、购买书籍、参加课程、研讨会和进行个人项目 - 任何有助于您发展技能的事物。
  • Customer.io 工作四年后,享受 1 个月带薪休假 - 用于度假或按您选择的方式度过。
  • 每年一次公司峰会,以及全年在小组中见面的机会。
  • 灵活的工作时间,可以在任何地方工作! - 只要您有可靠的互联网连接,并且与您的经理有一定重叠的工作时间,您就可以在任何地方、任何时间工作。

所有最终候选人都将被要求填写一份雇佣和教育验证授权表(允许我们验证您简历中列出的工作经历和教育背景),作为我们入职前流程的一部分。

Customer.io 认识到系统性不公对不同社区的窒息性影响。我们承诺利用我们的影响力来增加科技行业内的包容性和公平性。我们努力构建包容性的团队文化,实施无偏见的招聘实践,并发展社区合作伙伴关系以扩大我们的全球影响力。

加入我们!

查看我们的招聘页面,了解更多关于为什么您应该来和我们一起工作的信息!我们对我们"同理心、透明度、责任感和敢于尴尬"的核心价值观充满热情,并正在寻找新的同事来分享和建立这种热情!

如何申请

点击此处申请,并告诉我们您对这个职位感兴趣的原因!提前申请没有优势,所以请全力以赴。我们计划向所有申请人回复关于您申请状态的更新。

以下是您可以从我们的招聘流程中期待的内容(顺序可能更改):

  1. 与我们的招聘人员进行 30 分钟的视频通话。
  2. 与招聘经理进行 45 分钟的视频通话。
  3. 与两位潜在团队成员(前端和后端工程师)进行 60 分钟的技术面试。
  4. 与两位潜在团队成员一起完成带回家的前端和后端任务。

更多关于Golang全栈工程师招聘 - 100%远程工作的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang全栈工程师招聘 - 100%远程工作的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个非常吸引人的全栈工程师职位机会!Customer.io的技术栈(Go + Ember.js)和远程工作文化都很不错。从技术角度来看,这个职位对Go语言的要求很务实——虽然有经验者优先,但更看重学习能力。

以下是一个典型的Go后端服务示例,展示了这类项目中可能涉及的代码结构:

package main

import (
    "context"
    "database/sql"
    "encoding/json"
    "log"
    "net/http"
    "time"
    
    "github.com/go-chi/chi"
    "github.com/go-chi/chi/middleware"
    _ "github.com/go-sql-driver/mysql"
)

type NotificationService struct {
    db *sql.DB
}

type Notification struct {
    ID        int       `json:"id"`
    UserID    int       `json:"user_id"`
    Type      string    `json:"type"`
    Content   string    `json:"content"`
    Status    string    `json:"status"`
    CreatedAt time.Time `json:"created_at"`
}

func (s *NotificationService) SendNotification(ctx context.Context, n *Notification) error {
    query := `INSERT INTO notifications (user_id, type, content, status) VALUES (?, ?, ?, ?)`
    result, err := s.db.ExecContext(ctx, query, n.UserID, n.Type, n.Content, "pending")
    if err != nil {
        return err
    }
    
    id, err := result.LastInsertId()
    if err != nil {
        return err
    }
    
    n.ID = int(id)
    n.Status = "pending"
    n.CreatedAt = time.Now()
    
    // 异步处理通知发送
    go s.processNotification(n)
    
    return nil
}

func (s *NotificationService) processNotification(n *Notification) {
    // 模拟通知发送逻辑
    time.Sleep(100 * time.Millisecond)
    
    query := `UPDATE notifications SET status = ? WHERE id = ?`
    _, err := s.db.Exec(query, "sent", n.ID)
    if err != nil {
        log.Printf("Failed to update notification status: %v", err)
    }
}

func (s *NotificationService) GetUserNotifications(w http.ResponseWriter, r *http.Request) {
    userID := chi.URLParam(r, "userID")
    
    rows, err := s.db.QueryContext(r.Context(), 
        "SELECT id, user_id, type, content, status, created_at FROM notifications WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",
        userID,
    )
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer rows.Close()
    
    var notifications []Notification
    for rows.Next() {
        var n Notification
        if err := rows.Scan(&n.ID, &n.UserID, &n.Type, &n.Content, &n.Status, &n.CreatedAt); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        notifications = append(notifications, n)
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(notifications)
}

func main() {
    // 数据库连接
    db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/customerio")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    
    // 设置连接池
    db.SetMaxOpenConns(25)
    db.SetMaxIdleConns(25)
    db.SetConnMaxLifetime(5 * time.Minute)
    
    service := &NotificationService{db: db}
    
    r := chi.NewRouter()
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)
    
    r.Route("/api/v1", func(r chi.Router) {
        r.Get("/users/{userID}/notifications", service.GetUserNotifications)
        
        r.Post("/notifications", func(w http.ResponseWriter, r *http.Request) {
            var n Notification
            if err := json.NewDecoder(r.Body).Decode(&n); err != nil {
                http.Error(w, err.Error(), http.StatusBadRequest)
                return
            }
            
            if err := service.SendNotification(r.Context(), &n); err != nil {
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
            }
            
            w.Header().Set("Content-Type", "application/json")
            w.WriteHeader(http.StatusCreated)
            json.NewEncoder(w).Encode(n)
        })
    })
    
    log.Println("Server starting on :8080")
    log.Fatal(http.ListenAndServe(":8080", r))
}

这个示例展示了Customer.io这类消息平台可能涉及的技术实现:

  1. 使用chi路由器构建RESTful API
  2. MySQL数据库操作和连接池配置
  3. 异步处理消息发送
  4. 标准化的错误处理和JSON响应

对于前端部分,Ember.js的典型组件可能如下:

// app/components/notification-list.js
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';

export default class NotificationListComponent extends Component {
  @service notifications;
  @service router;
  
  @action
  async sendNotification(content, type) {
    try {
      const response = await fetch('/api/v1/notifications', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content, type, user_id: this.args.userId })
      });
      
      if (response.ok) {
        this.notifications.success('Notification sent successfully');
        this.router.refresh();
      }
    } catch (error) {
      this.notifications.error('Failed to send notification');
    }
  }
}

这个职位的技术挑战在于需要处理大规模的消息发送、确保系统的高可用性,同时保持前端用户体验的流畅性。Go的并发模型和性能特性非常适合处理这类高并发的消息处理场景。

回到顶部