Skip to content

Answers

1. What is a JAVA thread?

A Java thread is a lightweight unit of execution inside a process. Multiple threads run concurrently, sharing the same memory of the process.

2. Explain Java threads with code

java
class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) System.out.println("Thread: " + i);
    }
}
public class Main {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
        for (int i = 1; i <= 5; i++) System.out.println("Main: " + i);
    }
}

3. Draw and explain the thread life cycle with a diagram

text
                ┌──────────────┐
                │     NEW      │
                └──────┬───────┘
                       │  start()

                ┌──────────────┐
                │   RUNNABLE   │
                └──┬────┬──────┘
     scheduled     │    │  acquires CPU
        ▲          │    ▼
        │       ┌──────────────┐
        │       │   RUNNING    │
        │       └───┬───┬──────┘
        │   run()   │   │  run() ends / error
        │   again   │   ▼
        │           │ ┌──────────────┐
        │           │ │ TERMINATED   │
        │           │ └──────────────┘
        │           │
        │   wait()/sleep()/join()
        │           ▼
        │   ┌──────────────┐
        │   │ WAITING /    │
        │   │ TIMED_WAITING│
        │   └──────┬───────┘
        │      notify()/timeout
        │          │
        │          ▼
        │      ┌──────────────┐
        └──────┤   RUNNABLE   │
               └──────────────┘

                 blocked for lock
        RUNNABLE ─────────────────► BLOCKED ── lock released ──► RUNNABLE
  • NEW: created but not started
  • RUNNABLE: ready to run (waiting for CPU)
  • RUNNING: executing run()
  • BLOCKED: waiting for monitor lock
  • WAITING/TIMED_WAITING: waiting (optionally with timeout)
  • TERMINATED: finished execution

4. 3x3 matrix addition C = A + B

java
import java.util.Scanner;

public class MatrixAdd3x3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[][] A = new int[3][3];
        int[][] B = new int[3][3];
        int[][] C = new int[3][3];

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                A[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                B[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                C[i][j] = A[i][j] + B[i][j];

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) System.out.print(C[i][j] + " ");
            System.out.println();
        }
        sc.close();
    }
}

5. 3x3 matrix multiplication C = A * B

java
import java.util.Scanner;

public class MatrixMul3x3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[][] A = new int[3][3];
        int[][] B = new int[3][3];
        int[][] C = new int[3][3];

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                A[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                B[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int sum = 0;
                for (int k = 0; k < 3; k++) sum += A[i][k] * B[k][j];
                C[i][j] = sum;
            }
        }

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) System.out.print(C[i][j] + " ");
            System.out.println();
        }
        sc.close();
    }
}

6. 3x3 matrix subtraction C = A - B

java
import java.util.Scanner;

public class MatrixSub3x3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[][] A = new int[3][3];
        int[][] B = new int[3][3];
        int[][] C = new int[3][3];

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                A[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                B[i][j] = sc.nextInt();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                C[i][j] = A[i][j] - B[i][j];

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) System.out.print(C[i][j] + " ");
            System.out.println();
        }
        sc.close();
    }
}

7. Modify the program to handle errors using exception handling

SafeDivide (handle division by zero + input mismatch)

java
import java.util.Scanner;

public class SafeDivide {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        try {
            System.out.print("Enter numerator: ");
            int n = sc.nextInt();
            System.out.print("Enter denominator: ");
            int d = sc.nextInt();
            System.out.println("Quotient: " + (n / d));
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero.");
        } catch (java.util.InputMismatchException e) {
            System.out.println("Error: Please enter integers only.");
        } finally {
            sc.close();
        }
    }
}

ArrayAccessTest (handle out of range + input mismatch)

java
import java.util.Scanner;

public class ArrayAccessTest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] arr = {70, 10, 20, 30, 50};
        try {
            System.out.print("Enter an index (0-4): ");
            int idx = sc.nextInt();
            System.out.println("Value: " + arr[idx]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Error: Index must be between 0 and 4.");
        } catch (java.util.InputMismatchException e) {
            System.out.println("Error: Please enter a valid integer index.");
        } finally {
            sc.close();
        }
    }
}

FileReadTest (handle file not found + other errors)

java
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileReadTest {
    public static void main(String[] args) {
        Scanner fileScanner = null;
        try {
            File f = new File("data.txt");
            fileScanner = new Scanner(f);
            while (fileScanner.hasNextLine()) {
                System.out.println(fileScanner.nextLine());
            }
        } catch (FileNotFoundException e) {
            System.out.println("Error: data.txt not found.");
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        } finally {
            if (fileScanner != null) fileScanner.close();
        }
    }
}

