About the Position

We are looking for an aspiring Go Developer who wants to gain hands-on experience building backend services and Telegram bots. You will work alongside experienced developers and contribute to real projects using Go, PostgreSQL, and related tooling.

For details about how our internship works, check out our Internship Overview.
Learn more about our team at https://foreachpartners.com/.


What You Will Do

  • Build and maintain backend web services in Go, including HTTP APIs and integrations with PostgreSQL.
  • Develop Telegram bots using Go (e.g., telebot or similar libraries).
  • Collaborate with the team to analyze requirements, design solutions, and deliver features.
  • Continuously learn and adopt modern development practices and tools.

What We’re Looking For

Core Knowledge

  • Basic knowledge of Go syntax and tooling.
  • Understanding of goroutines, channels, and contexts.

Eagerness to Learn

  • Willingness to invest personal time into mastering multiple development technologies.

Additional Skills (Nice-to-Have)

  • Familiarity with JavaScript, HTML, CSS (including preprocessors like LESS/SASS).
  • Comfort with Linux CLI, Docker, and Git.
  • Experience with IDEs/editors such as Goland or VS Code.

Foundational CS Literacy

  • Basic understanding of databases, networking, common web stacks, and Linux-based operating systems.

Why Apply?

  • Practical Experience: Work on real projects with experienced professionals.
  • Skill Growth: Improve your backend engineering, concurrency, and problem-solving skills.
  • Career Building: Outstanding participants may have opportunities to continue collaboration on commercial terms.

Next Steps: Test Tasks

Complete the following tasks as part of your application. Provide links as requested in the deliverables.

Task 1: Implement a getScore Function

Objective:
Given the following Go code that generates a list of game score states, implement getScore(gameStamps, offset) to return the score at a specific offset.

package main

import (
"fmt"
"math"
"math/rand"
"time"
)

const TIMESTAMPS_COUNT = 50000

const PROBABILITY_SCORE_CHANGED = 0.0001

const PROBABILITY_HOME_SCORE = 0.45

const OFFSET_MAX_STEP = 3

type Score struct {
Home int
Away int
}

type ScoreStamp struct {
Offset int
Score Score
}

func main() {
var stamps = fillScores()

for _, stamp := range *stamps {
fmt.Printf("%v: %v -- %v\n", stamp.Offset, stamp.Score.Home, stamp.Score.Away)
}

}

func generateStamp(previousValue ScoreStamp) ScoreStamp {
random := rand.New(rand.NewSource(time.Now().UnixNano()))

scoreChanged := random.Float32() > 1-PROBABILITY_SCORE_CHANGED
homeScoreChange := 0
if scoreChanged && random.Float32() > 1-PROBABILITY_HOME_SCORE {
homeScoreChange = 1
}

awayScoreChange := 0
if scoreChanged && homeScoreChange == 0 {
awayScoreChange = 1
}

offsetChange := int(math.Floor(random.Float64()*OFFSET_MAX_STEP)) + 1

return ScoreStamp{
Offset: previousValue.Offset + offsetChange,
Score: Score{
Home: previousValue.Score.Home + homeScoreChange,
Away: previousValue.Score.Away + awayScoreChange,
},
}
}

func fillScores() *[]ScoreStamp {

scores := make([]ScoreStamp, TIMESTAMPS_COUNT)
prevScore := ScoreStamp{
Offset: 0,
Score: Score{Home: 0, Away: 0},
}
scores[0] = prevScore

for i := 1; i < TIMESTAMPS_COUNT; i++ {
scores[i] = generateStamp(prevScore)
prevScore = scores[i]
}

return &scores
}

/*
Takes list of game's stamps and time offset for which returns the scores for the home and away teams.
Please pay attention to that for some offsets the game_stamps list may not contain scores.
*/

func getScore(gameStamps []ScoreStamp, offset int) Score {
// continue the function's implementation
}

Deliverables:

  • Provide a link to a gist with your getScore implementation.

Task 2: Write Tests for getScore

Objective:
Using Go’s standard testing library, write comprehensive unit tests for the getScore(gameStamps, offset) function. Cover distinct scenarios, avoid repetition, and use clear, descriptive test names.

Deliverables:

  • Provide a link to a gist with your test files.

Task 3: Console Utility — Find Prime Numbers in Ranges

Objective:
Develop a console utility that accepts multiple numeric ranges, an output file name, and a timeout. The utility finds all prime numbers within the given ranges and writes them to the file.

Example command:

find_primes --file testfile.txt --timeout 10 --range 1:10 --range 200000:3000000 --range 400:500
  • file: name of the output file to write the found prime numbers
  • timeout: value in seconds after which the program must stop execution
  • range: a numeric range within which to find primes

Implementation Notes

  • Each range must be processed in its own goroutine.
  • Writing to the file should be performed in a separate goroutine.
  • Communication between goroutines should use channel(s).
  • Use contexts for timeout handling (select and/or ctx.Err()).
  • Result should be a single file main.go for ease of review.

Deliverables:

  • Provide a link to a gist with the full source code of the utility.

We look forward to reviewing your submissions and potentially welcoming you to our team!