MATLAB Interview Questions and Answers
Last updated:
Check out 40 of the most common MATLAB interview questions, then take an AI-powered practice interview
Q1What is MATLAB and what is it primarily used for?
BasicFundamentals
Answer
MATLAB (Matrix Laboratory) is a proprietary numerical computing environment and programming language developed by MathWorks since 1984. Its core data type is the double-precision matrix, and every operation is built around matrices, even a scalar is a 1x1 matrix internally. MATLAB is used heavily in engineering and applied science domains: signal and image processing, control system design, communications, computational finance, computational biology, and increasingly in machine learning and AI.
The platform consists of three layers: the MATLAB language and runtime, a large library of built-in functions (linear algebra, FFTs, ODE solvers), and over 100 domain-specific toolboxes sold separately (Signal Processing Toolbox, Image Processing Toolbox, Control System Toolbox, Simulink, etc.). In India, you'll find MATLAB everywhere from college lab assignments at IIT/NIT to mission-critical aerospace simulations at ISRO and DRDO. Interviewers usually follow up on where MATLAB is a bad fit, so be ready to say it plainly: it is licensed per seat plus per toolbox, JIT warm-up and startup cost make it a poor choice for short-lived command-line processes, and there is no free production runtime beyond MATLAB Runtime shipped alongside a compiled artifact.
Know the products too, because they change what you can actually do in a job: MATLAB Desktop, MATLAB Online (browser-based, still licensed), MATLAB Grader for teaching, and MATLAB Production Server for serving compiled functions over HTTP. Finally, know the release naming convention: MathWorks ships twice a year, so R2024b, R2025a, R2025b and R2026a are consecutive releases, and the answer to 'which MATLAB do you know' should be a release, not a year.
Key Points
- Matrix-first language; every variable is conceptually a matrix
- Proprietary (licensed), runs in MATLAB Desktop, MATLAB Online, or MATLAB Production Server
- Heavy use in engineering: signal/image processing, control, communications
- Strong in India's R&D ecosystem: ISRO, DRDO, MathWorks Bangalore, Bosch, Honeywell
Q2How do you create matrices and vectors in MATLAB?
BasicMatrices
Answer
Matrices use square brackets with semicolons separating rows and spaces or commas separating columns. Vectors are just 1xN or Nx1 matrices. The colon operator generates ranges quickly, and `linspace` / `logspace` create evenly-spaced sequences.
Special constructors (`zeros`, `ones`, `eye`, `rand`, `randn`) let you build matrices of a given size in one call. Remember: MATLAB is column-major, so `A(:)` flattens a matrix column-by-column, not row-by-row like NumPy. Concatenation is just matrix building: `[A B]` glues horizontally (this is `horzcat`, so row counts must match) and `[A; B]` glues vertically (`vertcat`, column counts must match).
Getting it wrong produces `Dimensions of arrays being concatenated are not consistent`, one of the first errors every beginner meets. `size(A)` returns the dimension vector, `numel(A)` the element count, `ndims(A)` the number of dimensions, and `reshape(A, m, n)` reinterprets the same column-major buffer without moving data. `repmat`, `cat(3, A, B)` and `kron` build larger arrays from blocks. Two things interviewers listen for: never grow an array inside a loop, because `v(end+1) = x` reallocates and copies on every iteration and `mlint` flags it, and remember that `zeros(3)` is 3x3 while `zeros(3,1)` is a column, because the single-argument form is square. For any class other than double, pass it explicitly: `zeros(1000, 'single')`, `ones(64, 'uint8')`, or `zeros(4096, 'single', 'gpuArray')`.
% Row vector
v = [1 2 3 4 5];
% Column vector
c = [1; 2; 3];
% 3x3 matrix
A = [1 2 3; 4 5 6; 7 8 9];
% Range with colon operator
x = 0:0.1:2*pi; % 0, 0.1, 0.2, ..., 6.2
% Evenly spaced
y = linspace(0, 1, 100);
% Special matrices
Z = zeros(3, 4);
I = eye(5); % 5x5 identity
R = rand(3); % 3x3 uniform randomKey Points
- Semicolon = new row, space/comma = new column
- Colon operator for ranges
- Column-major storage
Q3Why does MATLAB use 1-based indexing and what gotchas does it cause?
BasicIndexing
Answer
MATLAB indexes from 1, not 0, the first element of vector `v` is `v(1)`, and the last is `v(end)`. This matches the mathematical convention used in linear algebra textbooks, which was MATLAB's original audience. The biggest gotcha is when you port code to/from Python or C: an off-by-one error appears every time.
Common pitfalls: (1) `v(0)` throws an error (not zero or undefined), (2) `length(v)` gives the count, so the last index is `length(v)`, not `length(v)-1`, (3) when calling C/Fortran libraries via MEX, you must convert indices back to 0-based. Use the `end` keyword wherever possible, it works regardless of the array size and is the most idiomatic way to address the last element. The colon `v(:)` selects all elements; `v(2:end)` skips the first.
Two error messages come straight out of this design and you should recognize both on sight. `Array indices must be positive integers or logical values` means you indexed with 0, a negative, or a non-integer double, which is a very common result of arithmetic like `v(n/2)` when `n` is odd; the fix is `round`, `floor`, or `idivide`. `Index exceeds the number of array elements` means you overran the array. MATLAB also supports linear indexing into multi-dimensional arrays, so `A(5)` on a 3x3 matrix reaches the fifth element in column-major order, and `sub2ind`/`ind2sub` convert between subscripts and linear indices. Assignment past the end grows the array silently instead of erroring, so `v(10) = 1` on a three-element vector produces a ten-element vector zero-padded in between, which hides bugs rather than surfacing them. Finally, `end` is context-sensitive: inside `A(end, end)` it resolves to the last index of that specific dimension, and it is only legal inside an indexing expression, not as a standalone variable.
v = [10 20 30 40 50];
v(1) % 10, there is no v(0)
v(end) % 50
v(2:end) % [20 30 40 50]
v(1:end-1) % [10 20 30 40]
A = [1 2 3; 4 5 6; 7 8 9];
A(5) % 5, linear index, column-major
[r, c] = ind2sub(size(A), 5); % r = 2, c = 2
A(end, end) % 9
v(10) = 1; % silently grows to 10 elements, zero-padded
% v(0) -> Array indices must be positive integers or logical values
% v(99) -> Index exceeds the number of array elements (10)Key Points
- Indexing starts at 1
- `end` keyword = last index, works in any context
- `v(2:end)` skips first; `v(1:end-1)` skips last
- Common porting bug when moving between MATLAB and Python/C
Q4What is the difference between `*` and `.*` (and similarly `/`, `^`)?
BasicOperators
Answer
This is the single most common MATLAB confusion for beginners. `*` is matrix multiplication (linear algebra), inner dimensions must match. `.*` is element-wise multiplication, dimensions must match exactly (or broadcast). Same for `/` vs `./`, `^` vs `.^`. If you write `A^2` with a 3x3 matrix, MATLAB computes `A*A`.
If you want each element squared, you need `A.^2`. The dot-prefix family is what you almost always want when working with sampled signals or pixel arrays. The division pair is what trips up more experienced candidates: `A/B` is `mrdivide` and solves `x*B = A`, while `A\B` is `mldivide` and solves `A*x = B`, whereas `./` and `.\` are plain element-wise division in each direction.
Transpose has the same split: `A'` is the complex-conjugate transpose (`ctranspose`) and `A.'` is the plain transpose (`transpose`). On real data they agree, on complex data they do not, and using `'` on a complex baseband signal silently conjugates it, which is a classic bug in communications code. Matrix power is genuinely different from element power: `A^0.5` computes a matrix square root via an eigendecomposition, while `A.^0.5` takes the square root of each entry.
Since implicit expansion arrived in R2016b, element-wise operators broadcast singleton dimensions, so a 3x1 column plus a 1x4 row now yields a 3x4 matrix where older releases raised an error. When shapes are genuinely incompatible you get `Matrix dimensions must agree` for element-wise operators and `Incorrect dimensions for matrix multiplication` for `*`.
A = [1 2; 3 4];
B = [5 6; 7 8];
A * B % matrix product = [19 22; 43 50]
A .* B % element-wise = [5 12; 21 32]
A^2 % A*A = [7 10; 15 22]
A.^2 % element squared = [1 4; 9 16]
% Most signal processing uses dot-operators:
t = 0:0.001:1;
y = sin(2*pi*50*t) .* exp(-2*t); % NOT * hereQ5What is vectorization in MATLAB and why does it matter?
BasicPerformance
Answer
Vectorization means writing code that operates on entire arrays at once instead of looping element-by-element. MATLAB's array operations are implemented in optimized C/Fortran (BLAS/LAPACK), so a vectorized statement can be 10x to 1000x faster than the equivalent `for` loop. The JIT compiler (introduced in R2015b and improved through R2024b) has narrowed the gap for simple loops, but vectorized code is still usually faster and always more idiomatic.
Common transformations: replace element-wise loops with array operations, use `bsxfun` or implicit expansion (broadcasting since R2016b) for size mismatches, and prefer built-ins like `sum`, `cumsum`, `arrayfun` over manual loops. The nuance a senior interviewer wants is that vectorization is not free. A vectorized expression materializes full temporary arrays, so collapsing a loop over 10^8 elements into one statement can trade a slow-but-working loop for an out-of-memory failure; chunking the data or keeping the loop is then the right answer.
Implicit expansion makes this worse silently: `A - mean(A)` is fine, but `x(:) - y(:)'` on two million-element vectors quietly asks for a 10^12-element matrix. Where you cannot vectorize, preallocate with `zeros` or `cell` before the loop, because growing an array by assignment reallocates and copies each iteration, turning a linear loop quadratic; `mlint` raises `The variable appears to change size on every loop iteration`. Also know the vectorization helpers beyond arithmetic: logical masks (`x(x < 0) = 0`), `cumsum`/`diff`/`movmean` for sliding computations, `accumarray` for grouped aggregation, implicit expansion instead of `bsxfun` in new code, and `pagemtimes` for batched matrix products along the third dimension. Confirm every claimed speedup with `timeit` or the Profiler rather than assuming.
% SLOW: loop
N = 1e6;
y = zeros(1, N);
for i = 1:N
y(i) = sin(i/N) + 2*cos(i/N);
end
% FAST: vectorized
x = (1:N) / N;
y = sin(x) + 2*cos(x); % ~50x fasterKey Points
- Vectorized = whole-array operations, no explicit loops
- Speedup comes from BLAS/LAPACK + memory locality
- Implicit expansion (broadcasting) added in R2016b
- JIT has improved loops in R2024b but vectorized is still preferred
Q6How do you write a MATLAB function and what is the difference from a script?
BasicLanguage
Answer
A script is a .m file containing a sequence of commands that share the base workspace, every variable persists after the script finishes. A function is a .m file beginning with the `function` keyword that takes inputs and returns outputs in its own local workspace. Functions are the right unit for reusable code; scripts are for quick prototyping or top-level entry points.
Since R2016b, you can also define local functions in a script file (after the script's main commands), and since R2024 you can have anonymous functions with multiple statements via `arrayfun` or string-eval workarounds. Beyond the basics, know the argument machinery: `varargin` and `varargout` collect variable-length inputs and outputs as cell arrays, `nargin`/`nargout` report how many were actually supplied at the call site, and since R2019b the `arguments` block declares types, sizes, defaults and validators declaratively, which is now preferred over hand-rolled `inputParser` or `nargin` chains. There are four function flavors worth naming.
Local functions are extra `function` blocks in the same file, visible only inside it. Nested functions are defined inside another function's body and share its workspace, which is how you build a closure over mutable state. Private functions live in a `private/` subfolder and are callable only from the parent folder.
Anonymous functions capture the values of workspace variables at creation time, not by reference, and that rule causes real bugs: an anonymous handle built inside a loop freezes the loop variable's current value forever. On the script side, remember that sharing the base workspace means a script can silently clobber a caller's variables, which is exactly why production code lives in functions.
% file: addNumbers.m
function [sum, diff] = addNumbers(a, b)
% Returns sum and difference
sum = a + b;
diff = a - b;
end
% Usage:
[s, d] = addNumbers(10, 3); % s=13, d=7
% Anonymous (lambda) function
square = @(x) x.^2;
square(5) % 25Key Points
- Functions have their own workspace; scripts share the base workspace
- File name must match function name for callable functions
- Use `nargin`/`nargout` to check argument counts
- Anonymous functions via `@(args) expr`
Q7How do you read and write data files (CSV, Excel, MAT) in MATLAB?
BasicI/O
Answer
MATLAB has a layered file-I/O API. For tabular data, use `readtable`/`writetable` (returns/accepts a `table` object), these handle CSV, Excel (.xlsx), and text files with named columns. For pure numeric matrices, `readmatrix`/`writematrix` are faster.
The MAT-file format (`save`/`load`) is MATLAB's native binary format, preserves variable names, classes, and even sparse structure. For Excel specifically on Windows you can use `xlsread`/`xlswrite` (legacy, slower) or `readtable`/`writetable` (preferred, cross-platform). In interviews the follow-up is always about messy real files, and the answer is `detectImportOptions`: it returns an options object where you can force `VariableTypes`, set `MissingRule` and `ImportErrorRule`, set `VariableNamingRule` to `'preserve'` so headers with spaces and units survive instead of becoming `Var1`, and set `SelectedVariableNames` so you only read the columns you need.
Encoding matters too, so pass `'Encoding','UTF-8'` when a CSV exported from Excel garbles non-ASCII text. For time series use `readtimetable`, which gives you a row-time index plus `retime` and `synchronize`. For large data, `parquetread`/`parquetwrite` and `datastore` beat CSV by a wide margin on both size and read speed. On the MAT side, know the versions: `-v7` is the default compressed format with a roughly 2 GB per-variable ceiling, and `-v7.3` is HDF5-based, which is what you need for larger variables and what makes partial access possible through the `matfile` object, letting you read or write a slice of a huge array without loading the whole thing into memory.
% Read a CSV with headers into a table
T = readtable('sensor_data.csv');
T.temperature % column access by name
% Read pure numeric matrix
M = readmatrix('measurements.txt');
% Save/load native MAT format
save('results.mat', 'T', 'M');
load('results.mat'); % brings T and M into workspace
% Write Excel
writetable(T, 'output.xlsx', 'Sheet', 'Results');Q8What is the Live Editor and when should you use it?
BasicEnvironment
Answer
The Live Editor (introduced in R2016a, dramatically improved through R2024b) is MATLAB's notebook-style interface, `.mlx` files mix executable code, formatted text, equations (LaTeX), and inline plots in a single document. It's analogous to Jupyter notebooks. Use it for: reports and homework where the narrative matters, teaching, exploratory analysis where you want plots alongside code, and shareable documentation.
For pure code that will be called from other places, use plain `.m` scripts/functions instead, `.mlx` files are harder to diff in Git and slower to load at scale. R2024b added an AI-powered assistant in the Live Editor that can suggest code completions and explain errors, similar to GitHub Copilot. Practical details that show you have actually used it: `Ctrl+Enter` runs the current section, sections are delimited by `%%` exactly as in plain scripts, and the output pane can sit to the right of the code or inline under each block.
Live controls (sliders, drop-downs, checkboxes, edit fields) bind directly to variables in the code, which turns an `.mlx` into a lightweight parameter-tuning tool without writing an App Designer app. The `export` function (R2022a onward) converts an `.mlx` to PDF, HTML, LaTeX, Word or plain `.m`, and `export("analysis.mlx", "analysis.m")` is the sane way to get a reviewable diff into a pull request. In CI you run one headlessly with `matlab -batch "run('analysis.mlx')"`.
The trade-off to state out loud: an `.mlx` is a zipped Open Packaging Convention bundle, so Git treats it as a binary blob, conflicts resolve at whole-file granularity, and line-level review is impossible. Most teams therefore keep algorithms in `.m` files and reserve `.mlx` for reports and demos that call into them.
Q9How does MATLAB handle strings and what changed with the `string` type?
BasicLanguage
Answer
MATLAB has two string-like types: character arrays (legacy, `'hello'` with single quotes) and the `string` class (R2016b, `"hello"` with double quotes). Character arrays are literally `1xN` matrices of characters, concatenating with `[s1 s2]` works but `length` returns the number of characters. The `string` type is the modern API: each `string` element is a single object, arrays of strings work cleanly, and you get methods like `split`, `replace`, `contains`, `extractBetween`.
Always prefer `string` for new code, and use `string(charArray)` to convert when calling legacy functions. The differences that show up in real code: comparing char arrays requires `strcmp`, because `==` compares element by element and errors with `Matrix dimensions must agree` the moment the lengths differ, whereas `string` values compare correctly with `==` and `isequal`. A `string` can hold `missing`, which is distinct from the empty string `""`, and `ismissing` is how you test for it, which is what lets string arrays behave like proper columns inside a `table`.
Formatting is cleaner too: `compose` returns a string array from a format template while `sprintf` returns a char row vector, and `join`, `split`, `strip` and `pad` all operate elementwise across arrays. Since R2020b, `pattern` objects (`digitsPattern`, `lettersPattern`, `wildcardPattern`, `asManyOfPattern`) give a readable alternative to regular expressions inside `contains`, `extract`, `replace` and `split`. Two conversions to keep straight: `char(65)` gives `'A'`, because char arrays are numeric codes underneath, while `string(65)` gives `"65"`. Most toolbox functions now accept both types, but MEX gateways and low-level file I/O still want `char`, so wrap with `char(s)` at those boundaries.
% Legacy char array
s1 = 'Hello';
length(s1) % 5 (counts characters)
% Modern string
s2 = "Hello";
strlength(s2) % 5
% Array of strings
names = ["Asha", "Ravi", "Priya"];
names(2) % "Ravi"
upper(names) % ["ASHA" "RAVI" "PRIYA"]
contains(names, "a")Q10How do you create a basic 2D plot in MATLAB?
BasicPlotting
Answer
Use `plot(x, y)` with vectors of equal length. MATLAB opens a Figure window and renders. You can layer multiple plots with `hold on`, add labels via `xlabel`/`ylabel`/`title`, set the legend, and control line style with format strings like `'r--'` (red dashed).
For subplots, use `tiledlayout` (R2019b+) instead of the older `subplot`, it gives you better control over spacing and shared axes. Export figures with `exportgraphics(gcf, 'plot.png', 'Resolution', 300)` for publications. What separates a scripted plot from a maintainable one is using handles instead of current-figure state. `h = plot(x, y)` returns a `Line` object whose properties you can set later (`h.YData = newY`, `h.Color = [0 0.4 0.8]`), `ax = gca` gives you the `Axes` object, and setting `ax.XLim`, `ax.FontSize` or `ax.YScale = 'log'` reads better than the older `set(gca, 'YScale', 'log')` form.
Updating `h.YData` inside an animation loop with `drawnow limitrate` is dramatically faster than calling `plot` again each frame, because re-plotting tears down and rebuilds the whole graphics object tree. Other things worth naming: `yyaxis left` and `yyaxis right` for dual scales, `colororder` for consistent series colors, `nexttile` inside a `tiledlayout`, and `sgtitle` for a title spanning the layout. For output, `exportgraphics` is the modern path and accepts `'ContentType','vector'` for true vector PDF or EPS, while `saveas` and `print` are legacy and usually add whitespace. `savefig`/`openfig` persist the live figure object when you need to reopen and edit it later.
x = linspace(0, 2*pi, 200);
figure;
plot(x, sin(x), 'b-', 'LineWidth', 1.5);
hold on;
plot(x, cos(x), 'r--', 'LineWidth', 1.5);
xlabel('x (radians)');
ylabel('y');
title('Sine and Cosine');
legend('sin(x)', 'cos(x)');
grid on;
exportgraphics(gcf, 'trig.png', 'Resolution', 300);Q11What are MATLAB cell arrays and structures? When do you use each?
BasicData Structures
Answer
A cell array is an array where each element can hold any type, strings, numbers, other arrays. Created with curly braces: `c = {1, 'hello', [1 2 3]}`. Access elements with `c{i}` to get the contents or `c(i)` to get another cell.
Use cells for collections of heterogeneous items or variable-length strings. A structure groups named fields, like a Python dict or C struct: `s.name = 'Asha'; s.age = 28;`. Use structures when fields have meaningful names.
For larger tabular data, the `table` class (R2013b+) is usually better than struct-of-arrays. The distinction interviewers probe is `c{i}` versus `c(i)`: braces extract the contents, parentheses return a sub-cell, so `c{1:3}` produces a comma-separated list (which is why `[c{:}]` concatenates the contents and `{c{:}}` rebuilds a cell) while `c(1:3)` returns a 1x3 cell array. That comma-separated list is also the mechanism behind `deal` and multi-output assignment.
On structs, dynamic field access with `s.(fieldName)` lets you build field names at runtime, and `isfield`, `rmfield`, `orderfields` and `struct2table` round out the API. Know the performance shape as well: a struct array of 100000 elements each holding one scalar is far slower and heavier than a single struct holding one 100000-element vector, because every field of every element carries its own array header. Since R2022b the `dictionary` type gives real hash-map semantics with typed keys and values, and it supersedes `containers.Map` for new code because it is a value type, accepts numeric and string keys, and supports vectorized lookup. For homogeneous columnar data, `table` and `timetable` remain the right answer.
% Cell array
c = {1, 'hello', [1 2 3]};
c{2} % 'hello'
length(c) % 3
% Structure
s.name = 'Asha';
s.age = 28;
s.scores = [85 92 78];
fieldnames(s) % {'name', 'age', 'scores'}
% Struct array
people(1).name = 'Asha';
people(2).name = 'Ravi';
{people.name} % {'Asha', 'Ravi'}Q12What is Simulink and how is it different from regular MATLAB code?
BasicSimulink
Answer
Simulink is MathWorks' graphical block-diagram environment for modeling dynamic systems, you wire together blocks (transfer functions, integrators, sensors, sources) instead of writing code. It's used heavily in control systems design, signal processing system simulation, and most importantly in model-based design for embedded systems: you simulate a model, validate it against requirements, and then auto-generate C/C++/HDL code with Embedded Coder, Simulink Coder, or HDL Coder. Industries that depend on Simulink in India: automotive (Bosch, Mahindra, Tata Motors, Continental), aerospace (HAL, ISRO), and defense (DRDO labs).
MATLAB code calls Simulink via `sim('model.slx')` and you can embed MATLAB Function blocks inside Simulink models for custom algorithms. Concretely, a model is an `.slx` file (a zipped package since R2012a, which is why the older text-based `.mdl` still appears in legacy repos) and modern code simulates it with `sim(Simulink.SimulationInput(mdl))` so you can sweep parameters and fan them out with `parsim`. Every block carries a sample time: `0` means continuous, a positive number means discrete at that rate, and `-1` means inherited, and mixing rates carelessly is what produces the rate-transition errors beginners hit.
A `MATLAB Function` block runs generated code rather than interpreted MATLAB, so it only accepts the code-generation subset: no dynamic field names, no `cellfun` over anonymous handles, and variable-size signals must be declared explicitly. When you need hand-written C inside a model you write an S-function or drop in a C Caller block. The other classic Simulink failure is `Algebraic loop`, a direct-feedthrough cycle with no state in it, which you break with a Unit Delay or Memory block rather than by rewiring the physics.
Key Points
- Graphical modeling of dynamic systems
- Used for model-based design + auto-generated embedded code
- Huge in India's automotive and aerospace R&D
- Embedded Coder generates production C; HDL Coder generates Verilog/VHDL
Q13What is logical indexing in MATLAB and when is it better than `find`?
BasicIndexing
Answer
Logical indexing means indexing an array with a logical mask of the same size, and MATLAB returns the elements sitting under the `true` positions. `x(x > 5)` literally reads as 'the elements of x greater than 5', and since the comparison itself produces a logical array, no loop is involved. The same mask works on the left of an assignment: `x(x < 0) = 0` clamps negatives in place, and `x(isnan(x)) = []` deletes elements outright so the array shrinks. `find` converts a mask into the numeric positions of its `true` entries, so `x(find(x > 5))` gives the same answer but is slower, allocates an extra index vector, and `mlint` flags it with a suggestion to use logical indexing instead of FIND. Reach for `find` only when you genuinely need positions: `idx = find(x > 5, 1, 'first')` for the first threshold crossing, or `[r, c] = find(A)` for row and column subscripts.
Companions are `any`, `all`, `nnz` to count `true` entries, `xor`, and `islogical` to confirm a mask really is logical rather than a double array of ones and zeros. That difference is real: indexing with the double `[1 0 1]` asks for elements 1, 0 and 1 and errors on the zero, while `logical([1 0 1])` selects the first and third elements. A mask longer than the array raises `Index exceeds the number of array elements`.
x = [3 -1 8 NaN 5 -7];
mask = x > 0; % logical([1 0 1 0 1 0])
x(mask) % [3 8 5]
x(x < 0) = 0; % clamp in place
x(isnan(x)) = []; % delete elements, array shrinks to 5
nnz(x > 4) % 2
any(x > 100) % false (logical 0)
% find only when you actually need positions
idx = find(x > 4, 1, 'first');
[r, c] = find(magic(4) > 12);
% double mask vs logical mask are NOT the same
% x([1 0 1]) -> Array indices must be positive integers...
x(logical([1 0 1 0 1])) % selects elements 1, 3 and 5Key Points
- `x(x > 5)` selects; `x(x < 0) = 0` assigns; `x(mask) = []` deletes
- Prefer logical masks over `find` unless you need the index values
- `find(v, 1, 'first')` and `[r, c] = find(A)` are the legitimate `find` uses
- A double `[1 0 1]` is not a mask; wrap it in `logical(...)`
Q14How do you handle errors in MATLAB with `try`/`catch` and `MException`?
BasicError Handling
Answer
`try`/`catch` wraps code that may fail, and the `catch ME` form binds an `MException` object describing what went wrong. That object carries `ME.identifier` (a colon-separated string such as `MATLAB:UndefinedFunction` or `MATLAB:nonExistentField`), `ME.message` (the human-readable text) and `ME.stack` (a struct array with file, name and line for each frame). Always branch on `ME.identifier` using `strcmp` or a `switch`, never on `ME.message`, because messages are localized and get reworded between releases while identifiers are stable API.
Raise your own errors with the two-argument form, `error('acme:badGain', 'Gain must be positive, got %g', k)`, which gives callers something specific to catch; a bare `error('something failed')` produces an empty identifier and forces everyone downstream into string matching. To re-raise after logging, call `rethrow(ME)`, which preserves the original stack, instead of `error(ME.message)`, which discards both the stack and the identifier. `MException.addCause` chains a low-level failure onto a higher-level one so the report shows both, and `throwAsCaller` hides your validation frame so the error points at the caller's line rather than at your `if` statement. For cleanup that must run whether or not the body throws, `onCleanup` ties a handler to a local variable's lifetime, which is more reliable than putting `fclose` at the end of the `try`. Two related tools: `warning('acme:slowPath', ...)` paired with `warning('off', id)` to suppress a specific warning, and `dbstop if error` to break at the throw site with the workspace still live.
function y = applyGain(x, k)
if ~(isnumeric(k) && isscalar(k) && k > 0)
error('acme:badGain', 'Gain must be a positive scalar, got %s', mat2str(k));
end
y = k * x;
end
% Caller
try
y = applyGain(data, -2);
catch ME
switch ME.identifier
case 'acme:badGain'
warning('acme:fallback', 'Falling back to unity gain');
y = data;
otherwise
rethrow(ME); % preserves the original stack
end
end
% Cleanup that runs even if the body throws
fid = fopen('run.log', 'w');
cleaner = onCleanup(@() fclose(fid));Q15How does MATLAB's copy-on-write (pass-by-value) actually work?
IntermediateMemory
Answer
MATLAB's semantics say every function argument is pass-by-value, `function modify(A)` cannot mutate the caller's `A`. Naively this would mean every argument is fully copied on every call. In reality MATLAB uses copy-on-write: the array data is shared until something tries to modify it, then a copy is made.
So `function y = f(A); y = A; end` is essentially free even for a 1GB array. The gotcha is in-place modification inside functions: `function A = add_one(A); A(:) = A + 1; end` triggers a copy because the function modifies `A`. To avoid the copy, MATLAB has an optimization: if the input variable name and output variable name match in the caller (`A = add_one(A)`), AND the input has no other references in the caller, the JIT skips the copy.
This is sometimes called the 'in-place optimization'. Tools like `memory` and the Profiler help diagnose unexpected copies. Two further points are worth saying out loud.
Handle-class objects sit outside this scheme entirely, because a handle is a reference and mutating it inside a function is visible to the caller, which is exactly why handle classes are right for stateful models and wrong when you want value semantics. And the in-place optimization is fragile: it is disabled when the function is called from a script or the command line rather than from another function, when the variable is also captured by a nested or anonymous function, when you index the output as in `out.field = f(A)`, and when the function body contains `eval`, `save`, `assignin` or an active breakpoint, because any of those could observe the intermediate state. The practical diagnostic is to watch resident memory with `whos` or the OS monitor while running a loop that should be in place.
% This is COPY-ON-WRITE friendly, no actual copy made
function y = passthrough(A)
y = A;
end
% This MIGHT trigger a copy unless caller pattern matches
function A = add_one(A)
A(:) = A + 1; % modifies A
end
% In-place optimization succeeds (same variable name in/out)
big = rand(10000);
big = add_one(big); % no copyKey Points
- Logical semantics: pass-by-value
- Implementation: copy-on-write (shared until modified)
- In-place optimization: `x = f(x)` can avoid the copy
- Use Profiler / `memory` to diagnose unwanted copies
Q16What is the Signal Processing Toolbox and what does it provide?
IntermediateToolboxes
Answer
The Signal Processing Toolbox extends base MATLAB with functions for filter design (`designfilt`, `butter`, `cheby1`, `firpm`), spectral analysis (`pwelch`, `spectrogram`, `pmusic`), time-frequency analysis (CWT, STFT), and audio/communications-specific operations. The flagship apps are `signalAnalyzer` and `filterDesigner` (formerly fdatool), which let you design filters visually and export to code. Common interview topics: design a Butterworth bandpass filter, compute a periodogram vs Welch's method, distinguish IIR from FIR design tradeoffs, and apply zero-phase filtering with `filtfilt`.
This toolbox is the workhorse for biomedical signal analysis (ECG, EEG), audio processing, vibration analysis, and digital communications labs in India's engineering colleges. The details interviewers dig into: `butter`, `cheby1` and `ellip` take normalized frequency, so `Wn = fc/(fs/2)`, and passing raw hertz is the single most common mistake in this toolbox; `designfilt` sidesteps it because you pass `'SampleRate'` and real cutoffs by name. `filter` applies the difference equation once and introduces phase distortion equal to the filter's group delay, while `filtfilt` runs it forward and backward, which cancels phase but squares the magnitude response and therefore doubles the effective order, so a 4th-order design behaves like 8th and the attenuation you measure is not the one you specified. For high-order IIR designs ask for second-order sections, because the direct `[b, a]` form goes numerically unstable somewhere past order 8 and the poles drift off the unit circle. Also be ready on `resample` versus `decimate` (both anti-alias filter first, `downsample` does not), on picking `spectrogram` window length as the time-versus-frequency resolution trade-off, and on `fvtool` for inspecting magnitude, phase and group delay before you commit a design.
% Design a 4th-order Butterworth lowpass at 100 Hz, Fs = 1000
fs = 1000;
[b, a] = butter(4, 100/(fs/2));
% Apply zero-phase filtering (forward + backward)
y = filtfilt(b, a, x);
% Spectrum via Welch's method
[pxx, f] = pwelch(x, hann(512), 256, 1024, fs);
plot(f, 10*log10(pxx));Q17How do you do image processing in MATLAB with the Image Processing Toolbox?
IntermediateToolboxes
Answer
The Image Processing Toolbox provides `imread`/`imwrite`/`imshow` for I/O and display, plus a huge library of operations: filtering (`imfilter`, `imgaussfilt`, `medfilt2`), morphology (`imdilate`, `imerode`, `imopen`), segmentation (`imbinarize`, `watershed`, `activecontour`), and feature detection (`edge`, `detectHarrisFeatures`, `corner`). Images are stored as 2D matrices for grayscale or 3D (HxWx3) for RGB, with `uint8`, `uint16`, or `double` element types. A common interview question is to threshold an image, perform morphological cleanup, and count connected components, this is the classic 'count rice grains' problem.
R2024b strengthened the deep learning side: `imageDatastore`, `imageDataAugmenter`, and the `imagesegmenter` app let you build CNN-based segmentation pipelines without leaving MATLAB. Class handling is where most bugs live: a `uint8` image spans 0 to 255, a `double` image is expected to span 0 to 1, and `im2double` rescales while a bare `double()` cast does not, so a wrongly converted image displays as pure white. `imshow(I, [])` autoscales the display range, which is how you inspect 16-bit or floating-point data without altering pixels. For counting and measuring, `bwconncomp` plus `regionprops` beats the older `bwlabel`, because `regionprops` hands back `Area`, `Centroid`, `BoundingBox`, `Eccentricity` and `Circularity` in a table you can filter directly.
Integer arithmetic saturates rather than wrapping, so `uint8(200) + uint8(100)` is 255, not 44, which silently clips bright regions instead of erroring. For images that exceed memory, `blockproc` and `blockedImage` process tile by tile. And know that `imfilter` correlates by default while `conv2` convolves with the kernel flipped, which matters the instant your kernel stops being symmetric.
img = imread('rice.png');
gray = rgb2gray(img); % if color
bw = imbinarize(gray, 'adaptive');
bw = imopen(bw, strel('disk', 3)); % cleanup
[labels, n] = bwlabel(bw);
fprintf('Found %d objects\n', n);
imshow(label2rgb(labels));Q18How do you design and analyze a control system in MATLAB?
IntermediateControl Systems
Answer
The Control System Toolbox represents systems as `tf` (transfer function), `ss` (state space), `zpk` (zero-pole-gain), or `frd` (frequency response data) objects. You can plot the step response with `step`, the frequency response with `bode`, root locus with `rlocus`, and pole-zero map with `pzmap`. For controller design, `pidtune` automatically tunes a PID with specified bandwidth and phase margin, and `sisotool` opens an interactive interface for compensator design.
The workflow in industry: model the plant in Simulink, identify parameters from experimental data with the System Identification Toolbox, design a controller with Control System Toolbox, deploy via Simulink Coder. This is the daily workflow at Bosch India, Mahindra Research, and ISRO's GNC (Guidance, Navigation, Control) teams. Details a control interviewer will push on: a continuous system is stable when every pole has a negative real part (`pole`, `damp`, `isstable`), while a discrete system needs every pole inside the unit circle, and `c2d(G, Ts, 'tustin')` versus `'zoh'` changes where those poles land, with Tustin optionally prewarped at a chosen frequency. `margin(L)` computes gain and phase margins with their crossover frequencies from the open-loop transfer function, and quoting margins off the closed loop instead is a common slip. `lsim` simulates arbitrary input signals, `dcgain` gives the steady-state gain and therefore the steady-state step error, and `minreal` cancels the pole-zero pairs that naive series compensation leaves behind.
The interactive tools were renamed: `sisotool` now opens Control System Designer, and `pidTuner(G)` opens the PID app with response-time and transient-behavior sliders. For state space, test `rank(ctrb(A,B))` and `rank(obsv(A,C))` before you attempt `place` or `lqr`, because an uncontrollable mode makes pole placement fail with a rank warning rather than a useful answer.
% Plant: G(s) = 1 / (s^2 + 2s + 1)
G = tf(1, [1 2 1]);
% Auto-tune a PID
[C, info] = pidtune(G, 'PID');
% Closed-loop
T = feedback(C*G, 1);
step(T);
bode(T);
fprintf('Phase margin: %.1f deg\n', info.PhaseMargin);Q19What is `arrayfun` and how does it differ from a `for` loop?
IntermediateFunctional
Answer
`arrayfun(F, A)` applies function `F` to each element of array `A` and returns the results assembled into a new array. It's the higher-order map equivalent. For simple element-wise operations, vectorized syntax (`A.^2`) is faster than both `arrayfun` and an explicit loop. `arrayfun` shines when (1) you need to call a function that isn't vectorized, (2) you want GPU acceleration via `UniformOutput=false` and `gpuArray`, or (3) you're using anonymous functions for clarity.
With `'UseParallel', true` (requires Parallel Computing Toolbox), `arrayfun` distributes work across CPU cores. Sister functions: `cellfun` for cell arrays, `structfun` for structures, `rowfun` for tables. The error you hit first is `Non-scalar in Uniform output ...
Set 'UniformOutput' to false`, which means your function returned something other than a consistently typed scalar, so the results cannot be packed into a numeric array; passing `'UniformOutput', false` returns a cell array instead. Be honest about performance in the interview: for interpreted CPU code, `arrayfun` is typically the same speed as or slower than a plain `for` loop, because it pays function-call overhead per element, and the real reasons to use it are readability and composability inside a single expression. The genuine exception is `gpuArray` input, where `arrayfun` compiles your anonymous function into one CUDA kernel and runs it elementwise on the device, which beats both loops and a chain of separate GPU calls because it never materializes the intermediates. Also know `'ErrorHandler'` for continuing past failures, `cellfun(@isempty, c)` as the idiomatic emptiness test, and that the legacy string-name form such as `cellfun('length', c)` supports only a handful of names and should not appear in new code.
% Custom non-vectorized function
f = @(x) sum(divisors(x)); % divisors not vectorized
nums = 1:100;
% Loop version
result1 = zeros(size(nums));
for i = 1:numel(nums)
result1(i) = f(nums(i));
end
% arrayfun version
result2 = arrayfun(f, nums);
% Parallel arrayfun (with Parallel Computing Toolbox)
result3 = arrayfun(f, nums, 'UseParallel', true);Q20How do you call Python from MATLAB and vice versa?
IntermediateInterop
Answer
Two directions: (1) MATLAB calling Python: `pyenv` configures the Python interpreter, then `py.module.function(args)` invokes Python code. Data marshals automatically (`double` → `numpy.float64`, MATLAB cell → Python list, etc.) but large arrays involve a copy. (2) Python calling MATLAB: the MATLAB Engine API for Python lets you run MATLAB sessions from Python, install `matlabengineforpython` from pip and call `matlab.engine.start_matlab()`. R2024b adds the option to package MATLAB code as standalone Python packages with the MATLAB Compiler SDK, deployable as `pip install`-able wheels with no MATLAB runtime needed at the call site (a separate MATLAB Runtime is bundled).
This is increasingly common in India's R&D labs where the team has MATLAB-built algorithms but production is Python. Operationally, the first thing to check is the version matrix: each MATLAB release supports a specific band of CPython versions, and pointing `pyenv` at a newer interpreter than the release supports fails immediately, so calling `pyenv` with no arguments to print `Version`, `Executable` and `Status` is always the first debugging step. Run the interpreter out of process with `pyenv('ExecutionMode','OutOfProcess')` whenever the Python side loads native extensions such as PyTorch or OpenCV, because an in-process segfault or a clashing C++ runtime takes the entire MATLAB session down with it; `terminate(pyenv)` restarts that process, which is also how you pick up edits to a Python module without restarting MATLAB.
For short snippets, `pyrun` and `pyrunfile` (R2021b onward) execute Python source directly and hand named variables back. Conversion is the other gotcha: numeric arrays cross the boundary as copies, a MATLAB matrix lands in NumPy transposed unless you account for column-major order, and a Python `int` returns as `int64` rather than `double`, so wrap results in `double(...)` before doing arithmetic with them.
% MATLAB calling Python
pyenv('Version', '/usr/bin/python3.12');
np = py.importlib.import_module('numpy');
arr = np.array([1, 2, 3, 4, 5]);
result = np.mean(arr); % Python numpy.float64
m_val = double(result); % back to MATLAB double
% Python calling MATLAB:
% >>> import matlab.engine
% >>> eng = matlab.engine.start_matlab()
% >>> eng.sqrt(16.0)
% 4.0Q21How do you use GPU computing in MATLAB?
IntermediatePerformance
Answer
With the Parallel Computing Toolbox + a CUDA-capable NVIDIA GPU, MATLAB can offload computations transparently. The pattern: convert arrays to `gpuArray`, perform operations, then gather back to CPU with `gather`. Most MATLAB built-ins overload for `gpuArray`, FFTs, matrix multiply, solve, image filters, deep learning forward/backward all run on the GPU automatically.
R2024b expanded GPU coverage in the Image Processing Toolbox and added native support for FP16 (half-precision) for deep learning training. For custom CUDA kernels, you can write a `.cu` file and call it via `parallel.gpu.CUDAKernel`. Common gotcha: the gather step blocks until the GPU finishes, moving data to/from the GPU is expensive, so do as much work on the GPU as possible before gathering.
Two measurement traps are worth naming. GPU calls are asynchronous, so `tic`/`toc` around a GPU operation times the queueing rather than the work; you need `wait(gpuDevice)` before `toc`, or better, `gputimeit(@() myfun(A))`. And consumer NVIDIA cards have deliberately crippled double-precision throughput, often a small fraction of their single-precision rate, so a `double` `gpuArray` can be slower than the CPU while the identical code in `single` is an order of magnitude faster; casting to `single` is usually the first optimization to try.
Device memory is fixed and far smaller than host RAM, and overrunning it raises an out-of-memory error on the device, which you handle by chunking, clearing intermediates, or `reset(gpuDevice)` to wipe the device state. Not every function is overloaded for `gpuArray`, and unsupported calls either error or quietly gather to the CPU and back, which destroys throughput, so profile to catch those round trips. `arrayfun` and `pagefun` on `gpuArray` inputs fuse elementwise and batched work into single kernels.
% Check GPU
gpuDevice
% Move data to GPU
A = rand(5000, 'gpuArray');
B = rand(5000, 'gpuArray');
% Operations run on GPU
C = A * B;
D = fft(C);
% Gather result back to CPU
result = gather(D);Q22What is object-oriented programming in MATLAB?
IntermediateLanguage
Answer
MATLAB has full OOP since R2008a, with classes defined in `.m` files using the `classdef` keyword. Classes can have properties (with `SetAccess`/`GetAccess` for encapsulation), methods, events, and inherit from one or more base classes. There are two important class kinds: **value classes** (default) which behave like structs and copy on assignment, and **handle classes** (subclass of `handle`) which behave like Python objects, assignment copies a reference, and you need `clone` to deep-copy.
Most domain models you'd write in production (a `Filter` class, a `Robot` class) should be handle classes; mathematical entities (a `Polynomial` class) are usually value classes. R2024b improved property validation syntax and added more built-in validator functions like `mustBeNonnegative`. Attributes are where the depth is.
Properties can be `Constant`, `Dependent` (computed by a `get.` method instead of stored), `Transient` (skipped by `save`), or `SetObservable` so listeners fire, and access is controlled with `SetAccess = private` and `GetAccess = protected`. Methods can be `Static`, `Abstract`, `Sealed`, or `Access = private`. A handle class can declare `events` and raise them with `notify` while callers attach `addlistener`, which is the standard pattern for decoupling GUI code from simulation code, and it can define a `delete` method that acts as a destructor.
You overload operators by defining methods named `plus`, `mtimes`, `eq`, `subsref` or `disp`, which is exactly how `tf` objects and `duration` manage to behave like built-in types. `enumeration` blocks give typed enums instead of magic numbers. The performance caveat interviewers like to hear: MATLAB method dispatch is slow relative to a plain function call, so a method invoked inside a tight loop over a million objects is a known bottleneck, and the fix is one object holding arrays rather than an array of objects.
classdef Robot < handle
properties
position (1,2) double = [0 0] % typed + default
name (1,1) string
end
methods
function obj = Robot(name)
obj.name = name;
end
function move(obj, dx, dy)
obj.position = obj.position + [dx dy];
end
end
end
% Usage
r = Robot("R1");
r.move(1, 2);
r.position % [1 2]Q23How do you write unit tests in MATLAB?
IntermediateTesting
Answer
MATLAB has a built-in xUnit-style testing framework (R2013a+). Tests are functions in a `.m` file with a specific signature, or classes extending `matlab.unittest.TestCase`. Use the test runner via `runtests('mytests')` or `runtests('folder', 'IncludeSubfolders', true)` for CI integration.
Common matchers: `verifyEqual`, `verifyTrue`, `verifyError`, `verifyClass`, `verifyLessThan`. For fixtures and setup/teardown, the class-based form is required. CI integration is straightforward: jUnit XML output (`runtests(...
'OutputDetail', 'concise', ... )` plus the JUnit plugin) plugs into Jenkins or GitHub Actions. The MathWorks-hosted MATLAB Test (R2023a+) and CI-friendly action `matlab-actions/run-tests` are now standard in MATLAB-heavy repos. The distinction interviewers ask for is the qualification families: `verify*` records a failure and keeps going, `assert*` aborts the current test method because continuing would be meaningless, `assume*` marks the test filtered rather than failed (used to skip when a toolbox or a GPU is absent), and `fatalAssert*` aborts the entire run.
Floating-point comparisons need `verifyEqual(tc, actual, expected, 'AbsTol', 1e-10)` or `'RelTol'`, because bit-exact equality on doubles fails for reasons that have nothing to do with your code. Class-based tests unlock the rest: `TestMethodSetup` and `TestClassSetup` blocks, shared fixtures such as `PathFixture` and `TemporaryFolderFixture` that tear themselves down, and a `properties (TestParameter)` block that generates one test per parameter combination. For CI, build a `TestRunner` and attach plugins, `XMLPlugin.producingJUnitFormat` for the report and `CodeCoveragePlugin.forFolder` with Cobertura output for coverage, then run it headlessly with `matlab -batch "runtests('tests','IncludeSubfolders',true)"`, which exits non-zero on failure so the pipeline actually fails.
% file: testAdder.m
function tests = testAdder
tests = functiontests(localfunctions);
end
function testPositive(tc)
verifyEqual(tc, add(2, 3), 5);
end
function testNegative(tc)
verifyEqual(tc, add(-1, -2), -3);
end
function testError(tc)
verifyError(tc, @() add('a', 1), 'MATLAB:UndefinedFunction');
end
% Run
results = runtests('testAdder');Q24How do you profile MATLAB code for performance?
IntermediatePerformance
Answer
MATLAB has a built-in Profiler that times every function call, line, and built-in. Use `profile on`, run the code, then `profile viewer` to see an interactive report, colored hot lines, call counts, time per call. For micro-benchmarks, `timeit(@() myfunction(x))` runs the function many times and returns a robust mean, accounting for JIT warmup.
For memory profiling, R2024b's `memory` function reports MATLAB's address space usage on Windows, and the Profiler can now also track peak memory per function (enabled via `profile -memory on`). Common optimizations once you find a hot spot: vectorize, preallocate arrays with `zeros`, avoid growing arrays inside loops (the classic `mlint` warning), and switch built-ins where you can use a more specialized version (`*` to `\` for systems of linear equations rather than `inv`). State the caveats too.
The Profiler instruments rather than samples, so it adds per-call overhead that distorts code dominated by many tiny function calls and can make an already-slow helper look catastrophic; treat the ranking as reliable and the absolute numbers as not. Because it hooks every call, it also suppresses the in-place optimization and some JIT paths, so memory behavior under the Profiler is not identical to production. Use `profile('info')` to pull results out as a struct when you want to diff two runs in CI instead of eyeballing the HTML report.
For timing, prefer `timeit` over `tic`/`toc`, since a first `tic`/`toc` measures JIT compilation and file-system lookup rather than steady-state cost. And when the bottleneck turns out to be memory rather than CPU, the things to look for are array growth inside loops, copies forced by indexed assignment on a function's output, and fragmentation in long-running sessions, which `pack` no longer addresses on modern releases; restarting the worker is the honest answer.
profile -memory on;
myFunction(largeData);
profile viewer;
% Reliable micro-benchmark
t = timeit(@() myFunction(largeData));
fprintf('Avg time: %.3f ms\n', t * 1000);Q25How do you train a machine learning model in MATLAB?
IntermediateMachine Learning
Answer
The Statistics and Machine Learning Toolbox provides classical ML: `fitcsvm`, `fitctree`, `fitcensemble`, `fitcknn`, plus regression equivalents. There's also a Classification Learner app that lets you point-and-click through 20+ algorithms. For deep learning, the Deep Learning Toolbox provides `trainNetwork` (legacy) and `trainnet` (R2024a+, preferred), import from ONNX/TensorFlow/PyTorch via `importNetworkFromPyTorch` (R2024a+) or `importONNXNetwork`, and the Deep Network Designer app.
R2024b adds direct interop with Hugging Face Transformers via the `transformer` block. Why train ML in MATLAB instead of PyTorch? Tight integration with Simulink for deployment to embedded hardware (Speedgoat, NVIDIA Jetson via GPU Coder), and consistency with the rest of an engineering pipeline.
ISRO uses this workflow for image classifiers running on satellite hardware. What separates a real answer: use `cvpartition` with `crossval` and `kfoldLoss` instead of scoring on training data, because `resubPredict` accuracy is meaningless, and the snippet below reports exactly that inflated number for exactly that reason. Handle class imbalance through the `'Cost'` matrix or the `'Prior'` name-value pair on the `fitc*` functions, and report `confusionmat` or `confusionchart` rather than a single accuracy figure. `OptimizeHyperparameters` runs Bayesian optimization, so it needs a fixed `rng` seed plus `HyperparameterOptimizationOptions` with `'Kfold'` set if you want reproducible results.
On the deep learning side, know the modern stack: `dlnetwork` objects, `trainnet` driven by a `trainingOptions` object, `minibatchqueue` for custom input pipelines, and `dlarray` with `dlfeval`/`dlgradient` when you need a hand-written training loop with automatic differentiation. Models move both directions through ONNX via `exportONNXNetwork` and `importONNXNetwork`, and `analyzeNetwork` catches layer size mismatches before you burn an hour of GPU time on a run that was never going to work.
% Train an SVM classifier with hyperparameter tuning
load fisheriris
rng(42)
mdl = fitcsvm(meas, species, 'KernelFunction', 'rbf', ...
'OptimizeHyperparameters', 'auto');
pred = predict(mdl, meas);
acc = mean(strcmp(pred, species));
fprintf('Accuracy: %.2f%%\n', acc*100);Q26How do you solve an optimization problem in MATLAB?
IntermediateOptimization
Answer
The Optimization Toolbox provides solvers for the common problem classes: `fminunc` (unconstrained nonlinear), `fmincon` (constrained nonlinear), `linprog` (linear programming), `quadprog` (quadratic programming), `intlinprog` (mixed-integer linear), `lsqnonlin` (nonlinear least squares). The Global Optimization Toolbox adds `ga` (genetic algorithm), `simulannealbnd`, `particleswarm`, `surrogateopt`. Since R2017b, the problem-based workflow lets you define problems algebraically (`optimvar`, `optimproblem`) and MATLAB picks the solver automatically, cleaner than the solver-based API.
Common interview question: solve a small QP or LP problem (portfolio optimization, scheduling), or fit a nonlinear curve with `lsqcurvefit`. The follow-ups are about convergence, not syntax. Always inspect `exitflag` and the `output` struct rather than trusting the returned solution: a positive flag means a stopping criterion was met, `0` means the iteration or function-evaluation limit was hit, and negative values mean the solver failed or the problem is infeasible or unbounded.
Configure behavior with `optimoptions(@fmincon, 'Algorithm', 'interior-point', 'Display', 'iter', 'OptimalityTolerance', 1e-8)`, and know the algorithm choices: `interior-point` for large sparse constrained problems, `sqp` for smaller problems where every iterate must stay feasible, `trust-region-reflective` when you can supply gradients and only have bounds. Providing analytic derivatives with `'SpecifyObjectiveGradient', true` typically cuts function evaluations by an order of magnitude versus finite differences, and `checkGradients` verifies you derived them correctly. Scale your variables to similar magnitudes, because badly scaled problems stall long before they converge. Finally, `fmincon` returns a local minimum only, so on a non-convex objective either use `MultiStart`/`GlobalSearch` or switch to `ga`/`particleswarm`, and note `fzero` handles one-dimensional roots while `fsolve` handles systems.
% Problem-based: minimize x1^2 + x2^2 subject to x1+x2 >= 1
x = optimvar('x', 2, 'LowerBound', 0);
prob = optimproblem('Objective', sum(x.^2));
prob.Constraints.c1 = sum(x) >= 1;
sol = solve(prob);
disp(sol.x) % [0.5; 0.5]Q27What's the difference between scripts, functions, classes, and apps for MATLAB code organization?
IntermediateLanguage
Answer
**Scripts** (`.m` with no `function` line) are the simplest unit, they run top-to-bottom in the base workspace. Use them for analysis sessions and homework. **Functions** (`.m` starting with `function`) encapsulate reusable logic with their own workspace. Use them as the default unit of code. **Classes** (`classdef`) bundle data + behavior, use when you have stateful objects (a Robot, a Filter, a Session). **Apps** (`.mlapp` built in App Designer) are GUI applications with figure windows, buttons, plots.
Use App Designer for tools you ship to non-coders (calibration tool, parameter tuner). **Live Scripts** (`.mlx`) are for narrative analysis. **Packages** (folders starting with `+`) namespace code, avoiding global naming collisions in large codebases, `+myproject/+signal/filter.m` is called as `myproject.signal.filter(x)`. Two practical concerns sit underneath all of this. First, the search path: MATLAB resolves a name by checking variables, then nested and local functions, then private functions, then the current folder, then the path in order, so a file called `sum.m` sitting in your working folder shadows the built-in and produces failures that make no sense until you run `which -all sum`.
Packages prevent the problem outright. Prefer a Project or a `startup.m` that calls `addpath(genpath(...))` deliberately over scattered `addpath` calls inside scripts. Second, distribution: a reusable library should ship as a toolbox (`.mltbx`) built from a `.prj`, which installs into the user's add-on folder with the path configured and a version recorded, rather than as a zip everyone unpacks somewhere different. Class folders (`@ClassName/`) are a fourth organizational unit, useful when one class has many long methods, since each method can then live in its own file inside that folder while the `classdef` keeps only the signatures.
% +acme/+control/PidController.m -> acme.control.PidController
c = acme.control.PidController(1.2, 0.4, 0.05);
% Which file actually wins for a given name?
which -all sum
% Deliberate path setup, normally in startup.m
addpath(genpath(fullfile(projectRoot, 'src')));
% Class folder layout:
% @Filter/Filter.m (classdef + method signatures)
% @Filter/apply.m (one method per file)
% Open a project programmatically
proj = openProject('MyProject.prj');
disp(proj.Name);Q28What does the backslash operator `A\b` actually do, and why is `inv(A)*b` the wrong way to solve a linear system?
IntermediateNumerical Computing
Answer
`A\b` is `mldivide`, and it is not a single algorithm: it inspects the matrix and dispatches. For a square dense matrix it checks structure in order, using a triangular solve if the matrix is triangular, a Cholesky factorization if it is symmetric positive definite, and an LU factorization with partial pivoting otherwise. For sparse input it uses the sparse solvers in UMFPACK and CHOLMOD with a fill-reducing reordering.
For a non-square matrix it switches to QR and returns the least-squares solution, which is why `A\b` is also how you fit an overdetermined system. `inv(A)*b` is worse on all three counts that matter: it costs roughly three times the flops of an LU solve, it throws away the structure detection above, and it is numerically less accurate because forming the explicit inverse amplifies rounding error. If the matrix is ill conditioned you get `Warning: Matrix is close to singular or badly scaled. Results may be inaccurate.
RCOND = 2.1e-18`, and the right response is to inspect `cond(A)` and `rank(A)` rather than to suppress the warning. When you need to solve against many right-hand sides, do not refactorize each time: build a `decomposition(A)` object once (R2017b onward) and reuse it, which keeps the factorization and still selects the right algorithm. Genuinely singular systems need `pinv` or `lsqminnorm` instead.
A = rand(2000); b = rand(2000, 1);
x1 = A \ b; % LU with partial pivoting, one solve
x2 = inv(A) * b; % ~3x the work, less accurate
% Many right-hand sides: factor once, reuse
dA = decomposition(A);
for k = 1:100
X(:, k) = dA \ B(:, k);
end
% Overdetermined system -> least squares via QR
Atall = rand(500, 10);
xls = Atall \ rand(500, 1);
% Diagnose before trusting the answer
fprintf('cond = %.3e, rank = %d\n', cond(A), rank(A));
% Warning: Matrix is close to singular or badly scaled. RCOND = ...Key Points
- `\` dispatches on structure: triangular, Cholesky, LU, QR, sparse UMFPACK/CHOLMOD
- `inv(A)*b` costs more flops and loses accuracy; never use it to solve
- `RCOND` warning means ill conditioning, check `cond(A)` and `rank(A)`
- Reuse a `decomposition(A)` object for repeated right-hand sides
Q29How does `parfor` work and what code silently breaks inside it?
IntermediateParallel Computing
Answer
`parfor` (Parallel Computing Toolbox) splits loop iterations across the workers in a parallel pool started by `parpool`. Because iterations run in arbitrary order in separate processes, MATLAB statically classifies every variable in the loop body, and a variable it cannot classify is a compile-time error rather than a silent race. The classifications are: loop variable, sliced (indexed by the loop variable so each worker gets only its slice), broadcast (read-only, copied to every worker), reduction (combined with an associative operator such as `+` or `max`), and temporary (cleared each iteration).
The failures follow directly. Any dependency between iterations, such as `y(i) = y(i-1) + x(i)`, is rejected because it is not sliceable. Indexing with anything other than the plain loop variable, for example `A(idx(i))`, breaks slicing and MATLAB will refuse or serialize it. `break`, `return`, `global`, `eval` and `assignin` are not allowed.
Assigning to a broadcast variable inside the loop does not propagate back to the client. Randomness needs care: each worker has its own stream, so set `rng` per iteration or use `RandStream.create('mrg32k3a','NumStreams',...)` for reproducibility. Plotting or `fprintf` output from workers goes nowhere useful, so use `parallel.pool.DataQueue` with `afterEach` for progress.
The other real cost is data transfer: a large broadcast array is copied to every worker, which is what `parallel.pool.Constant` exists to avoid. For heterogeneous or asynchronous work use `parfeval` instead, and note `parpool('threads')` gives a lower-overhead thread pool for functions that support it.
parpool('Processes', 8);
big = loadCalibration(); % avoid copying per worker
c = parallel.pool.Constant(big);
q = parallel.pool.DataQueue;
afterEach(q, @(k) fprintf('done %d\n', k));
results = zeros(1, 1000); % sliced output
parfor i = 1:1000
rng(i); % reproducible per iteration
results(i) = process(c.Value, i); % results is sliced, c is broadcast
send(q, i);
end
% Rejected: results(i) = results(i-1) + 1; (iteration dependency)
% Rejected: results(idx(i)) = ...; (not sliceable)
f = parfeval(@process, 1, big, 42); % asynchronous alternative
out = fetchOutputs(f);Key Points
- Variables are classified as loop, sliced, broadcast, reduction or temporary
- Iteration dependencies and non-loop-variable indexing are rejected
- `parallel.pool.Constant` avoids copying big data to every worker
- `DataQueue` + `afterEach` for progress; `parfeval` for async work
Q30How do you validate function inputs with the `arguments` block?
IntermediateLanguage
Answer
The `arguments` block (R2019b onward) declares input validation declaratively at the top of a function, and it replaces the older stack of `nargin` checks, `inputParser` objects and `validateattributes` calls. Each entry has the form `name (size) class {validators} = default`. The size specification is checked and, where legal, coerced, so `(1,1) double` accepts a scalar and rejects a vector while `(1,:) string` accepts a row of strings.
The class specification also converts when conversion is unambiguous, which means declaring `string` and passing a char array gets you a `string` without writing the cast. Validator functions run last: `mustBePositive`, `mustBeNonnegative`, `mustBeInteger`, `mustBeMember(x, ["linear","spline"])`, `mustBeFinite`, `mustBeNonempty`, `mustBeA`, and you can write your own as a function that errors on bad input. Giving a default makes the argument optional, and every optional positional argument must follow the required ones.
Name-value pairs go in a separate `arguments (Input)` block marked with the `options.Name` pattern, which is how you get the tab-completion and error messages users expect from built-in functions. Two more forms are worth knowing: `arguments (Repeating)` for functions that accept a variable-length list of grouped arguments, and `arguments (Output)` (R2022b onward) for validating what you return. The payoff beyond terseness is the error messages, which name the offending argument and the failing validator instead of surfacing a confusing failure ten frames deeper in your code.
function y = smoothSignal(x, window, options)
arguments
x (1,:) double {mustBeNonempty, mustBeFinite}
window (1,1) double {mustBeInteger, mustBePositive} = 5
options.Method (1,1) string {mustBeMember(options.Method, ...
["movmean","movmedian","gaussian"])} = "movmean"
options.Verbose (1,1) logical = false
end
if options.Verbose
fprintf('Smoothing %d samples, window %d\n', numel(x), window);
end
y = smoothdata(x, options.Method, window);
end
% smoothSignal(data, 7, Method="gaussian", Verbose=true)
% smoothSignal(data, -1)
% -> Value must be positive. (names the argument, not a stack trace)Q31When does MATLAB still win over Python (NumPy/SciPy) and when should you migrate?
AdvancedEcosystem
Answer
MATLAB still wins decisively in: (1) **Simulink + model-based design**, there is no Python equivalent for graphical modeling of dynamic systems that auto-generates production C code via Embedded Coder. Every Tier-1 automotive supplier in India (Bosch, Continental, ZF, Magna) runs on Simulink. (2) **Hardware-in-the-Loop and code generation**, Speedgoat targets, Xilinx HDL Coder, dSpace integration, NXP/Freescale embedded targets all have first-class MATLAB support. (3) **Established research and textbook code**, decades of algorithms in signal processing, controls, and communications were written in MATLAB; rewriting in Python often isn't worth it. (4) **Validated toolboxes for regulated industries**, DO-178C (avionics) and ISO 26262 (automotive) certification credits for code generation. Migrate to Python when: data science / ML is the primary workload, deployment scale is large (1000s of servers), or your team is more comfortable in Python.
The pragmatic 2026 answer: use MATLAB for modeling and algorithm prototyping, deploy via Python wrappers or C code generation for production. This hybrid is now the standard at ISRO and DRDO for ML on embedded hardware. One more axis interviewers care about is cost and deployment topology.
A MATLAB seat plus the four or five toolboxes a real project needs is a recurring per-developer licence cost, and the licence check is a runtime dependency, so fanning out to a hundred containers means either MATLAB Production Server licences or compiled artifacts carrying MATLAB Runtime. Python has no such gate, which is why the boundary in most Indian R&D teams now falls at the handoff point rather than at the algorithm. Say that explicitly, then give the migration test you would actually apply: if the deliverable is a certified binary running on a target board, keep it in MATLAB and Simulink; if the deliverable is a service that scales horizontally, port the algorithm or wrap it and let the wrapper be the only MATLAB-licensed thing in the system.
Key Points
- Simulink for model-based design has no Python equivalent
- Embedded code generation (Embedded Coder, HDL Coder) is unmatched
- Heavy in automotive (Bosch, Continental, Tata), aerospace (ISRO, HAL, DRDO)
- DO-178C / ISO 26262 certification credits exist for MATLAB-generated code
- Common 2026 pattern: MATLAB for algorithms + Python for deployment
Q32How does MATLAB store multi-dimensional arrays in memory, and why does it matter?
AdvancedMemory
Answer
MATLAB uses column-major (Fortran-style) storage: in a 2D matrix `A(i, j)`, columns are contiguous in memory. So `A(1,1)`, `A(2,1)`, `A(3,1)`, ..., `A(1,2)`, `A(2,2)`, ... is the memory order. Compare to NumPy / C which is row-major by default.
Consequences: (1) `A(:)` flattens column-by-column, `[A(1,1); A(2,1); A(1,2); A(2,2)]` for a 2x2. (2) For-loops iterating columns-then-rows (`for j ... for i ...`) are dramatically faster than rows-then-columns, due to cache locality. (3) When interfacing with C/Fortran libraries via MEX, you don't need to transpose if the target is column-major (Fortran/LAPACK); you do need to transpose for row-major C arrays. (4) When passing data between MATLAB and Python (numpy), MATLAB's column-major and numpy's default row-major mean `A` in MATLAB becomes `A.T` in numpy unless you explicitly handle it. This is a frequent source of subtle bugs at the MATLAB/Python interop boundary. Two further consequences are worth naming.
First, `reshape` and `A(:)` are essentially free because they reinterpret the existing column-major buffer, whereas a transpose is not free: `A'` physically reorders memory, so `sum(A, 2)` on a wide matrix beats `sum(A', 1)` even though both give the same numbers. Second, when you must hand an array to a row-major consumer, do it explicitly with `permute` and document the convention, rather than relying on a lucky transpose that breaks the moment the array grows a third dimension. Inside a MEX file, `mxGetDoubles` hands you the raw column-major pointer, so you index it as `p[i + j*nrows]`; writing `p[i*ncols + j]` compiles cleanly and silently transposes your data, which is the single most common MEX bug. The same rule governs `fread` and `fwrite`, which fill and drain arrays in column order, so reading an image that a C program wrote row-wise needs a `reshape` to the transposed size followed by a transpose.
A = [1 2 3; 4 5 6];
A(:) % [1; 4; 2; 5; 3; 6], column-major
% Cache-friendly traversal
for j = 1:size(A,2) % outer: columns
for i = 1:size(A,1) % inner: rows
% access A(i,j), sequential in memory
end
endQ33How do you deploy a MATLAB algorithm to production at scale?
AdvancedDeployment
Answer
Three deployment paths depending on the target: (1) **MATLAB Compiler** packages MATLAB code into standalone executables, .NET assemblies, Java JAR files, or Python packages. End users run them without a MATLAB license but need the MATLAB Runtime (free, ~2GB). Use for: desktop tools, batch processing on a few servers. (2) **MATLAB Production Server** wraps MATLAB functions as REST/RPC endpoints, your web app or microservices call MATLAB over HTTP.
Use for: high-throughput web-facing services with MATLAB-built algorithms. Banks and risk analytics teams use this. (3) **MATLAB Coder / GPU Coder / HDL Coder** generates standalone C, CUDA, or HDL code, no runtime, no license dependency. Use for: embedded devices, FPGAs, microcontrollers.
ISRO uses HDL Coder for radar signal processing on space-grade FPGAs, Tata Elxsi uses Embedded Coder + AUTOSAR for ECU code. The 2026 trend: package as Python wheels via Compiler SDK and let DevOps treat the algorithm as a regular Python dependency, with the runtime bundled in a Docker base image. Details that matter in practice: the MATLAB Runtime version must match the release that compiled the artifact exactly, so an R2025a build will not run against an R2024b runtime, and you version-pin it in the image rather than installing 'latest'.
Not everything compiles. `mcc` rejects scripts as entry points, rejects `eval` of code that is not statically reachable, and rejects anything requiring the desktop, so a deployable entry point is a function whose entire dependency graph can be resolved at build time. A handful of toolbox functions carry deployment restrictions or are simply not deployable, and `mcc -v` reports that at build time instead of leaving you to discover it in production. For Production Server, functions are stateless by design, so per-request state must travel in the payload or live in an external store, and you size capacity by worker count rather than by threads.
Key Points
- MATLAB Compiler: standalone .exe / .py / .jar with bundled MATLAB Runtime
- MATLAB Production Server: REST/RPC endpoint for web-scale
- MATLAB Coder / GPU Coder / HDL Coder: C/CUDA/HDL with no runtime
- Pick path based on target: desktop vs web vs embedded vs FPGA
Q34How does Simulink's solver actually solve a continuous-time model, and how do you pick the right one?
AdvancedSimulink
Answer
Simulink models that contain continuous-time blocks (integrators, transfer functions) become a system of ODEs that the solver integrates over the simulation time. Solvers split into: **Fixed-step** (constant `Δt`, deterministic timing, required for code generation to embedded hardware, real-time simulation in Speedgoat) and **Variable-step** (adaptive `Δt`, more efficient for desktop simulation but non-deterministic). Within each, you pick by stiffness: non-stiff systems use explicit methods like `ode45` (Dormand-Prince) or `ode23`; stiff systems (large eigenvalue spread, fast and slow dynamics together) need implicit methods like `ode15s` or `ode23s`.
Pick wrong and you get either wrong results (`ode45` on stiff systems takes microscopic steps and may diverge) or wasted compute (`ode15s` on simple systems is overkill). Discrete-only models (digital control loops, fixed sample time) just use the FixedStepDiscrete solver. For HIL on Speedgoat, you must use a fixed-step solver, typically `ode4` (RK4) or `ode1` (Euler).
R2024b added a new local solver feature that lets different subsystems use different solvers, useful for mixed-fidelity models. Know the knobs and the symptoms. You set them from code with `set_param`, and for variable-step runs you should tune `RelTol` (default `1e-3`) and `AbsTol` before reaching for a different solver, because most accuracy complaints are tolerance problems rather than solver-choice problems.
If the diagnostic viewer fills with `Derivative of state ... is not finite`, or the step size collapses toward the minimum with a warning that the solver is taking a very small time step, that is stiffness or a discontinuity, not an arithmetic bug. Zero-crossing detection is the other classic failure: models containing switches, saturation or relay blocks can chatter at a discontinuity and stall the simulation, which you fix by disabling zero-crossing on the offending block, adding hysteresis, or moving to a fixed-step solver. And on a real-time target the step is a hard budget: the fixed step must exceed the measured task execution time or you get task overruns.
mdl = 'myPlant';
load_system(mdl);
% Desktop simulation of a stiff plant
set_param(mdl, 'SolverType', 'Variable-step', 'Solver', 'ode15s', ...
'RelTol', '1e-6', 'AbsTol', '1e-8');
% Real-time / code-generation target: fixed-step RK4 at 1 kHz
set_param(mdl, 'SolverType', 'Fixed-step', 'Solver', 'ode4', ...
'FixedStep', '0.001');
% Parameter sweep, parallel-ready via parsim
simIn = Simulink.SimulationInput(mdl);
simIn = simIn.setVariable('Kp', 2.5);
out = sim(simIn);
plot(out.tout, out.yout{1}.Values.Data);Q35How do you architect a large MATLAB codebase for a team of 20+ engineers?
AdvancedArchitecture
Answer
Treat MATLAB code like any other large codebase. (1) **Packages**: use `+namespace/` folders to namespace everything, `+acme/+control/PidController.m` called as `acme.control.PidController(...)`. Avoid global naming collisions across 20 engineers and 200 functions. (2) **Project files** (`.prj`, R2017a+): MATLAB Projects manage path setup, startup/shutdown, dependency analysis, and integrate with Git for branching. Every team should have a `.prj` checked in. (3) **Unit + integration tests** via the `matlab.unittest` framework, run in CI on every PR.
The `matlab-actions/run-tests` GitHub Action makes this trivial. (4) **Code style**, install MISS_HIT or use `checkcode`/MLINT for linting; pre-commit hooks reject violations. (5) **Compiled artifacts**, for Simulink models, use Referenced Models (`.slxp`) to break a 50,000-block monolith into modular subsystems each engineer owns. Toolbox dependencies declared via `requirements.json` in newer MATLAB versions, or pinned via Project. (6) **Documentation**, Live Scripts with `matlab.internal.liveeditor.openAndConvert` exports to HTML for the docs site. (7) **API stability**, flag internal functions with `+internal` packages so callers can tell what's public. This is the architecture MathWorks themselves use internally for their toolboxes, and what large MATLAB shops in India (Bosch India, Honeywell HTC) replicate.
Add two governance items that teams usually learn the hard way. Pin the release: everyone on a branch must run one agreed MathWorks release, because an `.slx` saved in a newer release cannot be opened in an older one and 'Export to Previous Version' only reaches back a limited number of releases, so one engineer upgrading early can block the whole team mid-sprint. And guard the merge boundary on models, because a text merge on `.slx` is meaningless: you compare and merge through `visdiff` and the Simulink three-way merge tool, and you keep individual models small enough that two engineers rarely touch the same one, which is the real practical argument for model referencing over a single monolith.
% Layout
% MyProject.prj
% src/+acme/+control/PidController.m
% src/+acme/+internal/clampGain.m
% tests/tPidController.m
proj = openProject('MyProject.prj');
% What does this file actually depend on, before you refactor it?
[files, products] = matlab.codetools.requiredFilesAndProducts( ...
'src/+acme/+control/PidController.m');
% CI entry point (matlab-actions/run-tests runs the equivalent)
% matlab -batch "runtests('tests','IncludeSubfolders',true)"
% Model diff, since text merges are useless on .slx
visdiff('controller_main.slx', 'controller_rev2.slx');Key Points
- Packages (`+name/`) for namespacing in large teams
- MATLAB Projects (`.prj`) for path + dependency management
- matlab.unittest + GitHub Action for CI
- Referenced Models (`.slxp`) to modularize large Simulink models
- MISS_HIT / checkcode for linting, pre-commit hooks
Q36How do you write, build and debug a MEX file that calls C or C++ from MATLAB?
AdvancedInterop
Answer
A MEX file is a shared library MATLAB loads and calls like a function. In the C API you write a `mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])` gateway, validate `nrhs` and `nlhs` yourself, pull data out with `mxGetDoubles` or `mxGetComplexDoubles`, allocate outputs with `mxCreateDoubleMatrix`, and report problems through `mexErrMsgIdAndTxt('acme:badInput', ...)` so the caller sees a normal MATLAB error with a catchable identifier. The version detail interviewers look for is the complex API change: before R2018a, complex arrays lived in separate real and imaginary buffers reached through `mxGetPr` and `mxGetPi`, and from R2018a the default is the interleaved complex API where the parts alternate in one buffer and `mxGetPi` is gone.
Building with `mex -R2017b` selects the old layout and `mex -R2018a` the new one, so legacy sources calling `mxGetPi` fail to compile until you port them or pass the compatibility flag. There is also a modern C++ interface where you subclass `matlab::mex::Function` and use `matlab::data::ArrayFactory`, which is type safe and avoids the raw `mxArray` pointer style entirely. Check your toolchain with `mex -setup`, and keep two MEX-specific failure modes in mind: an out-of-bounds write corrupts MATLAB's heap and takes down the whole session with a segmentation violation report rather than a catchable error, and memory from `mxMalloc` held in a persistent structure is freed when the MEX file is cleared, so state that must survive between calls needs `mexMakeMemoryPersistent` plus a `mexAtExit` handler. Build with `mex -g` to keep symbols and attach gdb or Visual Studio to the MATLAB process.
/* addTwo.c : y = addTwo(x, k) */
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
if (nrhs != 2)
mexErrMsgIdAndTxt("acme:nrhs", "Two inputs required.");
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]))
mexErrMsgIdAndTxt("acme:type", "Input must be real double.");
mwSize n = mxGetNumberOfElements(prhs[0]);
double *x = mxGetDoubles(prhs[0]); /* R2018a interleaved API */
double k = mxGetScalar(prhs[1]);
plhs[0] = mxCreateDoubleMatrix(1, n, mxREAL);
double *y = mxGetDoubles(plhs[0]);
for (mwSize i = 0; i < n; i++) y[i] = x[i] + k;
}
%% From MATLAB:
% mex -setup C
% mex -R2018a -g addTwo.c
% addTwo([1 2 3], 10) -> [11 12 13]Key Points
- `mexFunction` gateway; validate `nrhs`/`nlhs` before touching `prhs`
- Interleaved complex API is the default from R2018a; `mxGetPi` is gone
- `mex -R2017b` vs `mex -R2018a` selects the complex storage layout
- Out-of-bounds writes crash the MATLAB session, they do not throw
- Modern alternative: C++ `matlab::mex::Function` with `ArrayFactory`
Q37How do you process a dataset that does not fit in memory?
AdvancedBig Data
Answer
Four mechanisms, chosen by access pattern. First, `datastore` presents a collection of files as one logical dataset: `tabularTextDatastore`, `parquetDatastore`, `imageDatastore`, `fileDatastore` for a custom reader. You call `read` for one chunk at a time, `preview` to inspect the schema without reading anything, and `readall` only when you already know it fits.
Second, `tall` arrays wrap a datastore and give an array-like interface where operations are queued rather than executed: you write ordinary code such as `mean(t.price)`, nothing runs until `gather` triggers a pass over the data, and MATLAB reports how many passes it needed. Gathering several results in one `gather` call collapses them into a single pass, which is the main performance lever. Not every function has a tall implementation, so unsupported calls fail at queue time rather than an hour in.
With Parallel Computing Toolbox the same tall code runs across a pool, and with MATLAB Parallel Server it runs on a Spark or Hadoop cluster unchanged. Third, the `matfile` object gives random access into a `-v7.3` MAT file, so `m.data(1:1000, :)` reads only that slice from disk; this needs v7.3 because the default v7 format must inflate the entire variable. Fourth, `memmapfile` maps a raw binary file into the address space and lets the OS page it in on demand, which suits large fixed-layout sensor captures. If none of those fit, chunk explicitly with `blockproc` for images or a loop over `read(ds)`, and drop to `single` where the accuracy budget allows, since that halves the footprint immediately.
% 1. Datastore over a folder of CSVs
ds = tabularTextDatastore('data/*.csv', 'TreatAsMissing', 'NA');
ds.SelectedVariableNames = {'timestamp', 'sensor1', 'sensor2'};
preview(ds)
% 2. Tall array: nothing executes until gather
t = tall(ds);
mu = mean(t.sensor1, 'omitnan');
nHigh = sum(t.sensor2 > 100);
[muVal, nVal] = gather(mu, nHigh); % ONE pass computes both
% 3. Random access into a -v7.3 MAT file
save('big.mat', 'data', '-v7.3');
m = matfile('big.mat', 'Writable', true);
chunk = m.data(1:1000, :); % reads only this slice
m.data(1:1000, :) = chunk * 2;
% 4. Memory-map a raw binary capture
mm = memmapfile('capture.bin', 'Format', 'int16');
first = mm.Data(1:2048); % pages in only what you touchKey Points
- `datastore` for file collections, `tall` for deferred array math
- Gather multiple results in one `gather` call to force a single pass
- `matfile` random access requires `-v7.3` (HDF5), not the default v7
- `memmapfile` for raw fixed-layout binary; `blockproc` for large images
Q38How do you debug a MATLAB job that fails intermittently on a server but runs fine on your machine?
AdvancedDebugging
Answer
First make the failure observable, because you cannot attach a debugger to a batch job. Reproduce the server environment locally with `matlab -batch "main"`, which behaves differently from an interactive session: no desktop, a non-zero process exit code on an uncaught error, and `input`, `keyboard` or `uiwait` hanging or failing instead of pausing. Wrap the entry point in `try`/`catch` and log `getReport(ME, 'extended')`, which prints the message, the identifier and the full stack with line numbers, then `rethrow` so the exit code still signals failure.
For anything you can reproduce locally, `dbstop if error` breaks at the throw site with the workspace intact, `dbstop if naninf` catches the first NaN or Inf rather than the symptom fifty lines later, and a conditional breakpoint such as `dbstop in solver at 42 if k > 1000` skips the healthy iterations; `dbstack`, `dbup` and `dbdown` walk the frames. Then go looking for environment drift, which is where server-only intermittency almost always lives: an unseeded generator so nothing is reproducible (fix with `rng(seed, 'twister')` at entry), a different search path so a stale file shadows the right function (log `which -all` for the suspects and `ver` for toolbox versions), a licence checkout failing under concurrency, `pwd`-relative paths resolving differently under a scheduler, timezone and locale differences that move `datetime` results, and memory exhaustion that only happens when several jobs land on one host. On a parallel pool, worker errors surface through `getReport` on the future object, and `diary` or a `DataQueue` is the only way to get worker logs back at all.
function main()
try
rng(20260812, 'twister'); % reproducible across hosts
cfg = loadConfig(fullfile(getenv('JOB_ROOT'), 'cfg.json'));
runPipeline(cfg);
catch ME
fid = fopen('failure.log', 'a');
fprintf(fid, '%s | %s\n%s\n', ...
char(datetime('now', 'TimeZone', 'UTC')), ...
ME.identifier, getReport(ME, 'extended'));
fclose(fid);
rethrow(ME); % keep the non-zero exit code
end
end
%% Reproduce the server environment locally
% matlab -batch "main"
%% Interactive hunting
dbstop if error
dbstop if naninf
dbstop in runPipeline at 42 if k > 1000
%% Environment drift is the usual culprit
ver
which -all loadConfigQ39What breaks when you run MATLAB code through MATLAB Coder, and how do you fix it?
AdvancedCode Generation
Answer
`codegen` compiles a subset of the language to C or C++, and the subset is the whole difficulty. Everything must be statically typed and statically sized at compile time, so Coder first needs the input types, supplied with `codegen myfun -args {zeros(1,100), 0}` or a `coder.typeof` specification. Variables cannot change class or shape between assignments: one that is `double` on one branch and `logical` on another fails with a type mismatch, and one that is 1x10 on one branch and 1x20 on another needs `coder.varsize('y', [1 100000], [false true])` to declare an upper bound and which dimensions vary.
Cell arrays must be homogeneous or have a compile-time-known structure. Dynamic features are simply out: `eval`, `assignin`, `inputname`, dynamic field names, `load` and `save`, most graphics, and anything requiring the interpreter. Toolbox coverage is partial and the documentation marks which functions support code generation, so the fix for a call that only matters during simulation is `coder.extrinsic('plot')`, which calls back into MATLAB in MEX mode and becomes a no-op in standalone code.
Recursion is restricted, `containers.Map` and string support are limited, and integer overflow behavior is configurable between saturating and wrapping, which can make generated results differ from the interpreted run. The workflow that avoids surprises: annotate the entry function with `%#codegen` so the editor lints against the subset continuously, run the Code Generation Readiness tool, generate a MEX with `-report` first and diff its output against the interpreted version on the same inputs, and only then generate standalone C with a `coder.config('lib')` configuration for the target.
function y = movingRms(x, win) %#codegen
% x arrives as variable-length single, win as a scalar double
coder.varsize('y', [1 100000], [false true]);
n = numel(x);
y = zeros(1, n, 'single');
for i = 1:n
lo = max(1, i - win + 1);
y(i) = sqrt(mean(x(lo:i).^2));
end
end
%% Step 1: MEX first, then diff against the interpreted result
% codegen movingRms -report ...
% -args {coder.typeof(single(0), [1 Inf]), 0}
% max(abs(movingRms(x, 16) - movingRms_mex(x, 16)))
%% Step 2: standalone C for the target
cfg = coder.config('lib');
cfg.TargetLang = 'C';
cfg.GenerateReport = true;
% codegen -config cfg movingRms -args {coder.typeof(single(0), [1 Inf]), 0}Key Points
- Types and sizes must be static; declare growth with `coder.varsize`
- `eval`, dynamic fields, `load`/`save` and most graphics are unsupported
- `coder.extrinsic` defers a call to MATLAB in MEX mode, no-op in standalone
- Always generate MEX with `-report` and diff against interpreted output first
Q40How do you manage MATLAB release upgrades across a team, and what actually breaks?
AdvancedVersioning
Answer
MathWorks ships two releases a year, Ra in March and Rb in September, and upgrading is a coordinated project rather than an individual choice, because the artifacts are not backward compatible. Take the hard constraints first. A Simulink `.slx` saved in a newer release cannot be opened in an older one, and 'Export to Previous Version' only reaches back a limited number of releases, so one engineer upgrading early can lock the rest of the team out of a model mid-sprint.
A compiled artifact demands the exact matching MATLAB Runtime, so an upgrade means rebuilding and redeploying every compiled component and bumping the runtime layer in your container images. MEX binaries must be rebuilt against the new release's API, and the list of supported compilers moves between releases too. Inside the language, breakage is usually a function that was marked 'not recommended' several releases earlier and has finally been removed, which is exactly what the compatibility considerations section of the release notes exists to list.
Gate release-specific code with `isMATLABReleaseOlderThan("R2025a")` (R2020b onward) rather than parsing `version` strings or using the older `verLessThan`. The process that works: pin one release per branch and record it in the Project, keep the previous release installed side by side since MathWorks supports that, add the candidate release as an extra CI job and get the full test suite green before flipping the default, log `matlabRelease` output with every build so a failure can be traced to a release, and confirm the licence actually covers the new release, since a lapsed maintenance contract means you cannot legally install it.
% Gate release-specific behavior (isMATLABReleaseOlderThan: R2020b+)
if isMATLABReleaseOlderThan("R2024a")
net = trainNetwork(X, Y, layers, opts); % legacy API
else
net = trainnet(X, Y, layers, "crossentropy", opts);
end
% Log the environment with every run so failures are traceable
r = matlabRelease;
fprintf('%s on %s\n', r.Release, computer);
ver('signal')
%% CI matrix: prove the next release green before making it default
% strategy:
% matrix:
% release: [R2025b, R2026a]
% steps:
% - uses: matlab-actions/setup-matlab@v2
% with: { release: '${{ matrix.release }}' }
% - uses: matlab-actions/run-tests@v2
%% Simulink: save a copy an older release can still open
% Save > Export to Previous Version > R2025aKey Points
- `.slx` is forward-only; 'Export to Previous Version' reaches back a limited number of releases
- Compiled artifacts need the exact matching MATLAB Runtime; rebuild MEX too
- Read the release notes' compatibility considerations for removed functions
- Use `isMATLABReleaseOlderThan`, not `verLessThan` or `version` parsing
- Pin one release per branch; run the candidate release as a separate CI job
Frequently Asked Questions
Is MATLAB still relevant in 2026 given Python's dominance?
Yes, in specific domains. MATLAB remains dominant in control systems, signal processing R&D, model-based embedded design, and engineering education. Simulink has no equivalent in the Python ecosystem for production embedded code generation. For pure data science / ML / web work, Python is the better choice, but for an engineer working on automotive ECUs, satellite GNC, radar systems, or biomedical signals, MATLAB is still daily-driver software in 2026.
How much does a MATLAB engineer earn in India?
₹5-16 LPA in 2026, with the range depending on domain. Entry-level (0-2 yrs, fresh BTech) at automotive Tier-1s like Bosch, Continental: ₹5-8 LPA. Mid-level (3-6 yrs) in control systems / signal processing: ₹10-16 LPA. Specialized roles in defense (DRDO, HAL), ISRO, and MathWorks Bangalore itself can pay more, especially with combined MATLAB + Simulink + embedded code generation skills. The premium is for engineers who can do model-based design end-to-end, not just MATLAB scripting.
Should I learn MATLAB or Python first as an engineering student in India?
Learn MATLAB if your curriculum or target role demands it, most NIT/IIT engineering programs (mechanical, electrical, electronics) still teach in MATLAB and your lab assignments will require it. Learn Python alongside for general programming and data science. The two are complementary; many engineers use MATLAB for algorithm development and Python for data wrangling. Job openings at ISRO, DRDO, Bosch, Mahindra, Tata Motors specifically ask for MATLAB/Simulink expertise.
What is new in MATLAB R2024b?
R2024b (September 2024) added: an AI-assisted Live Editor with code suggestions and explanation; `trainnet` as the preferred deep learning training API replacing `trainNetwork`; expanded GPU coverage in image processing; FP16 support for deep learning; the transformer block for Hugging Face interop; local solvers in Simulink that let subsystems use different ODE solvers; and improved package management via project requirements. The Compiler SDK for Python now produces wheels directly installable via pip with bundled runtime. Since then MathWorks has continued its usual cadence of two releases a year, Ra in March and Rb in September, so a 2026 interviewer is likely standardized on R2025b or R2026a. Ask which release the team runs before you quote feature names, because function availability, supported Python versions and Simulink model compatibility are all release-gated, and read that release's compatibility considerations rather than reciting a feature list.
Can I use MATLAB without a license?
Officially no, MATLAB is proprietary commercial software. Free alternatives: MATLAB Online has a free tier with limited hours. GNU Octave is the most compatible free-and-open clone but lacks Simulink and most toolboxes. For students at most Indian engineering colleges, a campus license is included in your fees. Don't ship code in production using cracked licenses, MathWorks audits, and certifying agencies (FAA, ISO) won't accept results from unlicensed MATLAB.
How long does it take to prepare for a MATLAB interview?
If you already write MATLAB regularly, two to three weeks of focused revision is realistic: one week on the language itself (indexing, vectorization, cell arrays versus structs versus tables, copy-on-write semantics), one week on whichever toolbox the job description actually names, and a few days of timed practice writing code in a shared editor with no autocomplete. If your only MATLAB has been college lab work, budget six to eight weeks, because the gap in interviews is not syntax, it is being able to explain why `filtfilt` doubles the effective filter order or why `inv(A)*b` is the wrong way to solve a linear system. For Simulink and model-based design roles, add two weeks on solver selection, sample times and code generation, since those interviews usually include a modeling exercise rather than a coding round.
What does a MATLAB interview look like for a fresher versus someone with 5 years of experience?
A fresher round runs 45 to 60 minutes: matrix manipulation on the spot, vectorizing a loop, a plotting or file-reading task, and a project walkthrough where the interviewer checks you understand the algorithm rather than just the function name you called. Expect 1-based indexing, `*` versus `.*`, and cell arrays versus structs to come up almost every time. At 4 to 6 years the questions shift to judgment: why you chose a fixed-step over a variable-step solver, how you debugged a model that only failed on the hardware target, how you organized code and tests for a team, how you validated a controller before release. Experienced candidates also get asked about the boundary with C and Python, because at that level you are expected to own the handoff from prototype to production, not only the prototype.
MATLAB, Simulink, embedded C or Python: which combination pays more in India?
Pure MATLAB scripting is the lowest-paid version of this skill, roughly ₹5-8 LPA at entry. Pay steps up with each adjacent skill you stack on it. MATLAB plus Simulink and model-based design moves you into the automotive and aerospace band. Adding embedded C, AUTOSAR or Embedded Coder experience is what pushes engineers past ₹15 LPA at Tier-1 suppliers, because those teams hire for the whole model-to-ECU path rather than for modeling alone. Adding Python is worth less in direct salary terms but widens the market considerably, since it opens data and ML roles that MATLAB by itself will not. The pattern to internalize: MATLAB is a multiplier on a domain (control systems, signal processing, RF, power electronics), not a standalone career track, and job posts price the domain first.
Introduction
MATLAB (Matrix Laboratory) remains the language of choice for engineers and researchers working on signal processing, control systems, image processing, and model-based design in 2026. Despite Python's rise in data science, MATLAB still dominates in aerospace, automotive R&D, communications, and academic research, particularly across IITs, NITs, ISRO, DRDO, and Indian engineering colleges where it is taught from undergraduate level.
If you are interviewing for a MATLAB role in India today, expect questions on matrix operations, vectorization (the difference between an idiomatic MATLAB engineer and a slow C-programmer-writing-MATLAB), the major toolboxes (Signal Processing, Image Processing, Control Systems, Optimization, Machine Learning), Simulink for model-based design, and the new features in R2024b including the AI assistant, exported Python interop, and GPU acceleration.
This guide covers the 40 most-asked MATLAB interview questions in 2026, grouped by difficulty (14 basic, 16 intermediate, 10 advanced). Each answer includes the underlying concept, common gotchas (1-based indexing, column-major layout, copy-on-write semantics), the error messages you will actually see, and code examples where they add clarity. Note that MathWorks ships two releases a year, Ra in March and Rb in September, so an interviewer in 2026 may be standardized on R2025b or R2026a; function availability and Simulink file compatibility are release-gated, so it is always worth asking which release the team runs.
Ready to practice MATLAB interviews?
Don't just read, practice these MATLAB questions live with an AI interviewer that asks follow-ups and scores your answers.