[资深后端工程师(Golang)] 荷兰鹿特丹工作机会 - 需搬迁

[资深后端工程师(Golang)] 荷兰鹿特丹工作机会 - 需搬迁 在 Housing Anywhere,我们的目标是为寻找学生住宿的任何人提供最佳匹配。我们是一个点对点市场平台,这意味着您将构建一个满足学生住宿市场双方需求的应用程序。Housing Anywhere 业务覆盖 50 多个国家和 250 多个城市,已与全球 127 多所大学建立合作伙伴关系。

目前平台主要使用 Go 语言开发,后端采用 PostgreSQL 数据库。服务器组件部署在 Google Cloud 架构上,支持轻松扩展。我们使用的其他技术和工具包括 ReactJS、Redux、GraphQL、SASS、Webpack。

我们的产品开发团队正在扩充至 31 人(含产品负责人、产品经理、前端工程师、后端工程师、质量保证工程师和用户体验/界面设计师)。为加强团队实力,我们正在寻找在相关领域具有解决复杂问题经验的专业工程师。需要掌握 Go 语言知识。

您是否拥有丰富的 Golang 经验?请与我们联系,我们正在招聘高级职位。

听起来充满挑战?快来参与 Housing Anywhere 的建设!

后端开发工程师所需特质:

积极主动且开放的心态 条理清晰且组织有序 具备团队精神 能够找到简洁明了的解决方案,并能及时适应需求变更 对新科技保持兴趣

所需经验:

计算机科学或相关领域教育背景优先,但热情转行者同样欢迎 具有在线市场平台、服务提供商和 API 开发经验者优先 具备 Go 语言在生产级环境中的实战经验 除 Go 外还需掌握至少一门编程语言,如:C、Python、Ruby、JavaScript 等 数据库查询知识(优先考虑 PostgreSQL) Git 代码版本管理 对美味汉堡有基本鉴赏力 了解计算机安全基础知识和安全编程原则 具备(网页)用户界面设计与开发的基础认知

福利待遇

您将加入一家国际初创企业,与来自 12 个不同国家、由 35名全职成员组成的年轻活力团队共事 高责任感:网站变更将面向全球用户

具体信息

全职岗位(每周 40 小时) 立即入职 试用期:1 个月(若在荷兰境外可远程进行) 合同期限:我们希望从 7 个月期开始合作 工作地点:荷兰鹿特丹办公室

薪酬待遇

根据经验提供具有竞争力的薪资 安家套餐:若从国外加入,我们将为您办理签证并全额报销个人机票,同时为随行家属报销 50% 机票费用。此外,我们可通过专业房屋中介协助您寻找合适住所


更多关于[资深后端工程师(Golang)] 荷兰鹿特丹工作机会 - 需搬迁的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我有兴趣加入你们的团队,这是我的邮箱地址:dev.tech.generic@gmail.com

更多关于[资深后端工程师(Golang)] 荷兰鹿特丹工作机会 - 需搬迁的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


作为使用Go语言开发生产级系统的工程师,我来分析这个职位所需的技术栈和实际开发场景。

核心Go技术栈分析

从描述看,这是一个典型的Go微服务架构,结合PostgreSQL和Google Cloud。以下是相关技术实现的示例:

数据库层 - PostgreSQL集成

package main

import (
    "context"
    "database/sql"
    "fmt"
    "log"
    
    _ "github.com/lib/pq"
)

type Accommodation struct {
    ID          int    `json:"id"`
    Title       string `json:"title"`
    City        string `json:"city"`
    Price       int    `json:"price"`
    IsAvailable bool   `json:"is_available"`
}

type AccommodationRepository struct {
    db *sql.DB
}

func NewAccommodationRepository(connStr string) (*AccommodationRepository, error) {
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        return nil, err
    }
    
    if err := db.Ping(); err != nil {
        return nil, err
    }
    
    return &AccommodationRepository{db: db}, nil
}