8. 7 strings, two threads, 200 ms delay, interleaving, separate task class

java
import java.util.ArrayList;

class StringPrinterTask implements Runnable {
    private final ArrayList<String> list;
    private final int startIndex;

    StringPrinterTask(ArrayList<String> list, int startIndex) {
        this.list = list;
        this.startIndex = startIndex;
    }

    public void run() {
        for (int i = startIndex; i < list.size(); i += 2) {
            System.out.println(Thread.currentThread().getName() + ": " + list.get(i));
            try { Thread.sleep(200); } catch (InterruptedException e) { return; }
        }
    }
}

public class Main8 {
    public static void main(String[] args) {
        ArrayList<String> items = new ArrayList<>();
        items.add("A"); items.add("B"); items.add("C"); items.add("D");
        items.add("E"); items.add("F"); items.add("G");

        Thread t1 = new Thread(new StringPrinterTask(items, 0), "T1");
        Thread t2 = new Thread(new StringPrinterTask(items, 1), "T2");

        t1.start();
        t2.start();
    }
}

9. 12 characters, one thread vowels, one consonants, skip non-letters, separate thread class

java
import java.util.ArrayList;

class CharFilterPrinter implements Runnable {
    private final ArrayList<Character> list;
    private final boolean vowels;

    CharFilterPrinter(ArrayList<Character> list, boolean vowels) {
        this.list = list;
        this.vowels = vowels;
    }

    private boolean isVowel(char c) {
        c = Character.toLowerCase(c);
        return c=='a' || c=='e' || c=='i' || c=='o' || c=='u';
    }

    public void run() {
        for (char c : list) {
            if (!Character.isLetter(c)) continue;
            boolean v = isVowel(c);
            if (vowels && v) System.out.println("Vowel: " + c);
            if (!vowels && !v) System.out.println("Consonant: " + c);
        }
    }
}

public class Main9 {
    public static void main(String[] args) {
        ArrayList<Character> items = new ArrayList<>();
        items.add('A'); items.add('b'); items.add('c'); items.add('E');
        items.add('x'); items.add('i'); items.add('O'); items.add('t');
        items.add('u'); items.add('Z'); items.add('#'); items.add('m');

        Thread t1 = new Thread(new CharFilterPrinter(items, true));
        Thread t2 = new Thread(new CharFilterPrinter(items, false));

        t1.start();
        t2.start();
    }
}

10. 10 integers, foreach loop, two threads, separate task class

java
import java.util.ArrayList;

class ForeachIntPrinter implements Runnable {
    private final ArrayList<Integer> list;
    private final int mod;

    ForeachIntPrinter(ArrayList<Integer> list, int mod) {
        this.list = list;
        this.mod = mod;
    }

    public void run() {
        int idx = 0;
        for (int x : list) {
            if (idx % 2 == mod) System.out.println(Thread.currentThread().getName() + ": " + x);
            idx++;
        }
    }
}

public class Main10 {
    public static void main(String[] args) {
        ArrayList<Integer> items = new ArrayList<>();
        for (int i = 1; i <= 10; i++) items.add(i);

        Thread t1 = new Thread(new ForeachIntPrinter(items, 0), "T1");
        Thread t2 = new Thread(new ForeachIntPrinter(items, 1), "T2");

        t1.start();
        t2.start();
    }
}

11. Exam table SQL + JSP insert + 3 threads print multiples of 2/3/5 up to X

Oracle SQL

sql
CREATE TABLE Exam (
  ExamID NUMBER PRIMARY KEY,
  CourseCode VARCHAR2(20),
  ExamDate DATE,
  DurationMinutes NUMBER CHECK (DurationMinutes > 0),
  Venue VARCHAR2(50)
);

JSP execution code (insert + handle SQL exceptions)

sql
<%@ page import="java.sql.*" %>
<%
Connection con = null;
PreparedStatement ps = null;

try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
    con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "USERNAME", "PASSWORD");

    String sql = "INSERT INTO Exam (ExamID, CourseCode, ExamDate, DurationMinutes, Venue) VALUES (?, ?, ?, ?, ?)";
    ps = con.prepareStatement(sql);

    ps.setInt(1, Integer.parseInt(request.getParameter("ExamID")));
    ps.setString(2, request.getParameter("CourseCode"));
    ps.setDate(3, java.sql.Date.valueOf(request.getParameter("ExamDate")));
    ps.setInt(4, Integer.parseInt(request.getParameter("DurationMinutes")));
    ps.setString(5, request.getParameter("Venue"));

    ps.executeUpdate();
    out.println("Inserted successfully");
} catch (SQLException e) {
    out.println("SQL Error: " + e.getMessage());
} catch (Exception e) {
    out.println("Error: " + e.getMessage());
} finally {
    try { if (ps != null) ps.close(); } catch (Exception e) {}
    try { if (con != null) con.close(); } catch (Exception e) {}
}
%>

