Ada Interview Questions with Answers
Most Asked Ada Interview Questions for Software Engineer Roles
Introduction
Ada is a structured, statically typed, high‑level programming language designed for reliability, safety, and maintainability. Originally developed for the U.S. Department of Defense, it is now widely used in aerospace, defence, railway, medical devices, and other safety‑critical systems where correctness and predictability are paramount. This comprehensive guide collects the most frequently asked Ada interview questions – from fundamental concepts like packages, tasks, and strong typing to advanced topics such as the Ravenscar profile, SPARK formal verification, contract‑based programming, and real‑time concurrency. Whether you are a student, an embedded developer, or preparing for a specialised role, these questions will help you deepen your understanding and succeed in your next interview.
Why Ada?
- Safety‑critical – designed for reliability and formal verification
- Strong static typing – catches errors at compile time
- Built‑in concurrency – tasks, protected objects, rendezvous
- Real‑time support – precise scheduling, priority handling
- SPARK integration – formal verification of correctness
- Widely used in aerospace, defence, and industrial systems
Most Asked Ada Interview Questions
Ada is a structured, statically typed, high-level programming language designed for reliability and safety-critical systems. It features built-in support for design-by-contract, strong typing, and concurrent real-time execution.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
begin
Put_Line("Hello, World!");
end Main;Ada was developed by the U.S. Department of Defense (DoD) in the late 1970s to replace the hundreds of disparate programming languages then in use within military systems. It was named after Ada Lovelace, often credited as the first computer programmer.
Because of its uncompromising features: strong static typing, compile‑time checks,safe pointer interfaces, and built‑in concurrency support. It heavily minimises the occurrence of runtime system vulnerabilities, crashes, and undefined behaviours.
Strong typing in Ada means the compiler enforces strict differentiation between types. For example, you cannot accidentally add an integer measuring Speed to an integer measuring Distancewithout explicit conversions, preventing logical programming mistakes.
A package is the fundamental modular unit in Ada used for grouping logically related declarations and implementations together. It consists of a specification file (interface) and a body file (implementation), ensuring clean encapsulation.
A procedure is a subprogram in Ada that executes an action but does not return a value. It can communicate inputs and outputs to calling blocks using parameters marked with modes: in,out, or in out.
A function is a subprogram in Ada that performs computations and must return a single value of a specified type using a return statement.
In Ada, variables are declared using the pattern: Variable_Name : Type_Name := Initial_Value;
-- Declaration
X : Integer := 10;Constants are declared by adding the constant keyword right after the colon delimiter, which guarantees they cannot be modified after compilation.
Pi : constant Float := 3.14;An if statement checks condition states and ends explicitly with an end if; statement.
if X > 0 then
Put_Line("Positive");
end if;Loops in Ada can be controlled using standard ranges or index iterations. Numeric attributes can be formatted as output text using the 'Image attribute.
for I in 1..10 loop
Put_Line(Integer'Image(I));
end loop;Arrays explicitly define their boundary conditions during creation (e.g., indexes 1 to 5).
type My_Array is array (1..5) of Integer;
A : My_Array;A record allows programmers to group elements of varying types together into a cohesive custom type definition, similar to a struct in C.
type Person is record
Name : String(1..20);
Age : Integer;
end record;Ada handles runtime exception boundaries using structured blocks, stopping failures from destabilising complex critical environments.
begin
-- Potentially unsafe operation
X := Y / Z;
exception
when Constraint_Error =>
Put_Line("Division by zero or overflow!");
end;The program's entry execution context starts within a standard procedure mapped directly as the main system loop configuration block.
procedure Main is
begin
Put_Line("Main entry execution");
end Main;A task is an active concurrent execution thread managed directly by Ada's compiler and runtime platform layer, enabling native, portable multi-threading support.
task type Worker is
entry Start;
end Worker;
task body Worker is
begin
accept Start;
Put_Line("Task is running concurrently.");
end Worker;A rendezvous is Ada's fundamental synchronization mechanism, allowing safe data exchanges and thread coordination when multiple tasks meet.
accept Start do
-- Synchronized mutual-exclusion zone
Put_Line("Rendezvous active");
end Start;Generic components are templates parameterized with types, subprograms, or values, facilitating compilation-level type-safe code reuse.
generic
type Element is private;
procedure Swap(A, B : in out Element);A subtype defines a subset of an existing base type's values without instantiating a completely new distinct type category.
subtype Positive_Integer is Integer range 1 .. Integer'Last;Access types are type-safe pointer alternatives in Ada used to securely allocate and dereference memory addresses dynamically.
type Int_Ptr is access Integer;
My_Ptr : Int_Ptr;A tagged type enables object-oriented programming (OOP) paradigms in Ada, acting as a className base to support dynamic dispatching and inheritance.
type Instrument is tagged record
ID : Integer;
Name : String(1..10);
end record;A protected object provides coordinated lock synchronization, encapsulating data and locking thread entries automatically for concurrent access.
protected body Semaphore is
entry Wait when Count > 0 is
begin
Count := Count - 1;
end Wait;
procedure Signal is
begin
Count := Count + 1;
end Signal;
end Semaphore;Ada allows overloading, enabling multiple subprograms to declare identical names provided their signature parameters vary.
procedure Display(Item : Integer);
procedure Display(Item : Float);Recursion occurs when subprograms execute self-calls recursively to partition mathematical problems into manageable chunks.
procedure Recursive_Print (N : Positive) is
begin
if N > 0 then
Recursive_Print (N - 1);
Put_Line (Integer'Image (N));
end if;
end Recursive_Print;A pragma is a compiler directive used to configure optimisations, constraints, calling profiles, or target behaviours directly.
pragma Optimize(Time);Range constraints restrict variable domains dynamically, catching overflow logic errors automatically via runtime type-checking engines.
procedure Test is
type Small is range -10 .. 10;
X : Small;
begin
X := 5;
end Test;Memory allocations are safely structured using pointer constructors inside active heap spaces.
type Int_Ptr is access Integer;
My_Ptr : Int_Ptr;Discriminated records function similarly to variant records, altering structural properties based on dynamic discriminant variables.
type Buffer(Size : Positive) is record
Data : String(1 .. Size);
end record;Task entries establish structured communication interfaces to accept parameter payloads safely across thread boundaries.
task Server is
entry Get_Status(Code : out Integer);
end Server;Delay statements yield task executions temporarily, pausing threads for precise durations.
delay 2.5; -- Pause task execution for 2.5 secondsAda provides native, deterministic scheduling models, priority‑inversion controls, and clock systems vital for high‑reliability embedded targets.
pragma Priority(Interrupt_Priority'Last);The Ravenscar Profile is a specialised tasking subset that guarantees deterministic, analysable, and safety‑certifiable real‑time concurrency.
pragma Profile(Ravenscar);Contract‑based programming leverages Pre (preconditions) and Post (postconditions) aspects to mathematically verify subprogram correct states at boundaries.
procedure Deposit(Amount : Positive)
with Pre => Amount > 0,
Post => Balance = Balance'Old + Amount;SPARK is a specialised language subset and formal verification toolset. It mathematically proves the absence of runtime errors (like division by zero or buffer overflows) and verifies correctness.
procedure Safety_Critical_Process
with SPARK_Mode => On;An enumeration type defines a set of named values, providing clear and type‑safe representation of symbolic constants.
type Color is (Red, Green, Blue);A simple procedure that prints a string.
procedure Print (S : String) is
begin
Put_Line(S);
end Print;A function that returns the sum of two integers.
function Add (A, B : Integer) return Integer is
begin
return A + B;
end Add;A package specification declares the public interface of a package, including types, subprograms, and constants.
package Stack is
procedure Push (Item : Integer);
function Pop return Integer;
end Stack;A package body contains the implementation of the subprograms and data declared in the package specification.
package body Stack is
...
end Stack;A case statement selects one of several alternatives based on the value of an expression.
case X is
when 1 => Put_Line("One");
when 2 => Put_Line("Two");
when others => Put_Line("Other");
end case;A while loop executes a sequence of statements repeatedly while a condition is true.
while X > 0 loop
X := X - 1;
end loop;Defining an enumeration type for fruits.
type My_Enum is (Apple, Banana, Orange);A 2D array is declared using two dimensions in the array type definition.
type My_Array_2D is array (1..3, 1..3) of Integer;A fixed-length string is defined as an array of characters with a specific length.
type My_String is String (1..10);access all allows a pointer to refer to any object of the designated type, including unconstrained arrays.
type My_Access is access all Integer;A tagged null record is the simplest form of a tagged type, serving as a root for inheritance hierarchies.
type My_Tagged is tagged null record;A semaphore can be built with a protected object having an entry and a procedure to manage counting.
protected type Semaphore is
entry Wait;
procedure Signal;
private
Count : Natural := 0;
end Semaphore;The protected body contains the implementation of its entries, functions, and procedures.
protected body Semaphore is
entry Wait when Count > 0 is
begin
Count := Count - 1;
end Wait;
procedure Signal is
begin
Count := Count + 1;
end Signal;
end Semaphore;A function that returns the square of an integer.
function Square (X : Integer) return Integer is
begin
return X * X;
end Square;A recursive procedure that prints numbers from 1 to N using recursion.
procedure Recursive_Print (N : Positive) is
begin
if N > 0 then
Recursive_Print (N - 1);
Put_Line (Integer'Image (N));
end if;
end Recursive_Print;pragma Inline suggests the compiler to expand the subprogram inline for performance.
pragma Inline (Square);pragma Preelaborate ensures a package can be elaborated before any other code, useful for high‑integrity systems.
pragma Preelaborate (My_Package);pragma Restrictions disallows certain language features (e.g., tasking) to enforce a simpler, more predictable runtime.
pragma Restrictions (No_Tasking);Defining a type that can only hold values between -10 and 10.
procedure Test is
type Small is range -10 .. 10;
X : Small;
begin
X := 5;
end Test;A variant record (discriminated record) uses a discriminant to select between different record layouts.
type Rec (D : Boolean) is record
case D is
when True => I : Integer;
when False => F : Float;
end case;
end record;Tasks can be declared as separate task objects or as an array of tasks.
task T1;
task T2;
-- ...A select statement allows a task to choose between multiple entry calls or conditional accepts.
select
accept Entry1;
...
or
accept Entry2;
...
end select;A protected object that acts as a bounded buffer with Put and Get entries.
protected type Buffer is
entry Put (Item : Integer);
entry Get (Item : out Integer);
private
Data : Integer;
Empty : Boolean := True;
end Buffer;A function that calculates Base raised to Exp using a simple loop.
function Power (Base : Integer; Exp : Natural) return Integer is
Result : Integer := 1;
begin
for I in 1..Exp loop
Result := Result * Base;
end loop;
return Result;
end Power;A generic package that provides container operations for any element type.
generic
type Element is private;
package Generic_Container is
procedure Insert (Item : Element);
function Lookup (Key : Integer) return Element;
end Generic_Container;Defining a subtype or new type with a specific range.
type My_Integer is range 0 .. 100;Using digits to define the number of decimal digits of precision.
type My_Real is digits 6; -- 6 decimal digitsFixed‑point types are used for decimal arithmetic with a specified delta (smallest representable value).
type My_Fixed is delta 0.01 range -100.0 .. 100.0;Using exponentiation to compute square root.
function Sqrt (X : Float) return Float is
begin
return X ** 0.5;
end Sqrt;Swapping two integer values using a temporary variable.
procedure Swap (A, B : in out Integer) is
Temp : Integer;
begin
Temp := A;
A := B;
B := Temp;
end Swap;Using a representation clause to assign specific integer values to enumeration literals.
type My_Enum is (One, Two, Three);
for My_Enum use (One => 1, Two => 2, Three => 3);A representation clause specifies the exact bit layout of a record, useful for low‑level interfacing.
type My_Record is record
A : Integer;
B : Float;
end record;
for My_Record use record
A at 0 range 0 .. 31;
B at 4 range 0 .. 31;
end record;Enumerating the days of the week.
type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);Using the Day enumeration to determine weekend.
function Is_Weekend (D : Day) return Boolean is
begin
return D = Saturday or D = Sunday;
end Is_Weekend;pragma Assert is used to insert runtime assertions for debugging and verification.
pragma Assert (X > 0, "X must be positive");pragma Debug includes debugging code only when debugging is enabled, avoiding overhead in production.
pragma Debug (Put_Line ("Entering procedure"));A modular type defines an unsigned integer with wrap‑around arithmetic modulo a power of two.
type My_Mod is mod 256;A periodic task that executes at regular intervals using a delay loop.
task body Periodic_Task is
Running : Boolean := True;
begin
accept Start;
while Running loop
delay 1.0;
Put_Line ("Tick");
select
accept Stop;
Running := False;
or
delay 0.0;
end select;
end loop;
end Periodic_Task;Checking if a number is prime using trial division up to sqrt.
function Is_Prime (N : Positive) return Boolean is
Result : Boolean := True;
begin
if N < 2 then
return False;
end if;
for I in 2 .. Natural (Sqrt (Float (N))) loop
if N mod I = 0 then
return False;
end if;
end loop;
return True;
end Is_Prime;Bubble sort algorithm for an integer array.
procedure Sort (Arr : in out Integer_Array) is
Temp : Integer;
begin
for I in Arr'First .. Arr'Last - 1 loop
for J in Arr'First .. Arr'Last - I - 1 loop
if Arr (J) > Arr (J + 1) then
Temp := Arr (J);
Arr (J) := Arr (J + 1);
Arr (J + 1) := Temp;
end if;
end loop;
end loop;
end Sort;Binary search on a sorted integer array.
function Binary_Search (Arr : Integer_Array; Target : Integer) return Integer is
Low : Integer := Arr'First;
High : Integer := Arr'Last;
Mid : Integer;
begin
while Low <= High loop
Mid := (Low + High) / 2;
if Target = Arr (Mid) then
return Mid;
elsif Target < Arr (Mid) then
High := Mid - 1;
else
Low := Mid + 1;
end if;
end loop;
return -1; -- Not found
end Binary_Search;Computing Fibonacci numbers using recursion.
function Fibonacci (N : Natural) return Natural is
begin
if N <= 1 then
return N;
else
return Fibonacci (N - 1) + Fibonacci (N - 2);
end if;
end Fibonacci;Quick sort using recursion and partitioning.
procedure Quick_Sort (Arr : in out Integer_Array; Low, High : Integer) is
Pivot : Integer;
I, J : Integer;
begin
if Low < High then
Pivot := Arr (High);
I := Low;
for J in Low .. High - 1 loop
if Arr (J) < Pivot then
Swap (Arr (I), Arr (J));
I := I + 1;
end if;
end loop;
Swap (Arr (I), Arr (High));
Quick_Sort (Arr, Low, I - 1);
Quick_Sort (Arr, I + 1, High);
end if;
end Quick_Sort;A record with a value and an access to the next node.
type Node is record
Value : Integer;
Next : access Node;
end record;Base type Root and derived Child with overriding method.
type Root is tagged null record;
procedure Method (Obj : Root);
type Child is new Root with record
Extra : Integer;
end record;
overriding procedure Method (Obj : Child);Defining an access type that can point to a String.
type String_Access is access String;Comparing two strings character by character.
function Is_Equal (A, B : String) return Boolean is
begin
if A'Length /= B'Length then
return False;
end if;
for I in A'Range loop
if A(I) /= B(I) then
return False;
end if;
end loop;
return True;
end Is_Equal;Printing a 2D matrix with proper formatting.
procedure Print_Matrix (M : Matrix) is
begin
for I in M'Range (1) loop
for J in M'Range (2) loop
Put (Integer'Image (M (I, J)));
end loop;
New_Line;
end loop;
end Print_Matrix;Computing factorial using recursion.
function Factorial (N : Natural) return Natural is
begin
if N = 0 then
return 1;
else
return N * Factorial (N - 1);
end if;
end Factorial;Euclidean algorithm for greatest common divisor.
procedure GCD (A, B : Positive; Result : out Positive) is
X, Y : Positive := A, B;
begin
while X /= Y loop
if X > Y then X := X - Y; else Y := Y - X; end if;
end loop;
Result := X;
end GCD;Computing power using recursion.
function Pow (Base : Integer; Exp : Natural) return Integer is
begin
if Exp = 0 then
return 1;
else
return Base * Pow (Base, Exp - 1);
end if;
end Pow;pragma Suppress disables certain runtime checks (e.g., index checking) for performance.
pragma Suppress (Index_Check);pragma Detect_Blocking raises an exception when a task blocks inside a protected action, aiding in deadlock detection.
pragma Detect_Blocking;A private type hides its internal structure, exposing only operations through the package.
package My_Package is
type My_Type is private;
procedure Set (Item : My_Type; Value : Integer);
function Get (Item : My_Type) return Integer;
private
type My_Type is record
Value : Integer;
end record;
end My_Package;The package body contains the actual implementation of the operations.
package body My_Package is
procedure Set (Item : My_Type; Value : Integer) is
begin
Item.Value := Value;
end Set;
function Get (Item : My_Type) return Integer is
begin
return Item.Value;
end Get;
end My_Package;A periodic loop using delay until for precise timing.
with Ada.Real_Time; use Ada.Real_Time;
procedure Periodic is
Period : constant Time_Span := Milliseconds (100);
Next : Time := Clock + Period;
begin
loop
delay until Next;
Put_Line ("Tick");
Next := Next + Period;
end loop;
end Periodic;A modular type with 8‑bit size.
type Byte is mod 256;
for Byte'Size use 8;Setting the size of enumeration types using a representation clause.
type My_Enum is (A, B, C);
for My_Enum'Size use 8;pragma Pack instructs the compiler to reduce the storage size of a record by eliminating padding.
pragma Pack (My_Record);pragma Unsuppress re‑enables checks that were previously suppressed.
pragma Unsuppress (All_Checks);Using an alignment clause to specify the byte alignment of a record type.
type My_Record is record
A : Integer;
B : Float;
end record;
for My_Record'Alignment use 4;Example showing a procedure that takes an IN parameter and uses a local variable.
procedure My_Procedure (Param : in Integer) is
Local : Integer := Param;
begin
Local := Local + 1;
end My_Procedure;Function that returns the maximum of two integers.
function Max (A, B : Integer) return Integer is
begin
if A > B then return A; else return B; end if;
end Max;Swapping two integers using a temporary variable.
procedure Swap (A, B : in out Integer) is
T : Integer := A;
begin
A := B;
B := T;
end Swap;An array type with an indefinite range, allowing different sizes upon instantiation.
type My_Array is array (Positive range <>) of Integer;