Skip to content
VS

Računarski Fakultet Beograd · Expected 2027

VASILIJESTANKOVIĆ

Software Engineering Student

Compilers, concurrency, GPU kernels — and the platforms built on top of them.

Scroll to explore
01 /

SYSTEMS

Concurrency. Compilers. Architecture.

coursework · Collaborative university project

Concurrent Build Scheduler

Tasks arrive as a JSON dependency graph. The scheduler resolves what can run now, runs those in parallel across a hand-written thread pool, and unlocks the rest as their dependencies complete.

  • Python
  • Thread pool
  • Condition variables
  • Futures

Note 01

The graph decides, not the script

Tasks are declared in JSON along with what they depend on. The scheduler works out what is runnable at any moment and dispatches it — nothing is sequenced by hand, so adding a task changes the plan rather than the code.

Note 02

The pool is written, not imported

Worker threads, futures, locks and condition variables, built rather than called. Workers block on a condition variable instead of polling for work, which is the difference between a thread pool and a loop that happens to be threaded.

Note 03

Ready is not the same as allowed

Each task declares what it needs in CPU and memory. A task whose dependencies are satisfied still waits when the budget is spent. Cancellation runs through the same state machine, so no worker is left waiting on a task that will never finish.

Build task dependency graphfetch-deps and gen-proto run in parallel. compile waits for both. unit-tests, lint and typecheck then run in parallel. package waits for all three, and deploy runs last.fetch-depsgen-protocompileunit-testslinttypecheckpackagedeploy
PendingReadyRunningComplete

personal project

Piwo

Source text goes through a hand-written lexer into tokens, and a recursive-descent parser turns those tokens into an abstract syntax tree that serializes to JSON.

  • Java
  • Lexer
  • Recursive-descent parser
  • AST

Why it is worth building

Recursive descent is straightforward until the error cases. Reporting a syntax error usefully means carrying accurate line and column information out of the lexer and into every node of the tree, so a message can point at the character that broke rather than at the statement that contained it.

The keyword set is Serbian beer brands. Everything behind it — the token classification, the error positions, the serialized tree — is not a joke.

Source

  • keyword
  • ident
  • number
  • operator
  • punct
  • comment
Lexer

Tokens

The lexer emits a stream of classified tokens: keywords, identifiers, numbers, operators, punctuation and comments, each carrying its line and column.

Parser

AST

  • Program
  • FunctionDecl
  • Params
  • VarDecl
  • ArrayLiteral
  • IfStatement
  • BinaryExpr
  • Block
  • Assignment
Serialized to JSON

One thread per cell

Every cell of the grid is updated in parallel by a custom CUDA kernel. The grid size is configurable, so the same code runs at a size you can debug by eye and at one where the GPU is doing something worth doing.

Two buffers, not one

A naive diffusion step reads and writes the same grid, which makes the result depend on thread scheduling. Double-buffered device memory means every read comes from the previous state, so the update is race-free by construction rather than by luck.

The cost is transfer, not arithmetic

Device allocations persist across steps instead of being reallocated per frame, which keeps CPU–GPU traffic down to what actually has to cross the bus. On a simulation this shape, that is where the time goes.

03 /

PLATFORMS

System design carried through to working software.

Two systems where the design had to survive contact with real users, real money and real deadlines. One replaces software a client already depends on; the other exists to understand what happens when a system is split into services that can each fail on their own.

client project · In development for a higher-education client

Student Service Platform

A modular-monolith web replacement for an existing desktop student-service application, in development for a contracted higher-education client. Enrollment, courses, exams, grading, finances, documents, scheduling, notifications and reporting, across four role types.

  • Java 21
  • Spring Boot
  • React
  • TypeScript
  • MySQL

The part that is actually hard

Not the forms. Guaranteeing that two students cannot take the same last seat in a course, that a grade cannot be silently rewritten, and that a financial operation cannot be applied twice — while multiple users act on the same rows at the same moment.

Replacing a desktop system that people already rely on sets the bar: the new one has to be at least as trustworthy as the one it removes.

Student Service Platform
Student Service Platform overview showing student, administrator and professor portals
Head administrator
Head administrator reviewing student year-enrollment requests
Professor
Professor entering points for pre-exam activities
Student
Student profile with exam, ECTS and grade statistics
01

Architecture

A React and TypeScript client over a Spring Boot service layer, with the domain modelled in JPA and persisted to MySQL. Authorization sits in the domain model rather than at the edge, because four role types with different authority is a modelling problem, not a routing one.

Request path

  1. React
  2. REST API
  3. Spring Boot
  4. Modular monolith
  5. JPA / Hibernate
  6. MySQL
02

Security

Session-based authentication with CSRF protection on state-changing requests. Authorization is permission-based on top of roles, so an administrator and a head administrator differ by the permissions they hold rather than by branches scattered through the code.

  • 01Session-based authentication
  • 02CSRF protection
  • 03Role-based access control
  • 04Permission-based authorization
  • 05BCrypt password hashing
  • 06Rate limiting
  • 07Tamper-evident audit logging