Java OOP + 3 threads (multiples of 2,3,5 up to X)

java
class MultiPrinter implements Runnable {
    private final int x;
    private final int m;

    MultiPrinter(int x, int m) {
        this.x = x;
        this.m = m;
    }

    public void run() {
        for (int i = 1; i <= x; i++) {
            if (i % m == 0) System.out.println("M" + m + ": " + i);
        }
    }
}

public class Main11 {
    public static void main(String[] args) {
        int X = 123;
        Thread t2 = new Thread(new MultiPrinter(X, 2));
        Thread t3 = new Thread(new MultiPrinter(X, 3));
        Thread t5 = new Thread(new MultiPrinter(X, 5));
        t2.start(); t3.start(); t5.start();
    }
}

12. Teacher table SQL + JSP select by department + 3 threads print odd numbers up to X

Oracle SQL

sql
CREATE TABLE Teacher (
  TeacherID NUMBER PRIMARY KEY,
  Name VARCHAR2(50),
  Email VARCHAR2(100) UNIQUE,
  Department VARCHAR2(50),
  Contact VARCHAR2(30)
);

JSP execution code (select + display by department using PreparedStatement)

sql
<%@ page import="java.sql.*" %>
<%
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
    con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "USERNAME", "PASSWORD");

    String dept = request.getParameter("Department");
    ps = con.prepareStatement("SELECT TeacherID, Name, Email, Department, Contact FROM Teacher WHERE Department = ?");
    ps.setString(1, dept);

    rs = ps.executeQuery();
    while (rs.next()) {
        out.println(rs.getInt("TeacherID") + " " + rs.getString("Name") + " " + rs.getString("Email") + "<br/>");
    }
} catch (SQLException e) {
    out.println("SQL Error: " + e.getMessage());
} catch (Exception e) {
    out.println("Error: " + e.getMessage());
} finally {
    try { if (rs != null) rs.close(); } catch (Exception e) {}
    try { if (ps != null) ps.close(); } catch (Exception e) {}
    try { if (con != null) con.close(); } catch (Exception e) {}
}
%>

Java OOP + 3 threads (odd numbers 1..X)

java
class OddRange implements Runnable {
    private final int x;
    OddRange(int x) { this.x = x; }

    public void run() {
        for (int i = 1; i <= x; i += 2) System.out.println(Thread.currentThread().getName() + ": " + i);
    }
}

public class Main12 {
    public static void main(String[] args) {
        int X = 123;
        Thread t1 = new Thread(new OddRange(X), "Odd-1");
        Thread t2 = new Thread(new OddRange(X), "Odd-2");
        Thread t3 = new Thread(new OddRange(X), "Odd-3");
        t1.start(); t2.start(); t3.start();
    }
}

13. Employee table SQL + JSP update salary by EmpID + 3 threads print primes 1..X

Oracle SQL

sql
CREATE TABLE Employee (
  EmpID NUMBER PRIMARY KEY,
  EmpName VARCHAR2(50),
  Salary NUMBER NOT NULL,
  Designation VARCHAR2(50),
  Phone VARCHAR2(30)
);

JSP execution code (update salary by EmpID)

sql
<%@ page import="java.sql.*" %>
<%
Connection con = null;
PreparedStatement ps = null;

try {
    Class.forName("oracle.jdbc.driver.OracleDriver");
    con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "USERNAME", "PASSWORD");

    int empId = Integer.parseInt(request.getParameter("EmpID"));
    double salary = Double.parseDouble(request.getParameter("Salary"));

    ps = con.prepareStatement("UPDATE Employee SET Salary = ? WHERE EmpID = ?");
    ps.setDouble(1, salary);
    ps.setInt(2, empId);

    int rows = ps.executeUpdate();
    out.println("Updated rows: " + rows);
} catch (SQLException e) {
    out.println("SQL Error: " + e.getMessage());
} catch (Exception e) {
    out.println("Error: " + e.getMessage());
} finally {
    try { if (ps != null) ps.close(); } catch (Exception e) {}
    try { if (con != null) con.close(); } catch (Exception e) {}
}
%>