func (r *AccommodationRepository) FindByCity(ctx context.Context, city string) ([]Accommodation, error) {
    query := `
        SELECT id, title, city, price, is_available 
        FROM accommodations 
        WHERE city = $1 AND is_available = true
        ORDER BY price ASC
    `
    
    rows, err := r.db.QueryContext(ctx, query, city)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    var accommodations []Accommodation
    for rows.Next() {
        var acc Accommodation
        if err := rows.Scan(&acc.ID, &acc.Title, &acc.City, &acc.Price, &acc.IsAvailable); err != nil {
            return nil, err
        }
        accommodations = append(accommodations, acc)
    }
    
    return accommodations, nil
}

API服务层 - RESTful实现

package main

import (
    "encoding/json"
    "net/http"
    "strconv"
    
    "github.com/gorilla/mux"
)

type AccommodationService struct {
    repo *AccommodationRepository
}

func NewAccommodationService(repo *AccommodationRepository) *AccommodationService {
    return &AccommodationService{repo: repo}
}

func (s *AccommodationService) GetAccommodationsByCity(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    city := vars["city"]
    
    accommodations, err := s.repo.FindByCity(r.Context(), city)
    if err != nil {
        http.Error(w, "Internal server error", http.StatusInternalServerError)
        return
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(accommodations)
}

func (s *AccommodationService) UpdateAvailability(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    idStr := vars["id"]
    
    id, err := strconv.Atoi(idStr)
    if err != nil {
        http.Error(w, "Invalid accommodation ID", http.StatusBadRequest)
        return
    }
    
    var request struct {
        Available bool `json:"available"`
    }
    
    if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
        http.Error(w, "Invalid request body", http.StatusBadRequest)
        return
    }
    
    // 实现更新逻辑
    err = s.updateAvailability(r.Context(), id, request.Available)
    if err != nil {
        http.Error(w, "Failed to update availability", http.StatusInternalServerError)
        return
    }
    
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{"status": "updated"})
}

并发处理模式

package main

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

type SearchCoordinator struct {
    services []SearchService
}

func (sc *SearchCoordinator) ConcurrentSearch(ctx context.Context, query string) ([]SearchResult, error) {
    var wg sync.WaitGroup
    results := make(chan SearchResult, len(sc.services))
    errCh := make(chan error, 1)
    
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()
    
    for _, service := range sc.services {
        wg.Add(1)
        go func(svc SearchService) {
            defer wg.Done()
            
            result, err := svc.Search(ctx, query)
            if err != nil {
                select {
                case errCh <- err:
                default:
                }
                return
            }
            
            select {
            case results <- result:
            case <-ctx.Done():
            }
        }(service)
    }
    
    go func() {
        wg.Wait()
        close(results)
        close(errCh)
    }()
    
    var allResults []SearchResult
    for result := range results {
        allResults = append(allResults, result)
    }
    
    select {
    case err := <-errCh:
        return allResults, err
    default:
        return allResults, nil
    }
}

中间件和安全实现

package main

import (
    "context"
    "net/http"
    "strings"
    
    "github.com/dgrijalva/jwt-go"
)

func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        authHeader := r.Header.Get("Authorization")
        if authHeader == "" {
            http.Error(w, "Authorization header required", http.StatusUnauthorized)
            return
        }
        
        tokenString := strings.TrimPrefix(authHeader, "Bearer ")
        claims, err := validateToken(tokenString)
        if err != nil {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }
        
        ctx := context.WithValue(r.Context(), "userClaims", claims)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

func validateToken(tokenString string) (jwt.MapClaims, error) {
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return []byte("your-secret-key"), nil
    })
    
    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
        return claims, nil
    }
    
    return nil, err
}

技术架构要点

这个职位需要的Go工程师应该具备:

  1. 微服务架构经验 - 基于Google Cloud的分布式系统
  2. 数据库优化 - PostgreSQL查询性能和索引设计
  3. API设计 - RESTful和可能的GraphQL端点
  4. 并发编程 - 处理高并发租房请求
  5. 安全实践 - 用户数据和支付信息保护

从技术栈看,这是一个成熟的Go生产环境,需要处理国际化、支付集成、房源匹配等复杂业务逻辑。PostgreSQL的使用表明对数据一致性和复杂查询有较高要求。

回到顶部