03

Concurrency and reliability

The contended paths — taking a course seat, registering an exam result, applying a payment — run inside explicit transactional boundaries, with database constraints as the last line of defence. Pessimistic locking is used where two transactions genuinely cannot both proceed, and idempotency keys stop a retried request from applying an operation twice.

  • 01Transactional workflows
  • 02Database constraints
  • 03Pessimistic locking
  • 04Idempotency
  • 05Protected enrollment, examination and financial operations
04

Testing

Integration tests run against a real MySQL container rather than an in-memory substitute, so constraint and locking behaviour is exercised as it will actually behave in production. Playwright covers the workflows end to end, and the API is validated against its OpenAPI contract so the client and server cannot drift apart silently.

Test layers

  1. JUnit
  2. Testcontainers · MySQL
  3. OpenAPI contract
  4. Playwright E2E
05

Delivery and scanning

Schema changes are versioned with Flyway, the application is containerised behind nginx, and GitHub Actions runs the pipeline. CodeQL and Trivy scan the code and the image on the way through.

  • 01Docker
  • 02nginx
  • 03Flyway migrations
  • 04GitHub Actions
  • 05Testcontainers
  • 06Playwright
  • 07OpenAPI contract validation
  • 08CodeQL
  • 09Trivy

personal project

EcoTravel

Five independent Spring Boot services behind one gateway, split along business boundaries rather than technical layers.

  • Java 21
  • Spring Boot
  • Spring Cloud Gateway
  • Resilience4j
  • MySQL

Where it gets interesting

Once a booking spans accommodation, reservations and finance, the failure modes are more interesting than the happy path. Inter-service calls go through OpenFeign with Resilience4j guarding them, so a slow or unavailable downstream service produces a handled outcome rather than a cascade.

  • 01Independent services for authentication, accommodation, reservations, finance and maintenance
  • 02Centralized API gateway via Spring Cloud Gateway
  • 03Centralized configuration via Config Server
  • 04Declarative inter-service calls with OpenFeign
  • 05Resilience4j on cross-service paths
  • 06Unit, integration and end-to-end test suites
  • 07REST APIs documented with Swagger
EcoTravel service topologyA client calls the API gateway, which routes to five independent services: auth, accommodation, reservations, finance and maintenance. A reservation request goes from the client through the gateway to reservations, which then calls finance. A config server holds configuration centrally for all services.ClientAPI GatewayConfig ServerAuthAccommodationReservationsMaintenanceFinance
Reservation request pathConfiguration, read by every service
04 /

INTELLIGENCE

AI products and explainable systems.

Two products and a prototype. What they share is that the model is only one part — the harder engineering is in metering expensive work, protecting what users trust you with, and explaining an output after the fact.

personal project

LectureAI

Recorded lectures in, transcripts and generated study material out — behind a subscription platform with credits, cloud uploads and asynchronous GPU processing.

  • Next.js
  • TypeScript
  • PostgreSQL
  • Prisma
  • OpenAI
  • Stripe

Audio / video

Input

A two-hour lecture cannot be processed inside a request, so transcription and generation run asynchronously on GPU infrastructure and the browser is free to close.

Transcript

Transcription

Transcripts are user data. They are stored against the account with audit logs and rate limiting around access.

Generated

AI processing
  • Notes
  • Quiz
  • Study material

Metered by a credit system, so the expensive work is accounted for exactly once per job.

LectureAI
Capture pending

Best asset for this section: a short silent screen recording (15–25s, muted, looping) of upload → transcript → generated notes. Prefer MP4 (H.264) plus a JPG poster frame.

/projects/lecture-ai/walkthrough.mp4

personal project

Transcriber

The same problem without the platform: a desktop tool that transcribes video in batches, on the GPU when there is one and on the CPU when there is not.

  • Python
  • PySide6
  • faster-whisper
  • FFmpeg
  • 01Batch video transcription
  • 02GPU-accelerated Whisper inference with automatic CPU fallback
  • 03Keyword detection across transcripts
  • 04Video preview alongside the transcript
  • 05TXT, SRT and JSON export
  • 06Standalone Windows builds via PyInstaller

Pipeline

  1. Video
  2. FFmpeg
  3. faster-whisper
  4. TXT · SRT · JSON
Transcriber
Transcriber desktop window with video preview and transcript

prototype · 1st Honorable Mention · BIO4AI Hackathon, BelBI 2026

PGxAI Clinical Engine

An explainable pharmacogenomics engine that ranks antidepressant suitability from genotype and clinical context, and shows which factors produced each result.

  • Rule engine
  • Pharmacogenomics
  • Explainability

Genes the engine reasons over

  • CYP2D6

    Highly polymorphic; metabolizer status shifts exposure for many antidepressants.

  • CYP2C19

    Drives clearance for several SSRIs, so genotype changes the effective dose.

  • CYP2B6

    Relevant for a narrower set of agents, with correspondingly lower evidence weight.

A ranking you can argue with