Java OOP + 3 threads (prime numbers 1..X)

java
class PrimePrinter implements Runnable {
    private final int x;
    private final int mod;
    PrimePrinter(int x, int mod) { this.x = x; this.mod = mod; }

    private boolean isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; i++) if (n % i == 0) return false;
        return true;
    }

    public void run() {
        for (int i = 2; i <= x; i++) {
            if (isPrime(i) && i % 3 == mod) System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
}

public class Main13 {
    public static void main(String[] args) {
        int X = 123;
        Thread t1 = new Thread(new PrimePrinter(X, 0), "P0");
        Thread t2 = new Thread(new PrimePrinter(X, 1), "P1");
        Thread t3 = new Thread(new PrimePrinter(X, 2), "P2");
        t1.start(); t2.start(); t3.start();
    }
}

14. Course + subclasses + interface, enroll and calculate score

java
interface AssessmentPolicy {
    double calculateScore(int totalMarks, int obtainedMarks);
}

class Course {
    private String courseId, courseName, instructor;
    private boolean isAvailable;

    Course(String courseId, String courseName, String instructor, boolean isAvailable) {
        this.courseId = courseId;
        this.courseName = courseName;
        this.instructor = instructor;
        this.isAvailable = isAvailable;
    }

    public String getCourseId() { return courseId; }
    public String getCourseName() { return courseName; }
    public String getInstructor() { return instructor; }
    public boolean isAvailable() { return isAvailable; }

    public void enrollStudent() { isAvailable = false; }
}

class VideoCourse extends Course implements AssessmentPolicy {
    VideoCourse(String id, String name, String instructor, boolean available) {
        super(id, name, instructor, available);
    }

    public double calculateScore(int totalMarks, int obtainedMarks) {
        return (obtainedMarks * 100.0) / totalMarks;
    }
}

class TextCourse extends Course implements AssessmentPolicy {
    TextCourse(String id, String name, String instructor, boolean available) {
        super(id, name, instructor, available);
    }

    public double calculateScore(int totalMarks, int obtainedMarks) {
        double base = (obtainedMarks * 100.0) / totalMarks;
        return base + (base * 0.05);
    }
}

public class CourseSystem {
    public static void main(String[] args) {
        VideoCourse vc = new VideoCourse("C1", "Java", "Sir", true);
        TextCourse tc = new TextCourse("C2", "OOP", "Maam", true);

        vc.enrollStudent();
        tc.enrollStudent();

        System.out.println(vc.calculateScore(100, 80));
        System.out.println(tc.calculateScore(100, 80));
    }
}

15. Bank Account system + interface + exception handling

java
class InsufficientFundsException extends Exception {
    InsufficientFundsException(String msg) { super(msg); }
}

interface Transaction {
    void performTransaction(double amount);
}

class Account {
    private String accountNo;
    private String accountHolder;
    private double balance;

    Account(String accountNo, String accountHolder, double balance) {
        this.accountNo = accountNo;
        this.accountHolder = accountHolder;
        this.balance = balance;
    }

    public String getAccountNo() { return accountNo; }
    public String getAccountHolder() { return accountHolder; }
    public double getBalance() { return balance; }

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    protected void withdraw(double amount) throws InsufficientFundsException {
        if (amount <= 0) return;
        if (amount > balance) throw new InsufficientFundsException("Insufficient funds.");
        balance -= amount;
    }

    public void displayInfo() {
        System.out.println(accountNo + " " + accountHolder);
    }
}

class SavingsAccount extends Account implements Transaction {
    SavingsAccount(String no, String holder, double bal) { super(no, holder, bal); }

    public void displayInfo() {
        System.out.println("Savings: " + getAccountNo() + " " + getAccountHolder());
    }

    public void performTransaction(double amount) {
        try {
            withdraw(amount);
            System.out.println("Withdrawn: " + amount);
        } catch (InsufficientFundsException e) {
            System.out.println("Error: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Error: Arithmetic issue.");
        }
    }
}

class CheckingAccount extends Account implements Transaction {
    CheckingAccount(String no, String holder, double bal) { super(no, holder, bal); }

    public void displayInfo() {
        System.out.println("Checking: " + getAccountNo() + " " + getAccountHolder());
    }

    public void performTransaction(double amount) {
        try {
            withdraw(amount);
            System.out.println("Withdrawn: " + amount);
        } catch (InsufficientFundsException e) {
            System.out.println("Error: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Error: Arithmetic issue.");
        }
    }
}

public class BankSystem {
    public static void main(String[] args) {
        SavingsAccount s = new SavingsAccount("S-1", "A", 500);
        CheckingAccount c = new CheckingAccount("C-1", "B", 200);

        s.displayInfo();
        s.performTransaction(600);

        c.displayInfo();
        c.performTransaction(100);
    }
}

16. Course Enrollment system + interface + exception handling

java
interface EnrollmentPolicy {
    void register();
}

class Course {
    private String courseId, courseName;
    private int maxSeats;
    private int enrolledStudents;

    Course(String courseId, String courseName, int maxSeats, int enrolledStudents) {
        this.courseId = courseId;
        this.courseName = courseName;
        this.maxSeats = maxSeats;
        this.enrolledStudents = enrolledStudents;
    }

    public String getCourseId() { return courseId; }
    public String getCourseName() { return courseName; }
    public int getMaxSeats() { return maxSeats; }
    public int getEnrolledStudents() { return enrolledStudents; }

    public void enrollStudent() { enrolledStudents++; }

    protected void safeEnroll() {
        if (enrolledStudents >= maxSeats) throw new IllegalStateException("Course is full.");
        enrollStudent();
    }

    public void displayInfo() {
        System.out.println(courseId + " " + courseName);
    }
}

class OnlineCourse extends Course implements EnrollmentPolicy {
    OnlineCourse(String id, String name, int max, int enrolled) { super(id, name, max, enrolled); }

    public void displayInfo() { System.out.println("Online: " + getCourseId() + " " + getCourseName()); }

    public void register() {
        try {
            safeEnroll();
            System.out.println("Registered");
        } catch (IllegalStateException e) {
            System.out.println("Error: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Error: Arithmetic issue.");
        }
    }
}

class OfflineCourse extends Course implements EnrollmentPolicy {
    OfflineCourse(String id, String name, int max, int enrolled) { super(id, name, max, enrolled); }

    public void displayInfo() { System.out.println("Offline: " + getCourseId() + " " + getCourseName()); }

    public void register() {
        try {
            safeEnroll();
            System.out.println("Registered");
        } catch (IllegalStateException e) {
            System.out.println("Error: " + e.getMessage());
        } catch (ArithmeticException e) {
            System.out.println("Error: Arithmetic issue.");
        }
    }
}

public class CourseSystem16 {
    public static void main(String[] args) {
        OnlineCourse o = new OnlineCourse("OC1", "Web", 1, 1);
        OfflineCourse f = new OfflineCourse("FC1", "Lab", 2, 0);

        o.displayInfo();
        o.register();

        f.displayInfo();
        f.register();
    }
}

17. Two threads (Thread class): Fibonacci 10 + prime 10

java
class FibThread extends Thread {
    public void run() {
        int a = 0, b = 1;
        for (int i = 1; i <= 10; i++) {
            System.out.println("Fib: " + a);
            int c = a + b;
            a = b;
            b = c;
        }
    }
}

class PrimeThread extends Thread {
    private boolean isPrime(int n) {
        if (n < 2) return false;
        for (int i = 2; i * i <= n; i++) if (n % i == 0) return false;
        return true;
    }

    public void run() {
        int count = 0;
        int n = 2;
        while (count < 10) {
            if (isPrime(n)) {
                System.out.println("Prime: " + n);
                count++;
            }
            n++;
        }
    }
}

public class Main17 {
    public static void main(String[] args) {
        new FibThread().start();
        new PrimeThread().start();
    }
}

18. Two threads (Runnable): evens 2–20 and odds 1–19

java
class EvenRunnable implements Runnable {
    public void run() {
        for (int i = 2; i <= 20; i += 2) System.out.println("Even: " + i);
    }
}

class OddRunnable implements Runnable {
    public void run() {
        for (int i = 1; i <= 19; i += 2) System.out.println("Odd: " + i);
    }
}

public class Main18 {
    public static void main(String[] args) {
        new Thread(new EvenRunnable()).start();
        new Thread(new OddRunnable()).start();
    }
}

19. Two threads: numbers 1–5 and letters A–E

java
class NumTask implements Runnable {
    public void run() {
        for (int i = 1; i <= 5; i++) System.out.println("Num: " + i);
    }
}

class LetterTask implements Runnable {
    public void run() {
        for (char c = 'A'; c <= 'E'; c++) System.out.println("Char: " + c);
    }
}

public class Main19 {
    public static void main(String[] args) {
        new Thread(new NumTask()).start();
        new Thread(new LetterTask()).start();
    }
}

Educational resources for IUS students.