← back

Teaching

Undergraduate Course Overview

This undergraduate Software Engineering course introduces students to fundamental software development practices and team-based engineering workflows. Students learn requirements and user stories, UML-based system modeling, and software architecture, then apply these concepts through iterative implementation, testing, and refactoring. The course emphasizes version control with Git, code reviews, and continuous integration, helping students develop professional habits for building maintainable systems. Through projects, students practice design patterns, layered architectures, and quality assurance, gaining hands-on experience that connects core engineering principles to real-world development.

more

Graduate Course Overview

An advanced Software Engineering course focuses on the construction of developer tools, program analysis, and the integration of generative AI into IDE environments. The curriculum grounds students in the design of plugin-based systems, specifically building Visual Studio Code extensions using TypeScript and event-driven architectures. A core component involves deep static analysis, where we utilize frameworks like JavaParser and Tree-sitter to implement Abstract Syntax Tree (AST) visitors for structural extraction, semantic symbol binding, and interprocedural data flow analysis (def-use chains). The course culminates in Code Intelligence, bridging these traditional techniques with Large Language Models (LLMs) to build intelligent tools. We deconstruct the Transformer architecture, clarifying how Self-Attention ensures syntactic consistency (e.g., maintaining variable scope) and Cross-Attention leverages input context to generate relevant suggestions. Students explore pre-training objectives like MASS (Masked Sequence-to-Sequence) to understand how models learn code structure from massive corpora, and apply fine-tuning strategies to specialize models for tasks like code completion. Finally, we implement practical solutions that synchronize local static context (extracted via ASTs) with remote AI inference, providing hands-on experience in engineering the next generation of context-aware development tools.

In the research paper discussion session, students critically analyzed the evolution of AI-assisted software engineering, tracing its development from early neural models to modern LLM-based agents. The discussion was structured around four major research tracks. First, students examined the foundations of neural code models, focusing on the shift from general NLP to code-specific pre-training through seminal works such as CodeBERT, CodeT5, and UniXcoder. These studies demonstrated how bimodal pre-training (code and natural language) and AST-aware architectures enable models to capture syntactic structure. Second, the session explored code completion and generation, comparing early sequence-based models with recent Retrieval-Augmented Generation (RAG) approaches, while debating the industrial trade-offs between fine-tuning and RAG and considering efficiency improvements like memory-efficient completion. Third, students reviewed automated program repair and debugging, ranging from test-suite-based repair to self-planning code generation where LLMs iteratively refine their outputs, alongside neural repair using syntax-guided decoders. Finally, the discussion addressed security, trust, and evaluation, analyzing risks such as poisoned models (e.g., Poisoned ChatGPT), assessing LLM calibration, and examining limitations in manual annotation and code generation errors, offering a realistic perspective on the challenges of AI-assisted engineering.