Pharmacogenomic reasoning does not reduce cleanly to a number. Metabolizer status interacts with concurrent medications through phenoconversion, evidence strength varies by gene–drug pair, and two rules can point in opposite directions.

So the engine keeps each contribution separate, with its provenance, and generates the explanation from the same structure that produced the order. A clinician can disagree with the reasoning rather than with a score.

Verified capabilities

  • 01Evaluates 18 antidepressants against a structured patient profile
  • 02Models CYP2D6, CYP2C19 and CYP2B6 metabolizer status
  • 03Phenoconversion from concurrent medications
  • 04Drug interaction and safety risk modelling
  • 05Evidence confidence attached to each contribution
  • 06Transparent ranking with per-factor explanation
  • 07Pharmacogenomic data processing pipeline
  • 08Rule validation and testing pipelines
  • 09Evidence provenance tracking
PGxAI reasoning pathFive kinds of input — genetics, current medications, clinical risk factors, treatment history and patient preferences — feed a rule engine. The engine produces a ranking of medication options, and an explanation of which factors influenced each result.GeneticsMedicationsRisk factorsTreatment historyPreferencesRule engineRanked optionsExplanation18 antidepressants
  • Metabolism
  • Phenoconversion
  • Interactions
  • Safety risk
  • Evidence confidence
A decision-support prototype built for a hackathon. It is not a diagnostic tool, it has not been clinically validated, and it has not been deployed in a care setting.
05 /

GRAPHICS & GAMES

Real-time rendering and interactive software.

Three games at different distances from the metal: a turn-based RPG with its rules on a Spring Boot backend, then two OpenGL worlds built around the render loop itself.

competition entry · Nordeus Challenge 2026

Monster Trial

A turn-based boss rush where each boss has a weakness and its own mechanics, so a fight is read and adapted to rather than out-scaled.

  • React
  • Vite
  • Java 17
  • Spring Boot
  • 01Hero creation and progression
  • 02Skills and equipment systems
  • 03Strategic turn-based combat
  • 04Bosses with unique weaknesses
  • 05Boss-specific mechanics

Stack

  1. React + Vite
  2. REST
  3. Spring Boot
  4. Combat rules
Monster Trial
Capture pending

Gameplay capture of one boss encounter, silent and looping. This section is built around a large cinematic frame, so this is the asset that carries it.

/projects/monster-trial/gameplay.mp4

Hero and equipment
Screenshot pending

Still of hero creation or the equipment screen. Also used as the reduced-motion fallback.

/projects/monster-trial/hero.png

OpenGL lab / two render paths

One API. Two different worlds.

A networked 3D space and a 2D horror game share the same low-level graphics foundation. Choose a render path to inspect the project.

Active render path3D / networked

Real-time 3D first-person multiplayer application written in C with OpenGL and GLSL, networked over UDP sockets.

  • Real-time 3D rendering with OpenGL and GLSL
  • First-person camera and input handling via GLFW
  • Multiplayer synchronisation over UDP sockets
COpenGLGLSLGLFWUDP
View project
3D Multiplayer / live capture
Dimension3D
PipelineOpenGL
ShadersGLSL
About

Software Engineering student, working from the machine upward.

Software Engineering student at Računarski Fakultet Beograd, working across systems programming, backend engineering, GPU computing, concurrency, full-stack platforms and real-time graphics.

The projects on this site are the ones I learned the most from: a concurrent build scheduler written from its thread pool up, a programming language front end, CUDA kernels for a diffusion simulation, a university information system for a real client, and an explainable clinical decision-support prototype.

I am looking for engineering internships where the hard part is the system, not the screen.

Programme
Bachelor's Degree in Software Engineering
University
Računarski Fakultet Beograd
Graduation
Expected 2027
Based in
Belgrade, Serbia
Looking for
Engineering internships
InterestsSoftware engineeringBackend systemsSystems programmingConcurrent programmingGPU computingAI-powered productsScalable applicationsGraphics and games
Stack
LanguagesJavaPythonCC++TypeScriptJavaScriptSQL

SYSTEMS

Where the work is closest to the machine.

  • C
  • C++
  • Python
  • CUDA
  • Multithreading
  • Synchronization
  • Thread pools
  • Data structures & algorithms

BACKEND

Domain modelling, transactions, and service boundaries.

  • Java
  • Spring Boot
  • REST APIs
  • JPA
  • Hibernate
  • MySQL
  • PostgreSQL
  • Microservices
  • Client–server architecture

PRODUCT

The surface users actually touch.

  • React
  • TypeScript
  • Next.js
  • JavaScript

INFRASTRUCTURE & QUALITY

How the work stays correct once it leaves my machine.

  • Docker
  • GitHub Actions
  • JUnit
  • Testcontainers
  • Playwright
  • Vitest
  • Integration testing
  • End-to-end testing
  • API contract testing
Contact

Let’s build something that has to work.

I am looking for engineering internships where the hard part is the system. Backend, infrastructure, systems programming, GPU work — or something adjacent that I have not thought of yet.

Računarski Fakultet Beograd

Bachelor's Degree in Software Engineering · Expected 2027