Statistic & Probability Models
Statistics turns data you happened to collect into claims about a world you did not observe; probability is the machinery that makes those claims auditable. This post is a single self-contained pass over the foundation — the axioms, random variables, the distribution zoo, the limit theorems, estimation, hypothesis testing (including the two definitions everyone botches), regression, and the exact point where classical statistics becomes machine learning. Written for engineers who already write code and now need to reason about uncertainty without hand-waving. Every number below has been checked and is reproducible with and .
Learning Outcome
- Apply the probability axioms, conditional probability, independence, the law of total probability and Bayes' theorem to a real diagnostic problem, and see the base-rate fallacy numerically.- Work with random variables through PMF / PDF / CDF, and compute expectation, variance, covariance and correlation from their algebraic properties.- Pick a distribution from the standard zoo by its generating mechanism, and state the law of large numbers and the central limit theorem precisely — including what the CLT does not claim.- Derive a maximum-likelihood estimator from scratch, and say correctly what a 95% confidence interval means.- Run the standard tests, state a p-value correctly, correct for multiple comparisons, and prefer effect sizes to bare significance.- Fit and diagnose linear and logistic regressions, and describe the bias–variance trade-off separating models built to explain from models built to predict.
Chapter 1 — Probability foundations
Terminology
- Sample space (Ω) — the set of all possible outcomes. One die: .- Event — any subset of Ω. "The roll is even" is .- Probability measure (P) — assigns a number in to each event, obeying the axioms.- Mutually exclusive (disjoint) — , the events cannot both occur. Exhaustive — a collection whose union is all of Ω.- Independent — knowing one event occurred tells you nothing about the other.
The axioms (Kolmogorov, 1933)
> Watch out: the addition rule loses its correction term only when the events are disjoint. is a special case, not the general rule.
Counting
When every outcome in a finite Ω is equally likely, and the problem is pure counting. The only question is whether order matters: for ordered selections, for unordered, and for independent stages.
- Three distinct medals among 10 runners (ordered) is ; a three-person committee from the same 10 (unordered) is .- Five-card poker hands: . A flush (any suit, straight flushes included) is — about 0.198%.- Birthday problem: gives 0.5073 at and 0.9704 at . 23 people beats a coin flip because they generate pairs, not 23 opportunities.
Conditional probability and independence
Roll two fair dice. = "sum is 8" (: 2-6, 3-5, 4-4, 5-3, 6-2), = "first die is 3" (), = {3-5} (). So — not independent.
> Common pitfall: mutually exclusive and independent are near-opposites, not synonyms. Disjoint events with positive probability satisfy , so they are maximally dependent.
Law of total probability and Bayes' theorem
If partition Ω then . Two factories: F1 makes 70% of units at a 2% defect rate, F2 makes 30% at 5%, so .
Read it as an update: prior , likelihood , posterior . Which factory made a defective part? and — F2 makes under a third of the parts but is the more likely source of any given defect.
The medical test and the base-rate fallacy
A disease affects 0.5% of the population. A test has 99% sensitivity () and 95% specificity (so a 5% false-positive rate). You test positive. What is ? Natural frequencies over 100,000 people make it obvious:
A "99% accurate" test leaves you with a 9% chance of being ill, because the false positives come from a pool 199 times larger than the true positives. Ignoring when computing is the base-rate fallacy. Retest with an independent second test and the posterior becomes the new prior: of the 5,470, diseased and healthy test positive again, so — 66.3%. That is why screening programmes always confirm.
> Watch out: that second calculation assumes the two tests' errors are conditionally independent given disease status. Two tests using the same biochemical mechanism fail on the same patients, and the true posterior is lower than 66%.
Chapter 2 — Random variables
Terminology
- Random variable (X) — a function from the sample space to the reals. A rule, not a storage slot.- PMF — discrete only. PDF — continuous only; a density, not a probability. CDF — both; non-decreasing, right-continuous, 0 → 1.- Support — the values with non-zero probability or density. i.i.d. — independent and identically distributed, the default assumption for a sample.
> Common pitfall: because in the continuous case, and agree there — but for a discrete variable they differ by . Off-by-one errors in binomial and Poisson tails almost always trace back to this.
Expectation, variance, and their algebra
For independent variables the covariance term vanishes and variances add in both cases — subtracting random variables does not subtract uncertainty.
Covariance and correlation
Covariance carries units (kg·cm, dollars·hours) and is hard to read; correlation is the unitless rescaling, hitting exactly when is an affine function of .
Correlation measures linear association only. Let take with equal probability and — a perfect deterministic relationship. Then and , so and . Zero correlation, total dependence. ( returns 0 up to floating point; the continuous twin is , .)
> Watch out: means "no linear trend", never "independent". Independence implies zero correlation; the converse is false except for jointly normal variables. Plot the scatter before trusting . And correlation is still not causation — , , a common cause , and selection effects in how the data was gathered all produce the same .
Chapter 3 — The distribution zoo
Every named distribution is a generating mechanism plus its consequences. Choose one by asking what process produced the number.
| Distribution | Parameters | Mean | Variance | Mechanism / typical use ||---|---|---|---|---|| Bernoulli(p) | | | | one trial, success or failure || Binomial(n,p) | , | | | successes in independent trials, fixed || Geometric(p) | | | | trials until first success (support 1, 2, 3, ...) || Poisson(λ) | | | | count of rare events in a fixed window || Uniform(a,b) | | | | no reason to prefer any value in a range || Exponential(λ) | | | | waiting time between Poisson events || Normal(μ,σ²) | , | | | sums of many small independent effects || Log-normal(μ,σ²) | , | | | products of effects: incomes, latencies, file sizes || Student t(ν) | | for | for | a mean when is estimated from the data || Chi-square(k) | | | | sums of squared standard normals: count tables, variances || F(d₁,d₂) | , | for | long closed form | ratio of two variances: ANOVA, model comparison |
Bernoulli, binomial, geometric
, valid when trials are independent and constant. Ten independent requests each failing with probability 0.3:
Geometric: . With the expected number of attempts is and . Like the exponential it is memoryless — past failures do not improve your prospects.
Poisson and the binomial limit
— rare events at a constant average rate in a fixed window. A support line averaging 3 calls/hour: , , .
If and with fixed, :
Three decimals of agreement. Rules of thumb: good when and , usually acceptable from with . The error is of order , so it is — not — that sets the quality.
> Trick: use Poisson when you know a rate but not a trial count — packets dropped per second, defects per square metre, 500-errors per minute. If you cannot say what is, the binomial was never the model.
Uniform, exponential, normal
has constant density ; its practical roles are the output of a random number generator and the input to inverse-transform sampling ( has CDF ). Exponential is the waiting time between Poisson events:
The ten minutes already spent waiting are worth nothing. The exponential is the only continuous distribution with this property (geometric is its discrete twin).
> Watch out: memorylessness is usually false for anything that ages. Disks, mechanical parts and user sessions have hazard rates that change over time — reach for a Weibull or a log-normal when the failure rate is not constant.
Normal — , standardised by . The empirical rule is 68.27% / 95.45% / 99.73% within 1, 2, 3 σ; the exact 95% multiplier is 1.96, not 2. Sums of independent normals stay normal: . Heights as cm: has so ; has so .
The four support distributions
- Log-normal — is normal. Arises from multiplicative accumulation, so it is right-skewed with a long tail. Response times, incomes and city sizes fit far better here than under a normal; the mean is pulled well above the median, so report both.- Student t(ν) — the sampling distribution of when is estimated. Heavier tails than normal, converging to it as (already close by ). Used for t-tests and small-sample intervals.- Chi-square(k) — a sum of squared independent standard normals, used for goodness-of-fit and independence tests on counts and for inference about a variance. F(d₁,d₂) — a ratio of two independent chi-squares each over its df, used for ANOVA and for comparing nested regression models.
Chapter 4 — Sampling and the limit theorems
Terminology
- Population — every unit you want to claim something about; described by parameters , , .- Sample — what you measured; described by statistics , , . A statistic is a function of random data, so it is itself a random variable.- Sampling distribution — the distribution of a statistic across all possible samples of size . The central object of inference, and not the distribution of your data. Standard error (SE) is its standard deviation.
Quadrupling the sample halves the error. Precision is expensive and gets more expensive the more of it you already have — this single fact should govern every "should we collect more data?" conversation. For a proportion, , largest at .
> Watch out: all of this assumes independent sampling. Clustered data — many measurements per user, repeated requests from one client — has an effective sample size far below . Treating it as gives standard errors that are too small and intervals that are too narrow. This is the most common way real analyses go wrong.
Law of large numbers
in probability (weak LLN) and almost surely (strong LLN). That is all it says, and it needs a finite mean — for a Cauchy distribution the sample mean never settles down.
> Common pitfall: the gambler's fallacy is the LLN misapplied. After ten heads it does not predict compensating tails; it predicts the ten heads become negligible against a growing . The imbalance is diluted, never corrected.
The central limit theorem
What it does say: the sampling distribution of the mean (or of any sum) becomes approximately normal regardless of the population shape, provided the variance is finite. What it does not say:
- It does not say your data becomes normal. Ten thousand exponential measurements are still exponentially distributed; only the mean is approximately normal.- It does not license a normality assumption about individual observations — which is what regression and t-test assumptions are partly about.- It does not apply with infinite variance: the mean of Cauchy draws is Cauchy for every .- is a rule of thumb, not a theorem. Mild skew converges by ; strong skew may need hundreds. Bootstrap to check rather than reciting 30.- It says nothing about the tails at finite . The centre converges fastest and extreme quantiles slowest — which matters if you care about p99 latency.
Worked example. Population : , . With , , so — about 4.2%.
Chapter 5 — Estimation
Terminology
- Estimator — a rule (function of the sample) for guessing a parameter. Estimate — the number it produces on one sample.- Bias — . Zero bias means right on average across repeated samples.- Consistency — as . Efficiency — smallest variance among unbiased estimators; the Cramér–Rao bound is the floor.- Likelihood — , a function of with the data fixed. It is not a probability distribution over .
Since , bias and variance are different failure modes and a slightly biased estimator with much lower variance can beat an unbiased one — that observation is the seed of regularisation in Chapter 8.
Why sample variance divides by : using in place of the unknown makes systematically too small, because is precisely the value minimising that sum for this sample. Bessel's correction compensates exactly, giving .
> Watch out: defaults to (biased, the MLE) and to , so the same column yields two different standard deviations depending on which library you asked — is while gives . Set explicitly. Note also that is a biased estimator of even though is unbiased: unbiasedness does not survive nonlinear transformation.
Method of moments and maximum likelihood
Method of moments sets sample moments equal to population moments and solves. For the population mean is , so gives . MLE instead picks the parameter making the observed data most probable — worked all the way through:
Here MLE and method of moments coincide; frequently they do not. The Bernoulli MLE being the sample proportion is a good sign the machinery does something sensible. MLEs are consistent, asymptotically normal, asymptotically efficient and invariant (the MLE of is ), but not generally unbiased — the MLE of divides by .
Confidence intervals
The t-interval is wider; that width is the price of estimating from the same 25 numbers. What "95% confidence" actually means — a statement about the procedure, not this interval:
> If you repeated the whole experiment many times — new sample, same method — 95% of the intervals constructed this way would contain the true parameter. The 95% is a long-run coverage property of the recipe.
Once is computed, is either inside it or not; there is no randomness left to attach a probability to. Under the frequentist framework is a fixed unknown constant. Misreadings to avoid:
- ❌ "There is a 95% probability lies in (49.52, 54.48)." That is the Bayesian credible interval statement and it requires a prior — a legitimate thing to want, just not what this gives you.- ❌ "95% of the data lies in this interval." That is a prediction or tolerance interval, and it is far wider.- ❌ "95% of future sample means will fall in this interval." No — different interval, lower coverage. And ❌ "a wider interval means the estimate is wrong": a wider interval means less information, honestly reported.
Chapter 6 — Hypothesis testing
Terminology
- Null hypothesis (H₀) — the "nothing interesting happening" model, specific enough to compute probabilities under. Alternative (H₁) — what you conclude if H₀ is rejected.- Test statistic — a number from the sample whose distribution under H₀ is known. Significance level (α) — the Type I error rate chosen before seeing the data.- Type I error — rejecting a true H₀ (false positive, rate ). Type II — failing to reject a false H₀ (false negative, rate ). Power — .- Effect size — how big the difference is, in units someone cares about.
The p-value, stated correctly
> A p-value is the probability of obtaining a test statistic at least as extreme as the one observed, computed under the assumption that H₀ and all the model's assumptions are true.
Every clause carries weight. What it is not: ❌ the probability H₀ is true — that is , while a p-value is , the same confused conditional as the medical test in Chapter 1; ❌ the probability the result is "due to chance"; ❌ ; ❌ a measure of effect size, since at a trivial difference gives ; ❌ a statement about whether the finding will replicate; ❌ something with a bright line at 0.05, since and are the same evidence.
A large p-value is also not evidence for H₀ — absence of evidence is not evidence of absence, especially at small . "We failed to reject H₀" is the honest phrasing.
Mechanics. State H₀ and H₁ before seeing the data; choose and a sample size giving adequate power; compute the statistic; compute the p-value from its null distribution; reject if ; and always report the effect size with its confidence interval. A two-tailed test asks "is there a difference?", a one-tailed test asks "is it bigger?" and puts all of in one tail — easier to reach significance in that direction, impossible in the other. Choosing the tail after seeing which way the data went doubles the real Type I rate.
Worked tests
> Trick: default to Welch's t-test () for two independent samples. It does not assume equal variances, costs almost nothing in power when they are equal, and avoids a pre-test that inflates the error rate.
Chi-square goodness-of-fit. A die rolled 60 times, observed , expected 10 each: , , — no evidence of unfairness.
Chi-square independence. A 2×2 table with in every cell:
The correction flips the verdict — which is exactly why a bare "significant / not significant" is a poor summary.
One-way ANOVA decomposes variability as and forms . A significant says "not all means are equal" — not which. Follow with pairwise comparisons and a correction (Tukey's HSD is built for it).
> Common pitfall: running all pairwise t-tests instead of an ANOVA. With that is 10 tests and roughly a 40% family-wise false positive rate.
Assumptions and nonparametric alternatives
| Test | Question | Key assumptions | Nonparametric alternative ||---|---|---|---|| One-sample z | mean vs known value, known | independence; normal or large | sign test || One-sample t | mean vs known value, unknown | independence; approx. normal | Wilcoxon signed-rank || Two-sample t (pooled) | two independent means | independence; normality; equal variances | Mann–Whitney U || Welch's t | two independent means | independence; normality; unequal variances OK | Mann–Whitney U || Paired t | mean of within-pair differences | differences approx. normal; pairs independent | Wilcoxon signed-rank || Chi-square GoF / independence | counts vs expected; two categoricals related | independent counts; expected cells ≥ 5 | exact multinomial; Fisher's exact || One-way ANOVA | 3+ group means all equal | independence; normality; equal variances | Kruskal–Wallis || Pearson correlation | linear association | bivariate normal, no strong outliers | Spearman rank correlation |
Paired vs two-sample is the choice that most often costs power. If each subject is measured twice (before/after, A/B on the same user), analyse the differences with a one-sample t-test — pairing removes between-subject variability, usually the largest noise source.
Power, sample size and multiple comparisons
Underpowered studies are doubly bad: they usually miss real effects, and when they do reach significance the estimated effect is inflated, because only the luckiest samples cross the threshold. That inflation is one mechanical driver of failed replications.
Run independent tests at and : 5.0% at , 22.6% at 5, 40.1% at 10, 64.2% at 20, 92.3% at 50. Bonferroni tests each hypothesis at , controlling the family-wise error rate — simple, always valid, conservative. Benjamini–Hochberg controls the false discovery rate: sort p-values ascending, find the largest with , reject 1 through .
Use Bonferroni when a single false positive is expensive (a confirmatory clinical endpoint); use FDR when screening many candidates with a tolerable proportion of duds (genomics, feature screening, dashboards with dozens of metrics).
p-hacking and the replication crisis
Every test above is valid only if the analysis was fixed before the data was seen. The moment analytic decisions respond to the data, the reported p-value's null distribution is no longer the one you looked up — and this mostly happens without dishonest intent. Optional stopping: peeking and stopping when ; with enough peeks, an A/B test on two identical variants crosses the line with probability approaching 1. Outcome switching: measuring ten metrics, reporting the one that worked. Subgroup mining: "significant among iOS users aged 25–34". Flexible exclusions: choosing which outliers to drop after seeing the effect on . Model shopping: trying covariates and transformations until something is significant. The garden of forking paths: the same inflation without explicit re-testing, because the analysis would have differed had the data differed. HARKing: hypothesising after results are known and presenting exploratory work as confirmatory.
The replication crisis is the consequence. The Open Science Collaboration's 2015 Estimating the Reproducibility of Psychological Science re-ran 100 studies: 97% of originals reported significant results, 36% of replications did, with replication effect sizes averaging roughly half the originals. Comparable gaps appeared in cancer biology and experimental economics. What helps: pre-registration (hypotheses, outcomes, exclusions and analysis plan written down first — keep exploratory work, just label it); report effect sizes with confidence intervals, since "d = 0.31, 95% CI (0.05, 0.57)" carries size, direction and precision while "p = 0.03" carries almost nothing; power the study beforehand, because post-hoc power computed from the observed effect is a deterministic function of the p-value and adds no information; publish nulls, since the file-drawer problem makes the literature a biased sample; and share data and code, because reproducibility is the precondition for replicability.
> Watch out: if you must peek at a running A/B test, use a method designed for it — group sequential designs with alpha spending, or always-valid sequential inference. Repeatedly applying a fixed-sample t-test is not one of those methods.
Chapter 7 — Regression
Terminology
- Response — what you model; predictor — what you model it from. Residual — , the part the model failed to explain (not the same as the unobservable error term).- Homoscedasticity — residual variance constant across fitted values; the opposite is heteroscedasticity.- Multicollinearity — predictors strongly linearly related to each other. Leverage — how far a point's predictor values sit from the centre; high-leverage points can dominate a fit.
Simple linear regression
The fitted line always passes through ; on those five points returns slope , intercept , . Interpretation: means a one-unit increase in is associated with a 0.6-unit increase in the mean of — "causes" only if was randomised. is the prediction at , meaningless whenever is outside the data or physically impossible; centring at its mean makes the intercept the prediction at average .
and its limits. is the fraction of the variance of explained by the model — useful and routinely over-read. It never decreases when you add a predictor, even a column of pure noise, so compare models with adjusted or out-of-sample error. A high does not mean the functional form is right: Anscombe's quartet is four datasets with identical , , , the same line and the same — yet one is linear, one a clean parabola, one a perfect line plus an outlier, and one a vertical stack plus one influential point. Conversely a low does not mean the model is useless: with irreducible noise (human behaviour, financial returns) an of 0.05 can carry a real, well-estimated, economically significant slope. And says nothing about causality, bias, or whether the model holds on new data.
> Trick: always plot the data and the residuals. Summary statistics exist to compress, and what breaks a regression is exactly what compression discards.
Multiple regression and its assumptions
In , each is the expected change in per unit of holding the other predictors in the model fixed. That conditional clause is why a coefficient can flip sign when a variable is added — the classic Simpson's paradox situation.
| Assumption | Meaning | Diagnostic | Failure symptom | Fix ||---|---|---|---|---|| Linearity | mean of linear in predictors | residuals vs fitted | systematic curve / U shape | transform, polynomial or spline terms || Independence | errors uncorrelated across observations | residuals vs order; ACF; Durbin–Watson | runs of same sign; time pattern | time-series or mixed model; cluster-robust SEs || Homoscedasticity | constant error variance | residuals vs fitted; scale–location | funnel / megaphone shape | log-transform ; WLS; robust (HC) SEs || Normality of residuals | errors approximately normal | Q-Q plot of residuals | heavy tails, strong skew | transform; robust regression; lean on the CLT at large |
Independence matters most — violating it corrupts every standard error and p-value in the output, and no amount of rescues it. Normality matters least — it is a condition on the residuals, never on or the predictors, and moderate departures are survivable at decent .
Multicollinearity and categorical predictors
Strongly correlated predictors leave the model unable to attribute credit between them. Predictions stay fine; individual coefficients become unstable, with huge standard errors and signs that flip on refit. , where comes from regressing on all other predictors: is uncorrelated, is worth investigating, is serious and the coefficients are not individually interpretable. Remedies: drop a redundant predictor, combine them into an index or principal component, collect more data, or use ridge regression (Chapter 8), designed for exactly this.
A categorical variable with levels enters as dummy columns; the omitted level is the reference and every coefficient is a contrast against it.
Including all dummies alongside an intercept makes the design matrix singular — the dummy variable trap. and the operator in formulas handle it.
> Watch out: encoding an unordered category as integers () tells the model that blue is three times red and green sits halfway between. Ordinal encoding is valid only for genuinely ordered levels with roughly equal spacing.
Logistic regression
With binary , linear regression predicts probabilities outside and has structurally heteroscedastic errors. Model the log-odds instead, fitted by maximum likelihood using the Bernoulli likelihood from Chapter 5:
is the change in log-odds per unit of ; exponentiate for an odds ratio, so means each extra unit multiplies the odds by about 2.01, holding the others fixed ( no effect, increases, decreases). Note that the same 20-point score change above moves the probability by 23 points then 15: the effect on the probability is nonlinear even though the effect on the log-odds is constant. In , gives the odds ratios and their intervals.
> Common pitfall: an odds ratio is not a risk ratio. They are close only when the outcome is rare (); for common outcomes the OR sits much further from 1 than the relative risk, so reading "twice as likely" from overstates the effect. Report absolute probabilities at representative predictor values too. Evaluate with the confusion matrix, precision/recall, ROC-AUC and calibration — and note that accuracy on an imbalanced problem is the base-rate fallacy in disguise: always predicting "no disease" is 99.5% accurate on the Chapter 1 population and useless.
Chapter 8 — Where statistics becomes machine learning
Everything above is mostly inference: estimate a parameter, quantify uncertainty, decide whether an effect is real. Machine learning uses the same mathematics to optimise a different target — out-of-sample prediction error. The methods overlap almost entirely; the objectives do not.
Terminology
- Training error — error on the data used to fit; optimistically biased, always. Generalisation error — expected error on new data from the same distribution; the quantity you actually care about.- Overfitting — the model learned noise specific to the training set (train error low, generalisation error high). Underfitting — too rigid to capture the signal (both high). Hyperparameter — a knob not learned from the training data. Regularisation — a penalty on complexity, trading a little bias for a lot of variance.
High bias / low variance is a linear model on curved data: wrong the same way every time. Low bias / high variance is a degree-15 polynomial through 20 points: fits each training set beautifully and differently. The best model is rarely the most flexible; it is the one minimising the sum.
Train / validation / test
Train fits the parameters, validation chooses hyperparameters and model families, and test is touched exactly once to estimate generalisation error (60/20/20, or 80/20 with cross-validation inside the 80). k-fold cross-validation replaces a single validation split: partition into folds, fit on , score the held-out one, rotate, average. or is standard, uses the data far more efficiently, and gives a variance estimate alongside the mean.
> Watch out — leakage. Fit scalers, imputers and feature selectors inside the CV loop, on the training fold only; standardising the full dataset before splitting leaks test information and produces a score that will not survive production. makes the correct thing the easy thing. Two more traps: split time-ordered data by time (), never randomly, or the model sees the future; and split grouped data by group (), or the same user lands on both sides.
Regularisation as a statistical idea
Ridge and lasso are not ML inventions bolted onto regression — they are from Chapter 5 turned into an algorithm: accept a little bias, cut a lot of variance, lower the total.
| | Ridge (L2) | Lasso (L1) ||---|---|---|| Coefficients | shrunk toward 0, never exactly 0 | some set exactly to 0 || Feature selection | no | yes, automatically || Correlated predictors | keeps all, splits the weight | picks one arbitrarily, drops the rest || Bayesian reading | MAP with a Gaussian prior on | MAP with a Laplace prior on || Best when | many small effects; multicollinearity | few predictors matter; |
is chosen by cross-validation, never by looking at the test set. Both penalties require standardised predictors — otherwise a variable in millimetres is penalised a thousand times more than the same variable in metres — and the intercept is conventionally left unpenalised.
> Common pitfall: the p-values printed for a regularised model are not valid in the usual sense — the penalty biases the coefficients on purpose. Selecting variables with lasso and then reporting ordinary OLS inference on the survivors badly understates the uncertainty. Honest p-values are a job for an inferential model on a separate dataset.
Inference vs prediction
| | Inferential model | Predictive model ||---|---|---|| Question | Why? Does affect , by how much? | What next? What is for this case? || Success criterion | unbiased coefficients, correct SEs | low error on unseen data || Complexity / bias | simple and interpretable; avoid bias | whatever generalises; trade bias for variance || Correlated predictors | a serious problem | mostly harmless || Discipline | pre-registration, fixed analysis plan | held-out test set touched once || Validation | assumption diagnostics, residual plots | cross-validated out-of-sample score || Typical output | "effect 0.6 units, 95% CI (0.31, 0.89)" | "AUC 0.87 on held-out data" || Risk | a wrong causal claim | silent accuracy decay under drift |
The failure mode is using one where you needed the other. A gradient-boosted model with excellent AUC says nothing about whether raising the price causes churn — it will happily exploit any correlate, including consequences of churn. Conversely, a beautifully specified regression with every assumption satisfied may generalise poorly, because unbiasedness is not low prediction error. Decide which you are building before fitting anything: it changes the split, the model class, the metric, and what you may conclude.
Where the data comes from
None of this happens on clean arrays — the real pipeline is extract, aggregate, reshape, then model.
- The aggregation stage is usually a database job. The MongoDB course's aggregation basics post covers , and the accumulators that compute group means, counts and variances server-side — where the group summaries feeding an ANOVA or a chi-square table should come from.- Time-ordered measurements bring their own independence problems; the time-series at extreme scale post covers bucketing and windowing, and the statistical point is that consecutive observations are autocorrelated, so the effective is below the row count.- Vector search and RAG are cosine similarity plus nearest-neighbour retrieval — geometry built on the covariance ideas of Chapter 2; see Atlas Search and vector search and the production RAG build, and note that evaluating a retrieval system is a hypothesis-testing problem carrying every multiple-comparison hazard from Chapter 6. The Python side starts with data structures — , , comprehensions — which is what is built on and what you reach for when reshaping records before they hit .
Practice Exercises
Exercise 1 — Base rates
A screening test has 98% sensitivity and 90% specificity. Compute for prevalence 0.1%, 1% and 10%, then find the prevalence at which a positive result first becomes more likely than not.
<details><summary>Solution</summary>
</details>
Exercise 2 — Variance algebra
and are independent with . Compute and . Then redo the variance assuming .
<details><summary>Solution</summary>
</details>
Exercise 3 — Choose the distribution
Name the distribution and parameters for each, justifying from the generating mechanism: (1) heads in 50 fair coin flips; (2) typos on a page averaging 1.4 per page; (3) minutes to the next request at 12 requests/hour, memoryless; (4) interviews until the first acceptance at 15% per candidate; (5) end-to-end service latency formed as a product of independent multiplicative slowdowns.
<details><summary>Solution</summary>
</details>
Exercise 4 — CLT by simulation
Draw 20,000 samples of size from . Histogram the sample means and compare their standard deviation to with . At which does the histogram stop looking triangular? Then repeat with and explain why the spread never shrinks.
Exercise 5 — Derive an MLE
Derive the MLE of for i.i.d. observations from , including the second-derivative check.
<details><summary>Solution</summary>
</details>
Exercise 6 — Say what the interval means
A study reports "mean improvement 4.2 points, 95% CI (0.3, 8.1), p = 0.037." Which statements are correct? (1) There is a 95% probability the true mean lies in (0.3, 8.1). (2) Repeated many times, about 95% of intervals built this way would contain the true mean. (3) There is a 3.7% probability the null is true. (4) Data would be at least this extreme in 3.7% of studies if the true effect were exactly zero. (5) It is significant at , so the effect is important. (6) The interval is wide relative to the effect, so the study is consistent with anything from negligible to large.
<details><summary>Solution</summary>
</details>
Exercise 7 — Fit and diagnose
Simulate with , . Fit with and confirm the coefficients recover the truth within their standard errors. Then break one assumption at a time and note which diagnostic reacts: multiply the errors by (heteroscedasticity → funnel in residuals-vs-fitted and wrong SEs; refit with ); add a term (nonlinearity → U-curve in residuals-vs-fitted); draw from a t with 2 df (heavy tails → Q-Q plot bending at both ends); generate as an AR(1) series with (dependence → Durbin–Watson far below 2 and visible runs in residuals-vs-order).
Cheat-sheet
| What | How ||---|---|| Union / complement / conditional | ; ; ; independent ⟺ || Bayes / counting | — always check the base rate; ordered, unordered || Variance toolkit | ; ; if independent || Correlation | in — linear association only || Discrete zoo | Binomial , ; Poisson ; Geometric ; binomial → Poisson when large, , || Continuous zoo | Exponential , , memoryless; Normal 68/95/99.7, exact 95% is || Standard error / CLT | , so quadruple to halve it; the CLT normalises the sampling distribution of the mean, not your data || Sample variance / MLE | divide by ( needs ); MLE = write , take , differentiate, solve, check || CI | ; 95% of intervals from this procedure cover — not || p-value | — never || Errors and power | Type I , Type II , power ; per group for 80% power || Test picker | two independent means → Welch's t; paired → t on the differences; counts → chi-square; 3+ groups → ANOVA then Tukey || Multiple tests | Bonferroni (family-wise) or Benjamini–Hochberg (FDR) || Regression | ; line passes through ; || Diagnostics | residuals vs fitted, Q-Q, residuals vs order; serious; is an odds ratio, not a risk ratio || ML side | ; ridge shrinks, lasso zeroes; fit transforms inside the CV fold |
Where to go deeper
- Bayesian statistics — Chapter 1's theorem generalises to full posteriors over parameters, which is where the "95% probability the parameter is in this interval" statement legitimately lives. Gelman et al., Bayesian Data Analysis; implement with or .- Causal inference — regression coefficients are associations; turning them into causal claims needs potential outcomes, DAGs, backdoor adjustment, instrumental variables, difference-in-differences, regression discontinuity.- Experimental design and time series — allocation, blocking, randomisation and stratification (directly applicable to A/B testing, sequential designs and CUPED-style variance reduction); then ARIMA, state-space models and cross-validation that respects time ordering, for the case where Chapter 7's independence assumption fails by construction.- Generalised linear models — logistic regression is one member of a family, alongside Poisson regression for counts, gamma for skewed positives and ordinal models for ranked outcomes. Hierarchical / mixed-effects models — the principled answer to clustered data; partial pooling is regularisation derived from the data structure. Resampling — the bootstrap gives intervals for statistics with no tractable sampling distribution, and permutation tests give exact p-values without distributional assumptions.- Statistical learning — An Introduction to Statistical Learning is the natural sequel to Chapter 8, with The Elements of Statistical Learning as the deeper version.
References
- Kolmogorov, A. N. — Foundations of the Theory of Probability (1933; Chelsea translation). Source of the Chapter 1 axioms.- Casella, G. & Berger, R. L. — Statistical Inference, 2nd ed. (the standard graduate reference for estimation and testing); Wasserman, L. — All of Statistics (compressed and rigorous, written for computer scientists).- James, G., Witten, D., Hastie, T. & Tibshirani, R. — An Introduction to Statistical Learning (free PDF).- Hastie, T., Tibshirani, R. & Friedman, J. — The Elements of Statistical Learning (free PDF); Hernán, M. A. & Robins, J. M. — Causal Inference: What If (free PDF).- Wasserstein, R. L. & Lazar, N. A. — The ASA Statement on p-Values, The American Statistician, 2016.- Open Science Collaboration — Estimating the Reproducibility of Psychological Science, Science 349 (2015); Benjamini, Y. & Hochberg, Y. — Controlling the False Discovery Rate, JRSS-B 57 (1995); Anscombe, F. J. — Graphs in Statistical Analysis, The American Statistician 27 (1973).- SciPy reference · statsmodels · scikit-learn user guide · NumPy random sampling
Planned future extensions:
- A dedicated Bayesian inference post — conjugate priors, MCMC and posterior predictive checks, using the Chapter 1 medical-test example as the running thread.- A causal inference companion covering DAGs, confounding, and why "control for everything" is a bad strategy.- A practical A/B testing post: sequential designs, variance reduction, guardrail metrics, and what to do when someone peeks.- A time-series post extending Chapter 7 to autocorrelated data, pairing with the MongoDB time-series material, plus worked notebooks reproducing every numeric example here as runnable cells.
Web Development (Advanced) — Node.js, React, Vue, Build Tools, UI Frameworks
The basic post covered HTML, CSS, vanilla JS, jQuery. Modern web development sits on top of that base: Node.js as a JS runtime everywhere, package managers to wire dependencies, bundlers (Vite, esbuild, webpack) to produce production assets, component frameworks (React, Vue, Svelte) to manage state + UI, CSS frameworks (Tailwind, Bootstrap) to keep styles consistent, icon sets (Font Awesome, Lucide) for visuals, and a deployment story for shipping the result. This post is a survey of the stack and the trade-offs. (3D / WebGL / Three.js has its own dedicated series — see the link at the end.)
Learning Outcome
- Install and use Node.js + npm / pnpm / yarn.- Initialise a project with Vite, understand the dev server + build output.- Read and write a React or Vue component with state, props, events.- Pick between React, Vue, Svelte for a new project.- Use a CSS framework (Tailwind / Bootstrap) effectively.- Add icons with Font Awesome or Lucide.- Call REST / GraphQL APIs from the browser.- Deploy a static site (Vercel / Netlify / Cloudflare Pages / S3+CloudFront).
Chapter 1 — Node.js as a JS runtime
Node.js is V8 (Chrome's JS engine) outside the browser. It powers:
- Build tools (Vite, webpack, esbuild, Rollup).- Local dev servers.- The package manager (npm).- Many backend frameworks (Express, Fastify, NestJS, Next.js API routes).- Build pipelines in CI.
Install via nodejs.org (LTS) or nvm (manage multiple versions). Verify:
Run a script:
REPL: opens an interactive prompt similar to Python's.
Chapter 2 — Package managers
Three contenders today:
| Tool | Speed | Disk | Notes ||------|-------|------|-------|| npm | OK | duplicates per-project | ships with Node || pnpm | fastest | content-addressed store, hard-linked | modern default for many teams || yarn (Berry) | fast | Plug'n'Play option | corporate use, monorepos |
Pick one per project and stick with it. The lockfile ( / / ) is committed.
Common commands (npm flavour)
A typical :
Chapter 3 — Build tools (Vite + ESM)
Old days: webpack + Babel + a 200-line config; cold start 30 sec, HMR 2-5 sec. Modern: Vite uses native ES modules in dev (zero bundling) and esbuild / Rollup for production builds. Cold start < 500 ms, HMR < 100 ms.
Templates: , , , , , , , , , , , . TypeScript is the default in modern teams.
Why ESM matters
The browser fetches each -ed module separately. Dev servers serve them un-bundled — only re-process the file you changed. Production builds still bundle (fewer requests, tree-shaking).
Chapter 4 — React vs Vue vs Svelte
The three live framework families. Brief comparison:
| | React | Vue | Svelte ||---|-------|-----|--------|| Released | 2013 | 2014 | 2016 || Maintainer | Meta | core team | core team || Component file | / | (HTML+JS+CSS in one) | || State | hooks (, ) | reactivity (, ) | language-level () || Templating | JSX (JS-like) | HTML template + directives | HTML + minimal directives || Bundle size baseline | 45 KB gzipped | 30 KB | 5 KB (compiles away) || Job market | dominant | strong, especially APAC | growing || Best for | huge ecosystem, hiring | balance of approachability + power | smallest output, first-time learners |
There is no universally best. React if hiring + ecosystem matters most. Vue for a balanced learning curve. Svelte for performance + simplicity at small-to-medium scale.
Chapter 5 — React essentials
Rules of thumb:
- JSX — HTML-like syntax that compiles to .- for local state.- for side effects (data fetching, subscriptions).- Props are read-only inputs from parent.- Always give array children a stable prop.- Component names are PascalCase.
Fetching data
For real apps, use TanStack Query () or SWR instead of hand-rolling effects.
Routing
React itself does not include routing. Add React Router () for SPA routes, or use Next.js / Remix for a more opinionated framework with file-based routing + server rendering.
Chapter 6 — Vue essentials (composition API)
Single-file components bundle template + logic + styles. wraps a value; access with in JS, unwrapped automatically in templates.
Routing: . State: . Full-stack framework: .
Chapter 7 — CSS frameworks
| Approach | Example | When ||----------|---------|------|| Utility classes | Tailwind, UnoCSS | rapid prototyping, design systems, modern teams || Component CSS | Bootstrap, Bulma | quick admin/dashboard, less custom design || CSS-in-JS | styled-components, Emotion | React apps with dynamic styling || CSS Modules | (built into Vite) | scoped styles per component, no framework || Hand-written | nothing | full control, small projects, design-led |
Tailwind (the modern default)
Install:
Configure in and include in your CSS entry.
Bootstrap (still widely used)
Heavier visual opinion, faster to assemble admin dashboards. Pair with the JS plugins (modals, dropdowns, tooltips).
> Trick: mixing Tailwind + Bootstrap in the same project usually fights — both impose layout opinions. Pick one. For new projects, Tailwind almost always wins; for legacy + content-heavy, Bootstrap can still shine.
Chapter 8 — Icons
| Library | Bundle | Use ||---------|--------|-----|| Font Awesome | huge if loaded all; tree-shake-friendly via React/Vue packages | mainstream brand-icons + many UI icons || Lucide (fork of Feather) | small, MIT, modern | most React/Vue teams default in 2026 || Heroicons | from Tailwind team | pairs with Tailwind nicely || Material Symbols | Google | Android / Material Design feel || Tabler Icons | huge free set | open-source designers' favourite |
React usage (Lucide):
Avoid loading the whole Font Awesome CSS bundle in 2026 — too heavy. Use the per-icon import pattern for any library.
Chapter 9 — APIs: REST + GraphQL
REST
GraphQL
Single endpoint, client picks fields:
Tools: Apollo Client (React/Vue), urql, graphql-request.
Data-fetching libraries (the time-saver)
Hand-rolling fetch + loading + error state in every component is repetitive. Use:
- TanStack Query (, )- SWR (React)- Pinia Colada (Vue)
They handle caching, deduplication, retries, background refresh, pagination, and devtools. Standard in modern apps.
Chapter 10 — TypeScript (briefly)
JavaScript with optional static types. Catches whole classes of bugs at compile time + improves IDE autocomplete.
Vite templates ship with TS preconfigured. Use TS for any project bigger than a one-page demo — the productivity payoff comes quickly.
Chapter 11 — Deployment
| Target | Tool | Best for ||--------|------|----------|| Static hosting | Vercel, Netlify, Cloudflare Pages, GitHub Pages | SPAs, marketing sites, docs || S3 + CloudFront | AWS | full control, fits a wider AWS stack || Full-stack edge | Vercel (Next.js), Cloudflare Workers, Deno Deploy | SSR + APIs + edge || Containers | Fly.io, Render, AWS ECS/Fargate | Node.js servers, WebSockets, background jobs || VPS | DigitalOcean, Hetzner, Linode | hand-rolled, cheap |
A typical Vite build → static deploy:
For React/Vue SPAs that need a backend, the easiest stack in 2026 is Next.js on Vercel or Nuxt on Vercel/Cloudflare — they unify frontend + serverless backend + edge functions in one deployment.
Chapter 12 — Performance baseline
Hit these targets in Lighthouse for a polished site:
| Metric | Target ||--------|--------|| LCP (Largest Contentful Paint) | < 2.5 s || INP (Interaction to Next Paint) | < 200 ms || CLS (Cumulative Layout Shift) | < 0.1 || First-load JS (uncompressed) | < 200 KB || Image format | AVIF / WebP, not PNG/JPG raw || Fonts | , subset, self-host |
Tools: Lighthouse (in DevTools), PageSpeed Insights, WebPageTest.
Common wins:1. Lazy-load below-the-fold images ().2. Code-split routes (, dynamic ).3. Compress images (use a build-time tool — , ).4. Preload the hero font.5. Remove unused JS (the bundle analyzer flags it).
Practice Exercises
Exercise 1 — Vite + React/Vue starter
. Build a single-page counter app. Push to GitHub. Deploy to Vercel.
Exercise 2 — TanStack Query
Fetch with TanStack Query. Render the list with loading + error states. Add a refresh button.
Exercise 3 — Tailwind UI
Build a 3-card pricing layout with Tailwind. Responsive: stacked on mobile, 3 columns on desktop. Use Lucide icons in the feature lists.
Exercise 4 — Full mini-app
A note-taking app: list + create + delete + edit. State via React Context or Pinia. Data fetched via TanStack Query against a mock JSON server (). TypeScript. Tailwind. Deploy to Vercel.
Cheat-sheet
| What | How ||------|-----|| Init project | || Add dep | || Add dev dep | || Run script | || React state | || React effect | || Vue state | || Vue effect | || Routing (React) | / Next.js || Routing (Vue) | / Nuxt || Data fetching | TanStack Query / SWR || Style toolkit | Tailwind (modern) / Bootstrap (legacy) || Icon | Lucide / Heroicons / Font Awesome || Types | TypeScript everywhere || Deploy static | Vercel / Netlify / Cloudflare Pages || Deploy full-stack | Next.js on Vercel || Audit perf | Lighthouse / PageSpeed Insights |
Where to next
For 3D, WebGL, WebGPU, Three.js, React Three Fiber, shaders, instancing, physics, AI-assisted 3D and the rest — see the dedicated Three.js series (posts through ). That topic deserved its own multi-post arc rather than a single chapter.
Other areas that warrant their own deep-dive posts in future:
- Next.js / Nuxt — full-stack frameworks built on React / Vue with file-based routing, server components, edge.- State management — Zustand, Jotai, Redux Toolkit (React); Pinia (Vue).- Testing — Vitest + Testing Library, Playwright for E2E.- Animations — Framer Motion (React), GSAP, View Transitions API.- PWA — service workers, offline, install-to-home-screen.- WebSockets / real-time — Socket.IO, native WebSocket, SSE.- Web Components / Lit — framework-agnostic components.- Astro / Qwik — modern islands / resumability frameworks for content sites.
References
- MDN Web Docs- React docs- Vue docs- Svelte docs- Vite docs- Tailwind docs- TanStack Query- web.dev — Google's modern web practices.
> Note: this post is in progress. Planned additions: Next.js full walkthrough, Server Components explained, deep dive on Web Animations API. (WebGPU + Three.js is covered in the separate Three.js series.)
Java Development [Basic] Part 1 — Language, OOP, Exceptions, I/O, Threads
Java is a statically-typed, class-based, compiled-to-bytecode language that runs on the Java Virtual Machine (JVM). It powers Android, large enterprise backends (Spring), big-data tools (Hadoop, Kafka), and most banking infrastructure. Part 1 of this two-part series covers the language core: from "hello world" through OOP, generics, exceptions, file I/O, and the basics of multithreading. Part 2 picks up with GUI, events, functional programming, collections, and the Stream API.
Learning Outcome
- Compile and run Java programs with + (and via an IDE).- Use primitives, wrappers, control flow, arrays, and strings idiomatically.- Define classes with constructors, fields, methods, access modifiers, and .- Use inheritance, polymorphism, abstract classes, and interfaces.- Apply solid OOD principles (SOLID, encapsulation, composition over inheritance).- Write and use generic classes + methods.- Handle errors with and custom exceptions.- Use for development-time invariants.- Read and write files using the modern API.- Run code on multiple threads and recognise the standard concurrency utilities.
Chapter 1 — Introduction
Terminology
- JDK — Java Development Kit: compiler + standard library + tools.- JRE — Java Runtime Environment: enough to run compiled code (rarely separated from JDK anymore).- JVM — Java Virtual Machine: executes bytecode.- Bytecode — the file format produced by .- Class — the template for objects.- Object — an instance of a class.- Package — a namespace; maps to a directory.- Main method — the JVM entry point: .
Install
| OS | Recommended ||----|--------------|| Any | Temurin (Eclipse Adoptium build of OpenJDK) — LTS 21 in 2026 || macOS | || Windows | || Linux | (or distribution equivalent) |
Verify:
Or use an IDE — IntelliJ IDEA Community is the standard pick.
Hello, world
:
Compile + run:
Class name must match filename. One class per file.
Modern Java (21+) supports a simplified compilation for single-file programs:
Useful for scripts and learning.
Chapter 2 — Objects and Classes
Terminology
- Field — class-level variable (state).- Method — class-level function (behaviour).- Constructor — special method called when creates an instance.- — reference to the current instance inside a method.- — belongs to the class, not an instance.- Access modifiers — , , package-private (default), .- Record (Java 16+) — concise immutable data carrier.
A minimal class
Use:
members
Records (Java 16+)
Records auto-generate constructor, accessors, , , . Use for plain data carriers.
Chapter 3 — Inheritance & Polymorphism
Terminology
- — declares a subclass.- — refers to the parent.- Override — replace a parent's method in a subclass.- Polymorphism — call a parent-typed reference, dispatch to the actual subclass.- — prevents inheritance (on class) or overriding (on method).
Example
Always use — the compiler verifies you really did override (catches typos).
+ pattern matching (modern)
Chapter 4 — Abstract Class, OOD Principles
Terminology
- Abstract class — declared with ; cannot be instantiated; may contain abstract methods.- Interface — pure contract; can have and methods (Java 8+) and helpers (Java 9+).- SOLID — five design principles (Single-responsibility, Open/closed, Liskov substitution, Interface segregation, Dependency inversion).
Abstract class
Interface
A class can only one class but many interfaces — the standard answer to "multiple inheritance" in Java.
OOD quick-reference (SOLID)
| Principle | Plain English ||-----------|----------------|| Single responsibility | each class has one reason to change || Open / closed | open for extension, closed for modification || Liskov substitution | subtypes must work wherever the supertype works || Interface segregation | many small interfaces beat one fat one || Dependency inversion | depend on abstractions, not concretes |
Also fundamental: composition over inheritance (prefer containing collaborators to subclassing them).
Chapter 5 — Generic Class
Terminology
- Type parameter — , , etc.- Bounded type — .- Wildcards — , , (PECS rule).
Generic class
Generic method
Bounded + wildcards
Chapter 6 — Exception handling
Terminology
- — root.- — JVM-level (); usually don't catch.- — recoverable; subclasses include the checked family (must be declared/handled) and (unchecked).- Checked exceptions — , , , etc.- Unchecked — , , , etc.
try / catch / finally
try-with-resources (auto-close)
Implementing lets your own classes participate.
Custom exceptions
> Trick: prefer unchecked exceptions for programming errors (bug-style: bad arg, missing key). Reserve checked exceptions for genuinely recoverable I/O. Modern Java style leans towards fewer checked exceptions.
Chapter 7 — Assertion
checks a development-time invariant. Disabled by default in production unless run with (enable assertions).
Rules:- Never use for argument validation in public APIs — use .- Use for invariants that should never be false if the code is correct.- Assertions are stripped at runtime by default — don't put side effects inside.
Chapter 8 — File I/O
The modern API is (NIO.2, Java 7+). Avoid the legacy .
Read
Write
Path operations
Streams + buffered
Chapter 9 — Multithreading
Terminology
- Thread — a unit of execution scheduled by the OS.- Runnable — functional interface for a unit of work.- Thread-safe — correct when accessed from multiple threads simultaneously.- Race condition — outcome depends on thread interleaving.- — mutual-exclusion keyword.- — guarantees visibility of writes across threads.- Virtual thread (Java 21+) — lightweight, JVM-scheduled; millions can run concurrently.
Threads the modern way
Virtual threads were the headline Java 21 feature. They make blocking I/O efficient at scale without rewriting code as async.
Synchronisation
Or with explicit locks for finer control:
essentials
| Type | Use ||------|-----|| , , | lock-free counters / refs || | thread-safe map || | producer-consumer || , , | coordination primitives || | async pipelines || | thread pool || | periodic / delayed tasks |
> Trick: for most server workloads in 2026, + plain blocking code is the right answer. Reach for only when you really need composition of async pipelines.
Practice Exercises
Exercise 1 — Class basics
Build a class with , (reject if overdraw), . Override . Add a method.
Exercise 2 — Inheritance
Define (abstract ), , , . Put them in an array; print the total area.
Exercise 3 — Generics
Implement with , , , , . Use an underlying .
Exercise 4 — Exception flow
Read a file path from ; print its content. Catch and separately, exit with different exit codes (2 and 3 respectively).
<details><summary>Solution sketch</summary>
</details>
Exercise 5 — Concurrency
Spawn 1000 virtual threads, each downloading . Collect the responses into a (thread-safe!) and print the count of unique values.
Cheat-sheet
| What | How ||------|-----|| Compile | || Run | || Single-file run (modern) | || Class | || Record | || Constructor | || Override | on method || Abstract class | || Interface | || Generic class | || Bounded generic | || Try with resources | || Read file | || Write file | || Walk dir | || Virtual thread | || Virtual executor | || Sync method | || Atomic int | || Thread-safe map | |
What's next
Part 2 covers GUI (JavaFX), events, functional programming, the Collections framework, and the Stream API.
References
- docs.oracle.com/en/java/javase/21/ — official docs (LTS 21 in 2026).- Effective Java by Joshua Bloch — the canonical guide.- Java Concurrency in Practice by Brian Goetz — concurrency bible.- dev.java — Oracle's modern tutorial site.- Modern Java in Action by Urma / Fusco / Mycroft — covers lambdas, streams, modules.
> Note: this post is in progress. Planned additions: build tools (Maven, Gradle), modules (JPMS), sealed classes, pattern matching for , structured concurrency.
Java Development [Basic] Part 2 — GUI, Events, Functional, Collections, Streams
Part 1 covered Java's language core through threads. Part 2 picks up with the application-level toolkit: a graphical user interface (JavaFX), event handling, the functional programming features added in Java 8 (lambdas, method references, functional interfaces), the Collections framework (the standard data structures), and the Stream API (declarative bulk operations). Together they cover most of what real Java apps build on top of the basics.
Learning Outcome
- Build a basic JavaFX window with controls and a layout container.- Hook up event handlers (button clicks, key presses, observable property changes).- Write lambdas and method references; use the standard functional interfaces.- Choose between , , , , , , , .- Use the Stream API for , grouping, sorting, and parallel processing.- Combine functional + streams + collections into clean data pipelines.
Chapter 10 — Graphical User Interface (JavaFX)
Terminology
- Stage — a top-level window.- Scene — the content of a stage; holds a scene graph.- Node — anything in the scene graph (controls, shapes, layouts).- Layout (Pane) — a Node that arranges children (, , , , ).- Control — interactive widget (, , , , etc.).
JavaFX is the modern Java GUI (since 2008); Swing is the older one but still around in some enterprise code. Pick JavaFX for new work.
Setup
JavaFX is no longer bundled with the JDK. Add it via:
- Maven / Gradle dependency — .- Or download the SDK from openjfx.io and run with .
Minimal app
Common layouts
| Layout | Behaviour ||--------|-----------|| | children stacked vertically || | children in a row || | row/col grid (CSS-Grid-like) || | top / bottom / left / right / centre regions || | stacks children on top of each other || | wraps children left-to-right || | pin children to edges |
Common controls
, , , , , , , , , , , , , , , .
Styling
Style with CSS — JavaFX uses a CSS variant where selectors look like normal CSS but properties are prefixed with :
Attach with .
FXML (separate UI from logic)
For non-trivial apps, define the UI in FXML (an XML markup), edit visually in Scene Builder, wire to a controller class via .
Chapter 11 — Events
Terminology
- Event — an object describing something that happened (, , ).- Event handler — a function (now usually a lambda) that runs in response.- Observable property — a value that fires notifications when it changes (, ).- Binding — a derived observable computed from others.
Action + mouse + key
Observable properties
Bindings (declarative)
Bindings keep UI state in sync with model state without manual wiring.
Threading rule
All scene-graph changes must happen on the JavaFX Application Thread. From a background thread, use:
For longer work, use a which runs on a background thread and exposes / callbacks on the JavaFX thread.
Chapter 12 — Functional Programming (Java 8+)
Terminology
- Lambda expression — short anonymous function: .- Method reference — shorthand for a lambda that just calls one method: .- Functional interface — an interface with exactly one abstract method (SAM).- Effectively final — a local variable that isn't reassigned — required to capture in a lambda.
Lambdas
Method references
| Form | Example | Equivalent lambda ||------|---------|--------------------|| Static | | || Instance of a class | | || Instance of an object | | || Constructor | | |
Standard functional interfaces ()
| Interface | Signature | Use ||-----------|-----------|-----|| | | transform || | | two args → result || | | filter || | | side effect || | | factory || | | same-type transform || | | reduce step |
Specialised primitive versions exist (, , ...) to avoid boxing in hot loops.
Wraps a possibly-absent value — preferable to returning .
Chapter 13 — Collections
Terminology
- — root interface for groups of elements (List, Set, Queue).- — key-value lookups (not a ).- — anything iterable with .
The interface hierarchy
Concrete classes
| Interface | Implementation | When ||-----------|----------------|------|| | | default; O(1) index, O(n) middle insert || | | many insertions / deletions in middle (rarely the right choice in practice) || | | unordered, O(1) average ops || | | insertion-ordered || | | sorted, O(log n) || | | unordered, O(1) average || | | insertion-ordered || | | sorted by key, O(log n) || | | thread-safe || | | preferred over and || | | min-heap by natural / comparator order |
Common operations
Factory + immutable collections (Java 9+)
Use immutable factories for shared constants — safer + slightly faster.
Iteration
> Trick: uses the iterator and so will throw if you mutate the collection inside the loop. Use or iterate over a copy if you need to modify.
Chapter 14 — Stream API
A Stream is a sequence of elements supporting bulk operations. Streams don't store data — they consume from a source (collection, array, generator) and produce a result.
Pattern
Operations:- Intermediate (return a new Stream): , , , , , , , .- Terminal (consume the stream): , , , , , , , , , , , , (Java 16+).
Examples
Collectors (the secret weapon)
Reduce
Parallel streams
Easy parallelism. Works well for CPU-bound, side-effect-free work over large data. Don't blindly add to small lists or IO-bound work — overhead can outweigh the benefit. Measure.
> Trick: the modern terminal (Java 16+) replaces for the common case. Less typing; returns an unmodifiable list.
Chapter 15 — Putting it together
A small worked example tying chapters 12-14:
In a few declarative lines: grouping + aggregation + selection. Same logic in classic loops would be 30+ lines and harder to verify.
Practice Exercises
Exercise 1 — JavaFX counter (no FXML)
Build the counter app from Chapter 10. Add a "Reset" button and a to set the starting value.
Exercise 2 — JavaFX with FXML
Re-do Exercise 1 using FXML + a controller class. Apply a small CSS file styling the button.
Exercise 3 — Functional refactor
Take a loop-heavy method you've written before (any chapter) and rewrite it using streams + collectors. Compare line count + readability.
Exercise 4 — Words frequency
Given a long string, return a of word → count, sorted descending by count, top 10.
<details><summary>Solution</summary>
</details>
Exercise 5 — Group + summary
Given a (id, customer, status, total), produce:- count of orders per status,- average total per customer,- the customer with the highest single order.
Exercise 6 — Bound UI to model
JavaFX app: a (0-100) and a . Bind the label to display the slider value with one decimal place, prefixed "Value: ". No event listeners — use .
Cheat-sheet
| What | How ||------|-----|| JavaFX run | , || Layout | , , , || Button click | || Property listener | || Binding | or property || UI from BG thread | || Lambda | || Method ref | , || Optional | + , , || List | / immutable || Map | / immutable || Set | / immutable || Stream filter+map+collect | || Group by | || Sum / count | , || Parallel | (measure!) || Reduce | || Sort | |
Where to next
- Build tools — Maven / Gradle (the toolchain for any non-trivial Java project).- Spring Boot — the dominant Java framework for web/services in 2026.- JDBC / JPA / Hibernate — database access.- Modules (JPMS) — Java 9+ module system.- Records + sealed types + pattern matching — modern data-modelling features.- Structured concurrency — Java 21+ preview for safer concurrent code.- Project Loom / virtual threads — covered briefly in Part 1; worth a deeper post.
References
- docs.oracle.com/en/java/javase/21/- openjfx.io — JavaFX home.- Gluon Scene Builder — visual FXML editor.- Effective Java by Joshua Bloch — items on collections, streams, lambdas.- Modern Java in Action by Urma / Fusco / Mycroft — the canonical functional/streams guide.- dev.java tutorials — Oracle's official modern tutorials.
> Note: this post is in progress. Planned additions: full JavaFX TableView walkthrough; Maven + Gradle quick-start; pattern-matching examples; structured concurrency intro.
Java語言 重溫筆記 - Q&A (In Progress)
Java是一個十分常見的程式語言, 其 經常應用在各大公司的產品
Learning Outcome
Understand the basic terminologies of Java.
Learn how to develop basic Java projects.
this 指令static
Chapter 3 - Inheritance & Polymorphism
To be added..
Terminology
To be added..
Chapter 4 - Abstract Class, OOD Principles
To be added..
Terminology
To be added..
Chapter 5 - Generic Class
To be added..
Terminology
To be added..
Chapter 6 - Exception handling
To be added..
Terminology
To be added..
Chapter 7 - Assertion
To be added..
Terminology
To be added..
Chapter 8 - File I/O
To be added..
Terminology
To be added..
Chapter 9 - Multithreading
To be added..
Terminology
To be added..
Chapter 1 - Introduction
To be added..
Terminology
Generic class
Chapter 2 - Objects and Classes
To be added..
Terminology
To be added..
Chapter 3 - Inheritance & Polymorphism
To be added..
Terminology
To be added..
Chapter 4 - Abstract Class, OOD Principles
To be added..
Terminology
To be added..
Chapter 5 - Generic Class
To be added..
Terminology
To be added..
Chapter 6 - Exception handling
To be added..
Terminology
To be added..
Chapter 7 - Assertion
To be added..
Terminology
To be added..
Chapter 8 - File I/O
To be added..
Terminology
To be added..
Chapter 9 - Multithreading
To be added..
Terminology
To be added..
Useful Shortcut
To be added..
Java語言 重溫筆記 - 上 (In Progress)
Java 是一種十分基礎並常用的編程語言。 它的歷史非常悠久,在許多新語言的研究和開發中擔任著重要的角色, 但亦因此 Java 比其他常用語言更為繁瑣和嚴謹。 不過由於 Java 穩定的表現, 豐富的文檔和輕鬆搬移項目的靈活特性,至今仍然有不少從事資訊科技的公司採用。
學習目標
- 掌握Java Prograqmming的基礎- 能夠創建屬於自己的Project- 學習一些Java的進階指令
章節1 - 如何開始寫Java
市面上有不少支援 Java Development 的軟件\假如你是完全沒接觸過 Java 的同學, 建議先下載 Java Development Kit (JDK) 和相應的開發軟件\如 Eclipse, Visual Studio, Netbeans ...\本文將會專注於使用 Apache Netbeans, Java with Ants 的開發上
首先介紹 Java 的基礎文本範例\假設你在 Package example 中創建了一個 HelloWorld.java
main 是主要執行的部分, 想要創建或呼召任何定義功能都必須寫在 main 裡\執行後將會 Output
注意事項-Java 十分重視句式結尾,千萬不要忘記在最後加上分號 ; (儘管不少IDE會自動提醒你)
<br/>
如何在不使用開發軟件的前提下,單獨運行 Java 檔案
1. 首先你的裝置上必須安裝了 JDK2. 手上持有 Java 檔案,例: [檔案名稱].java3. 打開命令提示元 CMD 並輸入 cd [檔案位置] 將目標位置設定在檔案文件夾4. 輸入 javac [檔案名稱].java 以創建執行 Java 用的檔案 [檔案名稱].class5. 最後在命令提示元中輸入 java [檔案名稱].java 即可
<br/>
如何單獨運行 Java 檔案並附帶參數 Parameter
1. 首先依照上述的指示做一遍2. 在最後一步的指令後方添加任意Parameters\java [檔案名稱].java \<parameter1> \<parameter2> \<...>\所有Parameters將會儲進一個Array並傳遞至main裡面的String[] args\你便可以在main裡根據Array的內容進行其餘的指令, 如
章節二 - Objects Oriented Programming (OOP)
Java 開發的核心基本圍繞在 Object, 而 Object 的原型就是 Class
甚麼是 Class
簡單來說 Class 是一個包含虛化定義的 Template, 在實體化後就變成 Object\舉個例子
Class type 種類
不同的種類會導致不同的存取權限\分類不限於 Class ,更能用在 Variable 和 Method 上
- Public (最大權限)\Project內任何檔案都能存取- Protected\同一 Class, Package, 其他 Package 的 Subclass 能存取- Default\僅限同一 Class, Package 能存取- Private (最小權限)\僅限同一 Class 能存取
例子
<br/>
甚麼是 Method
Method主要用於定義功能,執行範圍內的指令且能選擇是否返回數值\在絕大部分語言中稱作 Function, 而在 Java 裡叫 Method
常見例子
<br />
每個 Class裡都有的 Constructor
Constructor是會在 Object 創建時觸發的 Method, 主要用於初始化不同 Object\每個 Class 中均隱藏著一個 Default Constructor\而開發者可以新增額外/覆蓋預設的 Constructor
例子
執行後的 Output
<br/>
筆記正在草擬...\也許到這裡你對實際的開發還沒明白透徹, 無須擔心, 稍後將會作更多解釋
實用鏈接
To be added..
Web Development (Basic) — HTML, CSS, JavaScript, jQuery
The foundation of every website on the open web is three languages: HTML for structure, CSS for presentation, and JavaScript for behaviour. Modern frameworks (React, Vue, Svelte) all compile down to those three. This post covers the basics that the advanced post and any future framework work assume — semantic HTML, the modern CSS layout systems (Flexbox + Grid), responsive design, vanilla JS DOM manipulation, jQuery (still found in older codebases), forms, and the accessibility minimum.
Learning Outcome
- Write semantic, valid HTML5.- Lay out pages with Flexbox and CSS Grid.- Make a site responsive with media queries.- Manipulate the DOM with vanilla JavaScript and jQuery.- Build accessible forms and handle their submission.- Set up a minimal local development environment.
Chapter 1 — How the web works (one paragraph)
A browser sends an HTTP(S) request to a server; the server replies with an HTML document; the browser parses it, loads any linked CSS + JS + images, builds the DOM (the in-memory tree of elements) and CSSOM (the matched style tree), and renders pixels. JavaScript can later mutate the DOM and styles, triggering re-renders. Every "fancy" feature ultimately reduces to those moves.
Terminology
- HTML — HyperText Markup Language; the structural language of web pages.- CSS — Cascading Style Sheets; selectors + property declarations that style HTML.- DOM — Document Object Model; the tree of nodes that the browser builds from HTML.- JavaScript (ES) / ECMAScript — the language that runs in the browser and (via Node.js) on servers.- Viewport — the visible area of the browser window.- Selector — a CSS pattern that targets HTML elements.
Chapter 2 — HTML essentials
Minimal HTML5 document
Always:- — first line.- (or the right language) — accessibility + SEO.- — avoid mojibake.- — required for mobile responsiveness.- on — runs after HTML parsed; almost always correct.
Semantic elements
Use the right element for the meaning, not just everywhere:
| Element | Use ||---------|-----|| | top of a page or section || | main navigation links || | unique page content (only one per page) || | thematic grouping || | self-contained piece (blog post, comment) || | sidebar, callout || | bottom of a page or section || + | image with caption || | clickable action || | navigation |
Semantics matter for accessibility (screen readers), SEO, and code readability. is keyboard-accessible by default; a is not.
Common elements quick-reference
> Trick: the attribute on is not optional. Use a meaningful description; or if purely decorative. Empty tells screen readers to skip it.
Chapter 3 — CSS basics
Linking
Selectors
The cascade
When multiple rules match, the winner is decided by:
1. Origin + importance — user styles → author styles → author styles → user → browser default.2. Specificity — inline (1000) → id (100) → class/attr/pseudo (10) → element (1).3. Source order — later wins on ties.
Avoid in normal code; it almost always means the cascade was lost. Refactor instead.
Box model
Every element has: content → padding → border → margin.
Set this globally in every project.
Useful units
| Unit | Meaning ||------|---------|| | absolute pixels || | multiple of the root font size (1rem = 16px by default) || | multiple of the parent's font size || | percentage of the parent || | percent of viewport width / height || | bounded fluid value |
for font sizes; for tight UI details; / for fluid layouts.
Chapter 4 — Flexbox
Flexbox is the right layout choice for one-dimensional arrangements (row or column).
Key parent properties:
| Property | Effect ||----------|--------|| | / / / || | space between children || | main-axis: start / end / center / space-between / space-around / space-evenly || | cross-axis alignment || | (default) or |
Key child properties:
| Property | Effect ||----------|--------|| | grow ratio when extra space || | shrink ratio when not enough || | preferred size before growing/shrinking || | shorthand for — equal share || | override for one child |
Chapter 5 — CSS Grid
Grid is the right choice for two-dimensional layouts (rows AND columns).
That one declaration creates a responsive image grid: as many columns as fit at minimum 220px each, the rest fluid.
Common patterns:
> Trick: Grid for the page skeleton, Flexbox for the components inside it. Grid handles "where do regions sit on the page?". Flexbox handles "how do icons + text align inside this button?".
Chapter 6 — Responsive design
The mobile-first pattern: write base styles for small screens, add complexity at larger breakpoints with .
Standard breakpoints (rough): 480 (large phone), 768 (tablet), 1024 (laptop), 1280+ (desktop).
Use container queries () in modern browsers when component layout should depend on the container's width, not the viewport's.
Chapter 7 — JavaScript essentials
Variables
Types
, , , , , , (object subtype), (object subtype).
DOM manipulation
/ (ES2017+) is the modern way to handle promises — readable, error-handled like sync code.
Useful patterns
Chapter 8 — jQuery (still found in older codebases)
jQuery dominated 2008-2018. Modern browsers shrank its job — but you'll still see it in legacy code, WordPress themes, and many enterprise apps.
Vanilla-JS equivalents:
| jQuery | Modern JS ||--------|-----------|| | || | || | || | || | CSS transitions on |
> Trick: for new projects, skip jQuery. The vanilla DOM API is good enough since 2017. For legacy projects, keep jQuery — re-platforming costs more than the bytes.
Chapter 9 — Forms
Browser-built validation:- , , , , , , , .- The browser prevents submission and shows native messages.
JavaScript-side handling:
Chapter 10 — Accessibility minimum
| Rule | Why ||------|-----|| Use semantic HTML | screen readers + keyboard get correct affordances for free || on every form input | inputs need labels || Sufficient colour contrast (WCAG AA: 4.5:1 for text) | low-vision users || styles visible | keyboard users must see where they are || on every image | screen readers; SEO || Heading hierarchy (one , then , ...) | document outline || on | pronunciation, translation || Use sparingly — only when no semantic HTML fits | "no ARIA is better than bad ARIA" || Test with keyboard only (Tab, Shift+Tab, Enter) | the cheapest accessibility test |
Run axe DevTools or Lighthouse for automated checks.
Chapter 11 — Development environment
| Need | Tool ||------|------|| Editor | VS Code + Prettier + ESLint extensions || Local server | or VS Code Live Server extension || Format | Prettier — opinionated, drop-in || Lint JS | ESLint || Browser | Chrome / Firefox / Safari + DevTools || Source control | Git |
Open DevTools (F12 / Cmd+Opt+I) often:- Elements — inspect + edit live HTML/CSS.- Console — JS REPL, log output.- Network — every request, headers, timings.- Application — cookies, localStorage, service workers.- Lighthouse — performance / accessibility / SEO audit.
Practice Exercises
Exercise 1 — Personal page
Build a one-page personal site: header, hero, about, projects (cards), contact form. Use semantic HTML + a Grid skeleton + Flexbox inside components. Responsive at 480/768/1024.
Exercise 2 — Todo list (vanilla JS)
Static HTML; on form submit, append a new with the entered text + a delete button. Persist to across reloads.
<details><summary>Skeleton</summary>
</details>
Exercise 3 — Fetch + render
Call with ; render each user as a card with name, email, city.
Exercise 4 — Responsive gallery
A grid of 12 images. At < 600px → 1 column. 600-900 → 2 cols. > 900 → 3 cols. Use Grid + .
Exercise 5 — Form validation
A signup form (name, email, age, password). Use HTML5 attributes for native validation. Add a JS-side check that the password is ≥ 8 chars and contains a digit. Show errors below each input without losing focus.
Cheat-sheet
| What | How ||------|-----|| HTML doctype | || Viewport (mobile) | || Semantic regions | || Box sizing default | || 1D layout | Flexbox || 2D layout | Grid || Mobile-first media | || Modern variables | / (avoid ) || Query DOM | || Class toggle | || Event | || HTTP | then || Async | / || jQuery still useful? | only in legacy / WordPress || Accessibility | semantic HTML + label + alt + keyboard test || Audit | Lighthouse in DevTools |
What's next
The advanced post covers Node.js, package managers, modern build tools (Vite), the framework families (React / Vue / Svelte), CSS frameworks (Tailwind / Bootstrap), Three.js for 3D, API integration, and deployment.
References
- MDN Web Docs — the canonical reference for every HTML / CSS / JS feature.- web.dev — Google's modern practices guide.- CSS-Tricks: A Complete Guide to Flexbox- CSS-Tricks: A Complete Guide to Grid- WCAG 2.1 quick reference- Eloquent JavaScript by Marijn Haverbeke — free online; canonical JS book.
> Note: this post is in progress. Planned additions: CSS custom properties + theming, modern logical properties, transitions + animations, intersection observer, intl APIs.
Logic Circuit Design
Every processor, memory controller, radio baseband and washing-machine timer is built from the same small vocabulary: a handful of logic gates, a clock, and a discipline for reasoning about them. Digital design is the bridge between "a transistor is an analogue switch" and "this chip runs an operating system". This post walks that whole bridge in one pass — number representations, Boolean algebra, gates and their CMOS reality, combinational minimisation, the standard blocks, sequential logic and timing, finite state machines, memory and programmable logic, and finally how all of it is actually written today in a hardware description language.
Learning Outcome
- Convert between number bases, and explain why two's complement beat its rivals.- Manipulate Boolean expressions with the axioms, De Morgan's laws and duality; build any gate from NAND alone.- Explain what a CMOS gate physically is, and reason about fan-out, propagation delay and power.- Minimise combinational logic with Karnaugh maps (2–4 variables, don't-cares included), fix hazards, and know when to reach for Quine–McCluskey.- Assemble adders, comparators, multiplexers, decoders and encoders into an ALU.- Distinguish latches from flip-flops, compute a design's maximum clock frequency, and design an FSM end to end in both Moore and Mealy form.- Describe SRAM, DRAM, ROM, PLA/PAL and FPGA architecture, then write synthesisable Verilog — FSM and testbench included — and simulate it with free tools.
Chapter 1 — Number systems and codes
Terminology
- Radix (base) — how many distinct digits a positional system uses.- MSB / LSB — most / least significant bit: the leftmost and rightmost bit of a word.- Word — a fixed-width group of bits handled as a unit (8, 16, 32, 64 bits).- Code — an assignment of bit patterns to things that are not plain numbers (BCD, Gray, ASCII).
Conversion. Binary ↔ octal and binary ↔ hexadecimal are trivial because 8 = 2³ and 16 = 2⁴: group bits in threes or fours from the LSB.
Decimal → binary is repeated division by 2 for the integer part (read remainders bottom-up: 45 → 101101) and repeated multiplication by 2 for the fraction, reading the carries top-down: gives .
> Trick: memorise the sixteen hex digits and the powers of two to 2¹⁶. Nearly all "mental arithmetic" in digital design is pattern recognition on those two tables.
Signed representations
| Scheme (8-bit) | −5 encoded | Range | Zeros | Addition hardware ||---|---|---|---|---|| Sign-magnitude | | −127 … +127 | two | separate compare + subtract path || One's complement | | −127 … +127 | two | adder plus end-around carry || Two's complement | | −128 … +127 | one | ordinary unsigned adder, unchanged |
Two's complement won for one reason: the same adder serves signed and unsigned operands — no correction step, no end-around carry, no second zero. Negation is "invert all bits, add one", and the MSB simply carries weight −2^(n−1) instead of +2^(n−1):
Two consequences: sign extension is replication of the MSB, and subtraction is — one adder, an inverter row, a forced carry-in.
Overflow
Overflow is not the carry-out. For two's-complement addition it occurs iff the carry into the MSB differs from the carry out of the MSB — equivalently, iff both operands share a sign and the result has the opposite one.
The same bit pattern is a valid unsigned answer, so hardware raises both and and lets the instruction set decide which matters.
Fixed point, floating point, and codes
Fixed point declares an implied binary point at a fixed position — a 16-bit value stores the real number times 2⁸ — so arithmetic is ordinary integer arithmetic plus a shift after multiplication: cheap, exact, the default in DSP and control loops. Floating point (IEEE 754 binary32: 1 sign bit, 8 exponent bits biased by 127, 23 stored fraction bits plus an implied leading 1) trades a wider dynamic range for variable absolute precision and considerably more silicon. Use fixed point when the signal range is known, floating point when it is not.
BCD stores each decimal digit in its own 4-bit field (59 → ), leaving – unused, because displays, financial arithmetic and legacy instrumentation want exact decimal digits. Its addition needs a correction — if a digit sum exceeds 9, add 6:
Gray code orders values so consecutive ones differ in exactly one bit — for three bits — and converts in one line each way: , and back, , . It has three genuine uses: absolute position encoders (a disc read mid-transition is off by at most one, instead of returning garbage as would); Karnaugh map row/column ordering, which is exactly why adjacent cells differ in one variable; and clock domain crossing, where an asynchronous FIFO's Gray-coded pointers sample as either the old or the new value, never a nonsense mixture.
Text is just another code: ASCII is 7-bit (128 code points, = 0x41, = 0x61), and UTF-8 encodes Unicode in 1–4 bytes whose single-byte forms are exactly ASCII — which is why ASCII-era hardware and protocols survived the transition.
Chapter 2 — Boolean algebra
Terminology
- Literal — a variable or its complement (, ).- Product term — a conjunction (). Sum term — a disjunction ().- Dual — swap AND ↔ OR and 0 ↔ 1 throughout, leaving literals alone.
Notation: is OR, juxtaposition or is AND, is NOT, is XOR.
| Law | OR form | AND form ||---|---|---|| Identity | | || Null | | || Idempotence | | || Complement | | || Involution | | — || Commutative | | || Associative | | || Distributive | | || Absorption | | || Absorption (2nd) | | || De Morgan | | || Consensus | | |
is the one that catches people: it has no arithmetic analogue. Verify it once from the truth table, then trust it.
Duality: the dual of any Boolean identity is also an identity — which is why every law above has two columns, and why SOP and POS minimisation are the same procedure applied to opposite cells of a K-map.
> Watch out: the dual of an expression is not its complement. has dual and complement . De Morgan is duality plus complementing the literals.
Worked simplifications
1. Idempotence () lets a term be reused, so replicate twice more. The result is the majority function — 1 when at least two of three inputs are 1 — with four 3-literal terms reduced to three 2-literal ones:
2. Apply backwards to the first two factors; 3. is De Morgan applied twice:
> Common pitfall: , not . Break the bar, flip the operator. Writing is the single most common error in a first digital-logic exam.
Chapter 3 — Logic gates
Terminology
- Fan-in / fan-out — inputs a gate has / gate inputs one output drives.- Propagation delay (tpd) — worst-case time from an input change to the resulting output change.- Contamination delay (tcd) — time before which the output is guaranteed not to have started moving.- Functionally complete set — a set of gates from which every Boolean function can be built.
XOR is "the inputs differ", XNOR "the inputs are equal" — making XNOR the natural 1-bit equality comparator. Beyond two inputs XOR generalises to odd parity, which is why parity generators are XOR trees.
NAND and NOR are functionally complete
Tie both inputs of a NAND together and you have an inverter; everything else follows:
Check the XOR on : X = 0, = 1, = 1, = 0. Correct. The NOR duals are just as short: , , . This matters commercially — a process only has to characterise one gate cell to build anything.
What a CMOS gate actually is
A static CMOS gate is two complementary transistor networks between the supply rails with the output node between them. The pull-up network is PMOS to VDD (a PMOS conducts when its gate is low); the pull-down network is NMOS to GND (conducts when its gate is high). The two are duals — series in one is parallel in the other — so for any input combination exactly one conducts, the output is always driven, and statically no current flows rail to rail. A NAND2 is two series NMOS below, two parallel PMOS above; a NOR2 is the mirror image. Three consequences:
1. CMOS gates are naturally inverting. NAND2 and NOR2 cost 4 transistors; AND2 and OR2 cost 6, being the inverting gate plus an inverter. Synthesis tools therefore prefer NAND/NOR/inverter forms — a "cheap" AND-OR schematic is not cheap silicon.2. NAND is faster than NOR at equal drive. NOR stacks PMOS in series, and holes have lower mobility than electrons, so that stack must be made wide — costing area and input capacitance. Standard-cell libraries are NAND-heavy for this reason.3. A gate input is a capacitor, not a resistor. It draws essentially no DC current.
Fan-out, delay and power
Because inputs are capacitive, CMOS has no hard DC fan-out limit the way bipolar TTL did (where fan-out was a real current budget of order 10–20 unit loads). What fan-out costs in CMOS is time: each load adds capacitance, and delay rises roughly linearly with the load being charged and discharged. Processes are commonly characterised by the FO4 delay — an inverter driving four copies of itself — precisely because it is a load-normalised yardstick. Delay is also asymmetric: and need not be equal, and datasheets quote both across process, voltage and temperature corners. Design to the maximum; use the contamination delay only for hold checks.
is the activity factor — the fraction of cycles in which a node toggles. Three levers fall straight out: lower VDD (quadratic, hence dynamic voltage scaling), lower , or lower by clock-gating idle blocks. Static leakage was negligible in older processes and is a first-class problem in modern ones, which is why power gating exists.
Chapter 4 — Combinational design and minimisation
Terminology
- Combinational circuit — output depends only on present inputs. No memory, no feedback.- Minterm (mi) / maxterm (Mi) — a product term true for exactly one input row / a sum term false for exactly one row.- Implicant — a product term that implies the function. Prime implicant (PI) — one that cannot be enlarged further. Essential PI — the only PI covering some minterm.
Canonical forms
Take true for rows 1, 3, 5, 7:
The index sets are complements: whatever is not a minterm of F is a maxterm of F. For row i, the minterm takes each variable uncomplemented where its bit is 1; the maxterm does the exact opposite. Both forms implement directly — SOP as two-level AND-OR, POS as OR-AND — and both are usually far from minimal ( is just ).
Karnaugh maps
A K-map redraws the truth table so that physically adjacent cells differ in exactly one variable — hence the Gray-code label order . Adjacent 1-cells then merge: a group of 2^k cells eliminates k variables. Groups must be rectangles of size 1, 2, 4, 8 …; they may wrap around both edges (the map is a torus); they may overlap; make each as large as possible and keep going until every 1 is covered.
Worked example 1 — three variables,
The whole and columns (m0, m2, m4, m6) form a group of four, all with C = 0, eliminating A and B: term . Cells m4 and m5 (bottom row, columns and ) have A = 1, B = 0: term . So . Both are prime and both essential — alone covers m0, m2, m6, and alone covers m5.
Worked example 2 — four variables,
The four corners m0, m2, m8, m10 are adjacent — the map wraps both ways — and all have B = 0, D = 0: term . The centre block m5, m7, m13, m15 all have B = 1, D = 1: term . So — sixteen literals in canonical form reduced to one XNOR gate. That is the payoff of the method, and a warning: the right answer here is invisible in the algebra and obvious in the picture.
Don't-care conditions
A don't-care () marks an input combination that cannot occur or whose output nobody reads. Treat each independently as 0 or 1 — whichever enlarges a group. Take "the BCD digit is 5 or greater": patterns 10–15 never occur.
The bottom half (rows and , eight cells) gives ; m5, m7, m13, m15 (1, 1, d, d) give ; m6, m7, m14, m15 (1, 1, d, d) give . So with the don't-cares, against without them — same behaviour on every input that can actually happen, noticeably less hardware.
> Trick: don't-cares are free minimisation. Whenever a spec says "unused encoding", "never happens" or "output ignored while is low", write into the truth table rather than picking 0 out of habit.
Essential prime implicants and cyclic maps
Circle every maximal group: those are the prime implicants. Take all essential ones first, then cover what remains as cheaply as possible. Sometimes none is essential — as for :
The PIs are , , , , , — six, each minterm covered by exactly two. This is a cyclic map with two equally minimal solutions, and . Neither is more correct; pick whichever shares terms with the rest of the design.
Quine–McCluskey
K-maps stop being drawable past about six variables and stop being reliable past four or five. Quine–McCluskey is the same idea made mechanical so a program can do it: (1) list all minterms and don't-cares as bit patterns, grouped by their number of 1s; (2) compare every term in group k with every term in group k+1, combining any pair that differs in exactly one bit into a term with in that position, and ticking both parents; (3) repeat until nothing more combines — everything left unticked is a prime implicant; (4) build a prime-implicant chart (PIs as rows, real minterms as columns), select the essential PIs, delete their columns, and solve the remaining covering problem with Petrick's method or a heuristic.
It is exact and exhaustive, and therefore exponential. Real tools (Espresso, and the minimisers inside every synthesis flow) use heuristics — but knowing this shape tells you what your synthesiser is approximating.
Hazards
Minimisation assumes instantaneous gates. A two-level network whose inputs change can produce a brief wrong output — a glitch. A static-1 hazard is an output that should stay 1 dipping momentarily to 0; a static-0 hazard is the mirror image; a dynamic hazard is an output that should change once changing three or more times, which needs multiple reconverging paths of differing delay and so appears in multi-level rather than clean two-level networks.
The classic case is . Hold B = C = 1: then F = A + A' = 1 for both values of A, so the output should never move. But when A falls 1→0, drops immediately while only rises after the inverter's delay, and for that window the OR sees two zeros. The fix is the consensus term — logically redundant, but it bridges the two groups that previously only touched on the K-map:
is 1 whenever B = C = 1 regardless of A, holding the OR high through the changeover, at the cost of one AND gate.
> Watch out: a synthesis tool will happily remove a redundant term as an optimisation. If you need the hazard-free form (asynchronous logic, a latch enable, a clock-gating cell), mark it /.
In fully synchronous design, glitches are usually harmless — they occur right after a clock edge and need only settle before the next setup window. Hazards become critical exactly where the synchronous discipline does not apply: asynchronous circuits, level-sensitive enables, reset trees and clock networks.
Chapter 5 — Standard combinational blocks
Adders
is "at least two of three inputs are 1" — the majority function from Chapter 2 — and is 3-input odd parity.
Chain n full adders carry-to-carry and you have a ripple-carry adder: small, simple, and with worst-case delay , linear in n. At roughly two gate delays per stage a 32-bit ripple adder costs over 60 gate delays, and since the adder normally sits on the critical path it caps the whole design's clock.
Carry-lookahead removes the chain. Per bit, define ("generate" — this bit makes a carry regardless of the incoming one) and ("propagate"). Then , and expanding the recursion gives every carry as a two-level function of the inputs:
One gate delay for all P and G, two more for the carries — constant time. But fan-in grows with block width, so real designs use 4-bit lookahead blocks and apply the same trick a level up on block-level and , giving logarithmic delay overall. Carry-select, carry-skip and parallel-prefix adders (Kogge-Stone, Brent-Kung) are variations on trading area for that logarithm.
Subtraction and comparison
Subtraction needs no new datapath. XOR each input with a signal and feed into : gives , gives . Flags fall out of the same adder — = all sum bits zero, = sum MSB, = carry out, = . A dedicated comparator is simpler: one bit gives , , . For n bits, equality is the AND of all bit XNORs; magnitude is resolved by scanning from the MSB down to the first position where the bits differ — which is exactly what the chained , , inputs of a cascadable comparator (the 74x85 family) expose.
Multiplexers, demultiplexers, decoders
A 2:1 MUX is ; a 4:1 MUX is . A demultiplexer routes one input to one of 2^k outputs; a decoder is a demux with its data input tied to 1, so its outputs are precisely the minterms of the select inputs — a 2-to-4 decoder with enable is , , , .
Because a 2^n:1 MUX with the variables on its selects outputs the truth-table entry those variables address, any n-variable function is one MUX plus constants. Better still, with n−1 selects the data inputs take , , or for the remaining variable (Shannon expansion). For on a 4:1 MUX with A, B on the selects:
One MUX and one inverter for an arbitrary 3-variable function — the direct ancestor of the FPGA look-up table in Chapter 8.
Encoders, priority encoders, and the ALU
A plain 2^k-to-k encoder outputs the index of the single active input and misbehaves badly if two are active, or none. A priority encoder fixes both — highest-priority active input wins, plus a flag:
This is how interrupt controllers pick a winner and how floating-point normalisers find the leading one.
An ALU is all of these blocks in parallel behind a multiplexer: adder/subtractor, AND, OR, XOR and a shifter fed the same and , with driving a MUX that chooses whose answer escapes and taken from the adder. Every unit computes every cycle, which is wasteful in power — real ALUs gate the unused ones — but logically that picture is the whole story.
Chapter 6 — Sequential logic
Terminology
- Sequential circuit — output depends on present inputs and stored state: combinational logic plus feedback through memory elements.- Latch — level-sensitive storage, transparent while its enable is asserted.- Flip-flop — edge-triggered storage, sampling only at a clock edge.- Setup / hold time (tsu, th) — how long data must be stable before / after the clock edge.- Clock-to-Q (tcq) — delay from the clock edge to a valid output.- Clock skew — difference in clock arrival time between two flip-flops.
Latches and the transparency problem
Cross-couple two NOR gates for an SR latch: sets , clears it, holds, and is forbidden (both outputs go low, and simultaneous release is a race). Add an enable and a data input for a gated D latch: while is high follows ; when falls, freezes.
That transparency is the problem. If the output feeds combinational logic that returns to its own input — exactly what a counter or state register does — the new value races round the loop during the enable window and can update the latch again in the same pulse, advancing the state an unpredictable number of times. The fix is to sample at an instant rather than over an interval: a master-slave pair of latches on opposite clock phases is never transparent in both halves at once, so data advances exactly one stage per edge.
Flip-flop tables
| Type | Behaviour | Characteristic equation ||---|---|---|| D | follows D at the edge | || JK | 0,0 hold · 0,1 reset · 1,0 set · 1,1 toggle | || T | 0 hold · 1 toggle | || SR | 0,0 hold · 0,1 reset · 1,0 set · 1,1 invalid | , with |
Excitation tables answer the design question — "I want this transition, what input do I apply?":
The entries are don't-cares, and they are why JK designs used to minimise better than D designs. That advice is now obsolete: FPGA and ASIC cells are D flip-flops, and a synthesiser builds JK or T behaviour from a D flip-flop plus a little logic. Design with D flip-flops.
Timing: where the clock frequency comes from
For a path leaving flip-flop A, crossing combinational logic and arriving at flip-flop B, data must be stable before B's setup window opens. The second inequality is the one beginners forget:
To go faster you must shorten the longest path — pipeline it, restructure the logic (lookahead instead of ripple), or use faster cells.
> Watch out: a hold violation cannot be fixed by slowing the clock — does not appear in the inequality. The data arrives too early, not too late. Fix it with delay buffers on the data path or by reducing skew. Setup violations are the ones a slower clock cures.
Metastability and synchronisers
A flip-flop whose input changes inside its setup/hold window may go metastable: its output hovers between logic levels for an unbounded time before resolving arbitrarily. This is physics, not a bug to design away, but the probability of still being unresolved after time falls exponentially — , where and are flip-flop characteristics and , the sampling and event rates. Because the decay is exponential, buying resolution time is extremely effective — hence the two-flop synchroniser, which gives the first flop almost a full clock period to settle before the second samples it (three stages for very high clock rates or reliability targets). Two rules go with it:
1. Never synchronise a multi-bit bus bit-by-bit. Each bit resolves independently, so the receiver can latch a combination that never existed. Cross a single-bit flag and use it to qualify a bus held stable (a handshake), Gray-code the value so only one bit changes at a time, or use a proper CDC FIFO.2. Synchronise once. Feeding one asynchronous signal into two synchronisers can give the two copies different answers in the same cycle.
Registers and counters
A register is n flip-flops sharing a clock; add a load enable and a mux and it holds or loads. A shift register wires each Q to the next D — serial-in/parallel-out, parallel-in/serial-out, bidirectional, or with taps and XOR feedback as a linear feedback shift register for pseudo-random sequences and CRCs.
| | Ripple (asynchronous) counter | Synchronous counter ||---|---|---|| Clocking | each FF clocked by the previous FF's output | all FFs share one clock || Delay | cumulative — n · tcq to settle | one tcq plus next-state logic || Decoding | transient wrong states → decoding glitches | glitch-free if outputs are registered || Timing analysis | painful (generated clocks) | straightforward || Use in new designs? | almost never | yes |
Designing a modulo-6 synchronous counter
Count 0→1→2→3→4→5→0 with three D flip-flops . States 6 and 7 are unreachable, so their next states are don't-cares.
Always finish by checking that the unused states cannot lock up. State 110 gives , , → 111; state 111 gives , , → 100, inside the legal ring. This counter is self-recovering: an illegal state caused by noise or power-up rejoins the sequence within two clocks. When that is not guaranteed, add a reset — which you should do anyway.
Chapter 7 — Finite state machines
Terminology
- FSM — a sequential circuit given by a finite state set, a transition function and an output function.- Moore machine — outputs depend on the current state only.- Mealy machine — outputs depend on the current state and current inputs.- State assignment — the choice of bit pattern representing each state.- Equivalent states — states producing identical output for every input sequence, so mergeable.
| | Moore | Mealy ||---|---|---|| Output is a function of | state | state and input || Output timing | changes only after a clock edge; one cycle "late" | responds in the same cycle || Output glitches | none — a decode of registered state | possible — input glitches pass through || State count | usually more | usually fewer or equal || Timing analysis | clean | input-to-output path crosses the module boundary |
Practical guidance: use Moore for anything leaving the module (registered, glitch-free, easy to time), and Mealy inside a module when the one-cycle latency actually matters. A common hybrid is a Mealy machine with registered outputs — which is a Moore machine with extra steps, and often the cleanest of the three.
The flow is always: spec → state diagram → state table → state minimisation → state assignment → next-state and output equations → implementation.
Worked FSM: a "1011" sequence detector
Detect in a serial bit stream, with overlap (so contains two occurrences). Moore version, states named by the longest prefix matched so far:
| State | Meaning | on 0 | on 1 | Output ||---|---|---|---|---|| S0 | nothing matched | S0 | S1 | 0 || S1 | | S2 | S1 | 0 || S2 | | S0 | S3 | 0 || S3 | | S2 | S4 | 0 || S4 | — detected | S2 | S1 | 1 |
The non-obvious transitions are the failure ones, each found by asking what is the longest prefix of the pattern that is a suffix of what I have just seen? S3 on 0 leaves the stream ending , whose longest such suffix is → S2, not S0. S4 on 0 ends → also S2. S4 on 1 ends , longest such suffix → S1.
For the non-overlapping variant, S4 restarts from scratch: on 0 → S0, on 1 → S1. That single row is the entire difference, and it is worth being explicit about which one the spec wants.
The Mealy version needs only four states, because detection is signalled on the transition into the match rather than by a state representing it:
| State | on 0 (next / out) | on 1 (next / out) ||---|---|---|| S0 | S0 / 0 | S1 / 0 || S1 | S2 / 0 | S1 / 0 || S2 | S0 / 0 | S3 / 0 || S3 | S2 / 0 | S1 / 1 |
Both machines on the same stream — identical detections, one fewer state, and the Mealy output asserting a cycle earlier (high during the cycle in which the final is presented, rather than after it has been clocked in):
State minimisation
Two states are equivalent when, for every input, they give the same output and go to equivalent states. Two mechanical methods: partition refinement (split states into groups by output, then repeatedly split any group whose members transition, on the same input, into different groups, until nothing splits) and the implication chart (a triangular table of state pairs, crossing out pairs with different outputs and iterating on the implied pairs). Neither helps the detector — its five Moore states all differ — but both matter when a machine is written directly from an informal spec, where duplicate states are common.
State assignment: one-hot vs binary
| | Binary (encoded) | One-hot ||---|---|---|| Flip-flops for N states | ceil(log2 N) | N || Next-state logic | wider, deeper | narrow — often one product term per transition || Output decode | a decoder over the state bits | a single wire || Best for | ASIC, register-poor targets, large N | FPGA, small-to-medium N, high fmax |
FPGAs have flip-flops in abundance and are limited by logic depth, so one-hot usually wins there and is often what the tool picks regardless of how you wrote it. Gray-coded assignment suits a machine that mostly walks a linear sequence, minimising switching and hence power. Whatever the encoding, write a branch returning to a safe state — a single upset bit in a one-hot register produces an all-zero or two-hot state that no legal transition covers.
Chapter 8 — Memory and programmable logic
SRAM vs DRAM at the cell level
| | SRAM | DRAM ||---|---|---|| Cell | 6 transistors: two cross-coupled inverters + 2 access transistors | 1 transistor + 1 capacitor || Storage | a latched, actively driven state | charge on a capacitor || Read | non-destructive | destructive — must be written back || Refresh | none while powered | yes, every row periodically (tens of ms) || Density | low | several times denser per bit || Speed | fast, low latency | slower; row-activate / column-access protocol || Typical use | caches, register files, FPGA block RAM | main memory |
The 6T SRAM cell is a bistable pair of inverters — the same feedback loop as an SR latch — with two pass transistors connecting it to the bit lines when its word line is selected. Being actively driven, it holds indefinitely while powered and reads without disturbance. The 1T1C DRAM cell holds charge that leaks, so reading dumps it onto the bit line where a sense amplifier compares it against a reference and rewrites the row. That destructive read plus refresh is the entire reason DRAM has a complicated protocol and SRAM does not. Both are volatile; neither survives power loss.
The non-volatile family
| Type | Programmed | Erased | Granularity | Typical use ||---|---|---|---|---|| ROM (mask) | at fabrication | never | — | huge-volume fixed firmware || PROM | once, by the user (fuses/antifuses) | never | — | one-time configuration || EPROM | electrically | UV through a quartz window | whole chip | historical; development parts || EEPROM | electrically | electrically | byte | configuration and calibration stores || Flash (NOR) | electrically | electrically | block erase; random reads | code storage, execute-in-place || Flash (NAND) | electrically | electrically | page write / block erase | mass storage (SSD, SD, eMMC) |
NOR gives random reads, so a CPU can fetch instructions directly; NAND gives density and is used where data is streamed. Both wear out as erase cycles degrade the oxide, which is why controllers do wear levelling.
Logic in a ROM, and the programmable arrays
A ROM with n address lines and m data lines is a full truth table for m functions of n variables: its decoder generates all 2^n minterms and the programmed array ORs the selected ones onto the outputs. No minimisation is needed or possible — you store the answer. The cost is exponential in input count (a 16-input function needs a 64K-word ROM), so ROM-based logic suits genuinely irregular functions: character generators, instruction decoders, microcode.
Between hard-wired gates and a full truth table sit the programmable arrays. A PLA has a programmable AND plane and a programmable OR plane — maximum flexibility, slower and more expensive. A PAL has a programmable AND plane and a fixed OR plane (a fixed number of product terms per output) — cheaper and faster; the classic 22V10 added an output macrocell with an optional flip-flop, which is what made PALs usable for state machines. A CPLD is an array of PAL-like blocks joined by global interconnect, with deterministic timing and instant-on behaviour — still the right answer for board glue logic and power sequencing.
FPGA architecture
An FPGA is a sea of configurable blocks plus programmable routing, its configuration held in SRAM and therefore loaded from external Flash at power-up:
- LUT (look-up table) — a k-input SRAM, typically k = 4 or 6, holding 2^k configuration bits, implementing any function of k variables by storing its truth table. This is the MUX-as-arbitrary-function trick from Chapter 5, made programmable.- Flip-flop — one or two per logic cell, after the LUT with an optional bypass. Registers are effectively free, which is why one-hot encoding and deep pipelining suit FPGAs.- Carry chain — a dedicated fast path between adjacent cells, so adders and counters skip general routing delay.- Routing fabric — wire segments and programmable switch matrices. Routing, not logic, dominates delay, which is why timing closure is a place-and-route problem.- Block RAM — hard dual-ported SRAM blocks, usable as RAM, ROM or FIFO. DSP slices — hard multiply-accumulate units.- Clock management — PLLs/MMCMs plus dedicated low-skew global clock networks. Always use those networks for clocks; never route a clock through the general fabric.
Chapter 9 — HDL in practice (Verilog)
Terminology
- HDL — hardware description language. It describes structure and behaviour, from which a synthesiser infers gates. It is not a program.- Synthesisable subset — the constructs a synthesis tool can map to hardware. Everything else is simulation-only.- RTL — the "registers, and the combinational logic between them" abstraction that synthesisable HDL describes.
The one thing to internalise: HDL is not sequential code. Every and every block in a module is hardware that exists simultaneously and runs continuously. Statements inside an block are evaluated in order during simulation, but what they describe is a network of gates that settles, not a sequence of steps executing over time. Reasoning "this line runs, then that line runs" produces code that simulates one way and synthesises another — the classic and most expensive bug in the field.
Module, ports, wire and reg
is a continuous assignment: the left side is recomputed whenever anything on the right changes. It drives a and describes combinational logic.
is Verilog's most misleadingly named keyword. It does not mean "flip-flop" — it means "a variable assigned inside a procedural block". A assigned in is combinational logic; a assigned in is a flip-flop. SystemVerilog's replaces both and in most contexts, which is one good reason to write SystemVerilog where the tools allow it.
Blocking vs non-blocking
> Use non-blocking () in clocked blocks and blocking () in combinational blocks. Never mix the two in one block, and never drive one signal from two blocks.
Why it matters — the swap, and the accidental latch:
Non-blocking assignments schedule their updates and apply them together at the end of the time step — exactly what a bank of flip-flops does, every flop sampling the values that existed just before the edge. Blocking assignments take effect immediately, modelling a wire rather than a register. Get this backwards and simulation and synthesis disagree; the tools are not obliged to warn you. The latch rule is the same one from Chapter 6 seen from the language side: in a combinational block, assign every output on every path — including a in every . SystemVerilog's makes the tool check this for you.
An FSM the canonical way
The Moore detector from Chapter 7, in three-block style: one clocked block for the state register, one combinational block for next-state logic, one for outputs.
Every transition in the table appears exactly once, recovers from illegal states, and is a pure decode of the state. For the Mealy form, drop S4 and write — noting that now depends on an input and can therefore glitch. Two-block style (merging blocks 2 and 3) is equally fine, as is one-block style with registered outputs; mixing styles inside one module is how people end up with a signal driven from two places.
A testbench
Driving stimulus on the falling edge and checking after the next falling edge keeps the testbench clear of the design's setup and hold windows — a habit worth forming early.
Synthesisable or not
| Construct | Synthesisable? ||---|---|| , , | yes || , , with constant bounds (unrolled) | yes || , , | yes || blocks | no for ASIC; FPGA tools accept them for register initial values || delays, , / | no — simulation only || , , , | no — simulation only || , dynamic arrays, classes, data-dependent | no |
> Common pitfall: a delay inside a design module simulates beautifully and synthesises to nothing (or an error). Timing in real hardware comes from the clock and from cell delays, never from delay statements in your source.
A toolchain you can install today
Add nextpnr to place and route for the open-toolchain FPGA families (Lattice iCE40 and ECP5), or use the vendor tools — AMD/Xilinx Vivado, Intel/Altera Quartus Prime, Lattice Radiant — whose free editions cover the parts on most dev boards.
> Trick: run on every file before simulating. It finds inferred latches, incomplete sensitivity lists and width mismatches in a second, which is faster than finding them in a waveform.
Practice Exercises
Exercise 1 — Representations
(a) Convert 205 decimal to binary, octal and hexadecimal. (b) Write −37 as an 8-bit two's-complement value. (c) Adding the 8-bit signed values and , does overflow occur?
<details><summary>Solution</summary>
</details>
Exercise 2 — Algebraic simplification
Simplify to minimal SOP using the laws of Chapter 2, then confirm with a K-map.
<details><summary>Solution</summary>
All three are prime and all three essential — m1, m2 and m4 are each covered by only one of them.
</details>
Exercise 3 — Karnaugh map
Minimise and state which prime implicants are essential.
<details><summary>Solution</summary>
</details>
Exercise 4 — MUX implementation
Implement using a single 4:1 multiplexer with A and B on the select lines.
<details><summary>Solution</summary>
</details>
Exercise 5 — Timing
A path has , worst-case combinational delay , and skew . (a) What is fmax? (b) The design must run at 400 MHz — by how much must the logic delay fall, and name two ways to achieve it.
<details><summary>Solution</summary>
</details>
Exercise 6 — Hazard removal
Show that , built as a two-level AND-OR network, has a static-1 hazard, and give the hazard-free implementation.
<details><summary>Solution</summary>
</details>
Exercise 7 — Counter design
Design a synchronous modulo-5 up counter (states 000 through 100) with D flip-flops: write the state table, derive the three next-state equations treating the unused states as don't-cares, and check whether the result is self-recovering.
Exercise 8 — Verilog
Write a synthesisable 4-bit up/down counter with synchronous active-high reset, a input with 4-bit , and an direction control. Extend the Chapter 9 testbench pattern to exercise all four behaviours.
Cheat-sheet
| What | How ||------|-----|| Binary → hex; sign-extend | group bits in 4s from the LSB; replicate the MSB || Negate (two's complement) | invert all bits, add 1 || Signed overflow | || De Morgan | , || Absorption | , || Consensus | || NOT / OR from NAND | / || K-map column order | (Gray), and it wraps || Group of 2^k cells; don't-care | eliminates k variables; use as whichever enlarges the group || Static-1 hazard fix | add the consensus term || Half / full adder | , / , || Subtract with an adder | (invert B, ) || Lookahead carry | , , || n-var function on a MUX | variables on selects, truth table on data inputs || D / JK / T flip-flop | / / || Setup / hold checks | ; || Cross a clock domain | two-flop synchroniser; Gray-code multi-bit values || Verilog sequential vs combinational | with / with || Avoid an inferred latch | default-assign at the top of the block, or in the || Simulate free | + + |
Where to go deeper
- Computer architecture — the natural sequel. With an ALU, a register file and an FSM controller in hand, a single-cycle then pipelined RISC-V or MIPS datapath is a two-week project.- CMOS VLSI — the layer below this post: transistor sizing, logical effort, layout, and where the timing numbers you were handed come from.- Static timing analysis and timing closure — constraints, clock trees, multi-corner analysis, false and multi-cycle paths. This is most of the day-to-day work in real FPGA and ASIC flows.- Clock domain crossing and asynchronous design — handshakes, async FIFOs, reset synchronisation. The failures are intermittent and expensive; read the literature properly.- SystemVerilog and verification — , /, interfaces, assertions, constrained-random stimulus, UVM.- Get a board. An iCE40 or ECP5 runs entirely on the open toolchain; an Artix or Cyclone gets you the vendor flow. Nothing here is properly learned until a blinking LED has been debugged with a logic analyser.
References
- Digital Design and Computer Architecture — Harris & Harris. The best single bridge from gates to a working processor.- Digital Design: Principles and Practices — John F. Wakerly. Thorough on minimisation, hazards and real device families.- Digital Design: With an Introduction to the Verilog HDL — Mano & Ciletti. The standard first course.- CMOS VLSI Design: A Circuits and Systems Perspective — Weste & Harris. For Chapter 3's transistor-level material and logical effort.- Icarus Verilog — free Verilog/SystemVerilog simulator.- GTKWave — waveform viewer for VCD files.- Verilator — linter and high-speed simulator.- Yosys — open-source synthesis; nextpnr for place-and-route.- IEEE Standards Association — IEEE 1364 (Verilog) and IEEE 1800 (SystemVerilog).- Sunburst Design papers — Clifford Cummings on non-blocking assignments, FSM coding styles and clock domain crossing.
Planned future extensions:
- A companion post building a single-cycle RISC-V datapath up from the ALU and register file assembled here.- Rendered schematic and K-map figures to replace the ASCII diagrams.- A downloadable Verilog project (adder, FSM, counter, testbenches) with a Makefile for the Icarus/Verilator/Yosys flow.- A dedicated treatment of static timing analysis: constraints, corners, false paths, and how to read a timing report.- Asynchronous FIFO design worked end to end, as the practical follow-on to the clock-domain-crossing section.
Data Structure & Algorithm (C++)
Data Structure & Algorithm is the fundamental knowledge of programming. Learning how to store, organize, sort, search data allow us to code more efficiently and concisely.
Learning outcome
Apply structural programming approach to solve more complex computation problems.Demonstrate applications of standard data structures such as linked list, stack, queue and tree.Solve computation problems using recursion where appropriate.Understand different sorting and searching algorithms.
Chapter 1 - Basic Concepts of C++
Terminology
Abstract Data Type (ADT)
Common Standard Library Header
- \Support Standard I/O functions: , , , , , etc..- \Support Standard utility functions: , , , etc..- \Support String functions: , , , etc..- \Perform both input and output operations with the stream objects : and
Comments
Primitive Data types
| Data type | Size (byte) | Representation | Range of values ||-------------------- |---|------------------------------------|--------------------|| bool | 1 | Boolean | $\textnormal{false / true}$ || char | 1 | Signed number (2's complement) | $\textnormal{-128 to 127}$ || unsigned char | 1 | Unsigned number | $\textnormal{0 to 255}$ || int | 4 | Signed number (2's complement) | $-2^{31} \space \textnormal{to} \space 2^{31}-1$ || unsigned int | 4 | Unsigned number | $\textnormal{0 to } 2^{32}-1$ || short | 2 | Signed number (2's complement) | $-2^{15} \space \textnormal{to} \space 2^{15}-1$ || unsigned short | 2 | Unsigned number | $\textnormal{0 to } 2^{16}-1$ || long | 4 | Signed number (2's complement) | $-2^{31} \space \textnormal{to} \space 2^{31}-1$ || unsigned long | 4 | Unsigned number | $\textnormal{0 to } 2^{32}-1 $ || long long | 8 | Signed number (2's complement) | $-2^{63} \space \textnormal{to} \space 2^{63}-1$ || unsigned long long | 8 | Unsigned number | $\textnormal{0 to } 2^{64}-1 $ || float | 4 | IEEE 32-bit floating point number | $\pm 1.410^{-45} \textnormal{ to } \pm3.410^{38}$ || double | 8 | IEEE 64-bit floating point number | $\pm 510^{-324} \textnormal{ to } \pm1.79810^{308}$ || pointer | 4 | Memory address | $\textnormal{0 to } 2^{32}-1$ |
C++ File Structure
Header file (.h) Program file (.cpp)Functions Declaration Functions Implementation
Chapter 2 - Computation Complexity (Big-O)
There are two types of complexity- Time Complexity (Time spent)- Space Complexity (Memory space spent)
They both use three asymptotic notation to descript the complexity- $\textnormal{Big-O (O)}$- $\textnormal{Big-Omega }(\Omega)$- $\textnormal{Big-Theta }(\Theta)$
Big-O
Upper bound of the complexity$$ f(n) = \textnormal{O}(g(n)) $$
Big-Omega
Lower bound of the complexity$$ f(n) = \Omega(g(n)) $$
Big-Theta
Exact bound of the complexity$$ f(n) = \Theta(g(n)) $$
Common Complexity Classes
- Constant time - $O(1)$- Logarithmic time - $O(\log2 n)$- Linear time - $O(n)$- Log-linear time - $O(n\log2 n)$- Quadratic time - $O(n^2)$- Cubic time - $O(n^3)$- Polynomial time - $O(n^k)$- Exponential time - $O(2^n)$- Factorial time - $O(n!)$
Slope of Complexity Classes
TIme Complexity
Simple operations such as- declaration, assignment- cin, cout- function call- return
take constant amount of timeThe overall time complexity = O(Constant),\and constant time costs almost zero influence no matter the size.\Therefore the overall time complexity is$$ O(1) $$
Only looping will cost longer time complexity\Single nested loop usually takes as the operations inside the loop will run times.$$ C n $$
The overall time complexity is$$ O(n) $$While for more than one nested loop usually takes as the operations inside the loop will run times.$$ C n^2 $$
The overall time complexity is$$ O(n^2) $$
Best case
To be added..
Average case
To be added..
Worst case
To be added..
Space Complexity
To be added..O()
Chapter 3 - Linked Lists
A linked list is an object that only contains head node of the list.Each node is created with parameter [next] linked to next node or necessaryly [prev] linked to previous node.
Terminology
- Predecessor- Successor
Josephus Problem
People are standing in a circle waiting to be executed.Counting begins at a specified point in the circle andproceeds around the circle in a specified direction. Aftera specified number of people are skipped, the nextperson is executed. The procedure is repeated with theremaining people, starting with the next person, going inthe same direction and skipping the same number ofpeople, until only one person remains, and is freed
The problem — given the number of people (n), startingpoint, direction, and number to be skipped (k) — is tochoose the position in the initial circle to avoid execution.(guessing who is the survivor)
Linear List
Unordered / Random List
Ordered List
General List
Restricted List
Common Operations
Find length of linked list
Search element x from the beginning of list
Insert new element x at the front of list
Remove the first element x found in the list
Insert new element x in an ordered list
Common Issues
Null-pointer exceptionMemory leak
Variants of Lists
Singly Linked List with Header Node- Sentinel node
Circularly Linked List- Last node points back to first node
Doubly Linked List- Each node has next and back pointers
Circular Doubly Linked List- Boundary-tag method
Orthogonal List- ...
Chapter 4 - Stacks and Queues
To be added..
Terminology
To be added..
Stack
Last In First Out (LIFO)
Queues (FIFO)
First In First Out (FIFO)
Chapter 5 - Recursion
To be added..
Terminology
To be added..
Chapter 6 - Binary Trees
To be added..
Terminology
To be added..
Chapter 7 - Sorting and Searching Algorithms
To be added..
Terminology
To be added..
Chapter 8 - Hashing
Terminology
- Indexing- Perfect Hashing- Minimal Perfect Hashing- Hash Collision- Open Addressing- Closed Addressing- Design of Hash function
Introduction of Hashing
Hashing is generally [ Indexing ].
If you have learnt what [ index ] is, you may understand it as positioning or classifying objects with duplicated meaning for a smaller size of data and better searching.
Steps for Indexing1. Define an array with a specific purpose.2. Define meaning for each index in the array.3. Classify the input and determine the size of the array.4. Map the input to the array.
Example of Indexing (Minimal Perfect Hashing)Given A string [foo] = "abacbdef".\Precondition: there will only be alphabets inside the string.\If you want to find how many 'a' occured inside the string, you may use Indexing.1. Define an array for storing the occurrence of letters.2. Each index represents an alphebet.3. There are a total of 26 alphabets as potential input, so the size of array will be 26.4. Similar to the ASCII table, we can take index [0] representing the occurrence of 'a', index [1] representing the occurrence of 'b', and so on...5. Loop over the string and map the character to corresponding index.
However, there are still some differences between Hashing and Indexing.\In Hashing, we convert ASCII char to key directly with so that 'a' = 0, 'b' = 1, and so on...\which allows us to map the data easier and faster.
Hash function
A function f(k) is known as defined with specific formula,\it can be either One-to-one, or Many-to-one,\Under this property,\it can convert a large variable-sized amount of data into a small datum by transforming data into keys.
A Hash table arr[ ] is an array that will be created to hold the keys after conversion.
A Hash value is usually an integer that may serve as an index to an array.
Example of Hash function
Hashing Student ID k using Modulo, where h is the function, h(k) is the hash value of k, n is an arbitrary key.$$ h(k) = k \bmod n $$The size of the array will be reduced significantly due to the limited range of the modulus [0 to n-1].
Take k = 5000, n = 5, the function will be$$ h(k) = k \bmod 5 $$In Hash table, the value k will be updated to the index of hash value, arr[h(k)] = k$$ h(5000) = 5000 \bmod 5 = 0 $$arr[0] = 5000, arr[1] = 5081, arr[2] = 5072, arr[3] = 5023, arr[4] = 5014
You may now be thinking of what if the index collides, it should happen frequently as the function is many-to-one.
Yes, and therefore, I am going to introduce the solution against collision.
Hash Collision
Collision occurs when two distinct data own the same hash value.\Collisions are usually unavoidable when a large set of data is mapped into small datum.\It will increase the average cost of lookup operations.
Solutions to Hash Collision- Open Addressing- Closed Addressing
Load factor represents the length of data in each index,\larger load factor brings lower performance
Open Addressing
Place the key in other free slot when collisions occured.
An index only maps to 1 key.\Theoretical max load factor = 1
Advantages- No size overhead apart from the hash table array- Better memory locality and cache performance. Memory allocation is laid out linearly- Performs better when the number of keys is known in advance and the churn is low.
Example of Open Addressing:- Linear Probing- Quadratic Probing- Double Hashing- Hopscotch hashing- Robin Hood hashing- Cuckoo hashing- 2-Choice hashing
Linear Probing
To be added..
Quadratic Probing
To be added..
Double Hashing
To be added..
Closed Addressing
Place the key in the same slot even when collisions occured.
An index can map to multiple keys.\Theoretical max load factor = depends
To achieve placing multiple keys in same slot- Separate chaining using linked lists- Separate chaining using dynamic arrays- Using self-balancing binary search trees
Advantages- Easier removal- Assign quicker with high load factor- No issues with Clustering
Example of Closed Addressing:- Chaining Buckets
Chaining Buckets
To be added..
After dealing with collision, there will be two general types of Hashing.
Minimal Perfect Hashing (Best)A hash function that maps each valid input to a different hash value.\Every index is taken in the hash table.
Perfect HashingA hash funciton that maps n input keys to n consecutive hash values.\But not every index is taken in the hash table.
Designing Hash Functions
Ideal properties- Low Cost- Easier and faster to compute the result- Variable Range- Able to transform [words], [symbols] into [numbers]- Uniformity- Distribute the keys evenly- Minimize the chance of collisions
Common types of Hash Functions
1. Division
2. Mid-Square
3. Folding
4. Radix Transformation
Division
hashValue = key % tableSize\Try to use prime number as the hash table size to reduce collisions
For non integer keys, transform them into integer with ASCII code
Mid-Square
1. Transform keys into integer2. Sqaure the number3. Pick some digits from the middle to hash
Take tableSize = 5
|$\textnormal{key}$|$\textnormal{key}^2$|$\textnormal{new key}$|$\textnormal{hashValue}$||-|-|-|-||99 |9801 |80 | 80 % 5 = 0 ||145 |21025 |102| 102 % 5 = 2 ||342 |116964 |69 | 69 % 5 = 4 |
Folding
1. Split key into 3 parts [ Left, Middle, Right ] as you wish,\left and right should have the same size2. Fold keys and sum the keys
Shift-folding
Sum the splitted keys directly
Take tableSize = 5
|$\textnormal{key}$|$\textnormal{split}$|$\textnormal{new key}$|$\textnormal{hashValue}$||-|-|-|-||5829 |58-29 |58 + 29 = 87 | 87 % 5 = 2 ||452642 |45-26-42 |45 + 26 + 42 = 113 | 113 % 5 = 3 ||1234567|123-4-567 |123 + 4 + 567 = 694 | 694 % 5 = 4 |
Boundary-folding
Invert the left and right part of each splitted part except middle oneThen sum the keys
Take tableSize = 5|$\textnormal{key}$|$\textnormal{split}$|$\textnormal{new key}$|$\textnormal{hashValue}$||-|-|-|-||5829 |58-29 |85 + 92 = 177 | 177 % 5 = 2 ||452642 |45-26-42 |54 + 62 + 24 = 140 | 140 % 5 = 0 ||1234567|12-345-67 |21 + 345 + 76 = 442 | 442 % 5 = 2 |
Radix Transformation
Define same key with new radix then convert back to original radix
Given $ k = 358345{10} $\Define $ k2 = 358345{9} $\$ h(k) = k2 \space mod \space tableSize $\$ k2 = 358345{9} = 216068{10} $\$ h(k) = 216068{10} \space mod \space tableSize $
Useful shortcut
Convenient Mathematics formulas for programming
Gauss Summation
$$ \frac{n(n+1)}{2} $$
Calculate the sum of integers from 1 to n inclusively
$$ \frac{(a+b)(b-a+1)}{2} $$
Calculate the sum of natural numbers from a to b inclusively
To be added..
Data Communication & Networking
Networking is the part of computing that stays true the longest. Frameworks are replaced every few years; the fact that a packet is a bounded chunk of bytes travelling between two addresses, that it may be dropped, duplicated or delayed, and that everything above it is an attempt to hide those facts, has held since the 1970s and will outlive whatever runtime you are using this year. This post is a single self-contained pass over data communication and networking: the switching reality at the bottom, the layered abstractions built over it, the addressing and subnetting arithmetic you have to be able to do by hand, the transport and application protocols that carry the modern web, the delivery machinery that makes it fast at scale, and the diagnostic ladder that turns "the site is slow" into a specific, provable fault. Security is not a separate chapter here — firewalls, TLS and the common attack classes appear at the layer where each actually lives.
Where a cloud provider gives these concepts a branded name — a VPC, a security group, a NAT gateway — the mapping is pointed out, because a VPC is not a new idea: it is subnetting, routing tables and stateful firewalls with a control plane bolted on. The companion post AWS Course — 01 · Network First is the applied version of Chapters 3 and 4.
Learning Outcome
- Explain what a network is in switching terms, distinguish bandwidth, throughput, latency and jitter, and use the bandwidth-delay product to explain why it caps a single connection.- Map OSI's seven layers onto TCP/IP's four, walk one real packet through encapsulation header by header, and read an Ethernet frame — including what a switch learns and how ARP, VLANs and MTU interact.- Subnet IPv4 by hand: derive network address, broadcast, usable host range and host count from any prefix, and build a VLSM plan that does not overlap.- Explain NAT and its real costs, read an IPv6 address, describe SLAAC and dual stack, and defend why IPv6 adoption matters.- Describe how routing tables, longest-prefix match, OSPF and BGP move a packet across the internet — and how hijacks and route leaks break that.- Explain TCP's handshake, retransmission, flow control and congestion control, know when UDP is the better answer, and say what QUIC and TLS 1.3 fixed above it.- Trace one DNS name to its answer, compare HTTP/1.1, HTTP/2 and HTTP/3, and diagnose a broken or slow connection from layer 1 upward.
Chapter 1 — Fundamentals
Terminology
- Network — nodes plus links, arranged so any node can deliver bytes to any other, directly or via intermediaries.- Node — anything terminating or forwarding traffic: host, switch, router, firewall, load balancer.- Protocol — an agreed message format and set of rules; the contract that lets independently written programs interoperate.- Bandwidth — capacity of a link in bits per second. A property of the link, not of your transfer.- Throughput — the rate your transfer actually achieves. Always ≤ bandwidth, usually well below. Goodput counts only useful application bytes, excluding headers and retransmissions.- Latency — one-way delay. RTT is the there-and-back figure, which is what most tools measure.- Jitter — variation in latency between successive packets. Fatal for real-time media, irrelevant for file transfer.- Packet loss — the fraction of packets that never arrive. Networks are allowed to drop; reliability is built above.
Circuit switching vs packet switching
| | Circuit switching | Packet switching ||---|---|---|| Resource model | dedicated path held for the call's duration | statistical multiplexing, no reservation || Setup | required before data flows | none; the first packet just goes || Idle capacity | wasted — the circuit is held either way | reused by others || Delay | constant, predictable | variable; queues build under load || On failure | call drops, must be re-established | packets reroute around it || Example | analogue telephony, TDM leased lines | the internet, Ethernet, Wi-Fi |
The internet chose packet switching because data traffic is bursty: a browser idles for seconds, then wants everything at once, and reserving capacity for an idle conversation is waste. The price is that delay is no longer constant, congestion is possible, and every layer above must cope with loss and reordering. Essentially all of Chapter 5 exists to pay that price.
Bandwidth is not speed
These four terms are routinely conflated, and the conflation causes most bad network decisions.
A 1 Gbit/s link does not make a packet arrive sooner; it makes more packets fit per second. Bandwidth is a truck's capacity, latency is how long the drive takes. And latency has a floor you cannot buy past: light in fibre travels at roughly two-thirds of c, about 200,000 km/s, so London to New York (5,600 km) has a one-way minimum near 28 ms and an RTT floor near 56 ms. Real paths are not straight, so 70–80 ms is the production figure. No money reduces this; only moving the data closer does (Chapter 7). Throughput is the outcome, determined jointly by bandwidth, latency, loss, window sizes, the far end's capacity and every queue in between.
> Watch out: "the network is slow" almost never means bandwidth is exhausted. Far more often it is latency, loss driving retransmission, an undersized window, a DNS stall, or a slow server. Measure before upgrading a link.
Bandwidth-delay product
The BDP is how much data fits "in flight" on a path: . It matters because a reliable protocol can only have as much unacknowledged data outstanding as its window allows; if the window is smaller than the BDP, the sender stalls waiting for acknowledgements and the link runs empty.
Now the classic consequence. TCP's receive-window field is 16 bits, so without window scaling the maximum window is 65,535 bytes. On that 80 ms transatlantic path:
A 1 Gbit/s link delivering 6.5 Mbit/s per connection — a 150× shortfall — purely because of a header field sized in 1981. Window scaling (RFC 7323) is the fix and is default everywhere now, but the shape recurs constantly: on long paths the window, not the link, is the limit.
> Trick: when one transfer is slow over a long path but many parallel transfers saturate the link, the bottleneck is per-connection windowing or congestion control, not capacity. That is exactly why , download accelerators and multipart S3 uploads exist.
Why layers
Each layer solves one problem using only the service beneath it and offers one service above. The payoff is substitutability: HTTP does not know whether it runs over Ethernet, Wi-Fi or LTE. Each layer adds a header going down and strips it coming up — encapsulation, the subject of Chapter 2.
The cost is worth naming: layering hides information the layer above sometimes needs. TCP cannot tell wireless loss from congestion loss and slows down for both. HTTP/1.1 could not see it was sharing one connection. Most protocol progress of the last decade — QUIC especially — is layer boundaries being renegotiated because the old ones hid too much.
Chapter 2 — OSI and TCP/IP
Terminology
- PDU — the unit of data at a layer. Layer 2 calls it a frame, layer 3 a packet, TCP a segment, UDP a datagram.- Encapsulation — wrapping a higher layer's PDU as the payload of a lower one by prepending a header.- Trailer — metadata appended rather than prepended; Ethernet's frame check sequence is the example.- MTU — the largest payload one link carries in a single frame. MSS — the largest TCP payload that fits in one packet without fragmenting.
The two models
OSI defines seven layers; the model RFC 1122 actually describes defines four.
| OSI layer | # | TCP/IP layer | Runs here ||---|---|---|---|| Application | 7 | Application | HTTP, DNS, SMTP, SSH, gRPC || Presentation | 6 | Application | TLS (approximately), encodings, serialization || Session | 5 | Application | TLS resumption, RPC session state || Transport | 4 | Transport | TCP, UDP, QUIC (approximately), SCTP || Network | 3 | Internet | IPv4, IPv6, ICMP, IPsec, routing || Data link | 2 | Link | Ethernet, Wi-Fi, PPP, ARP, VLAN tags || Physical | 1 | Link | copper, fibre, radio, line coding |
One packet, encapsulated
A browser sending an HTTPS request over IPv4 and Ethernet, using documentation addresses from RFC 5737:
Two things cause real bugs. The destination MAC is the gateway's, not the server's — layer 2 addressing is hop-by-hop, layer 3 is end-to-end. IP addresses stay the same across the path (absent NAT); MAC addresses are rewritten at every router. This is the single most useful mental model in networking.
Header sizes determine the MSS. On a 1500-byte MTU: . With IPv6's fixed 40-byte header, . With the TCP timestamp option (common on Linux, 12 bytes padded), 1448. Over PPPoE at MTU 1492, 1452. Every VPN or overlay subtracts more.
OSI is a teaching tool; TCP/IP is what runs
OSI was a complete protocol suite that lost; what survived is its vocabulary. Seven layers are useful for talking ("that is a layer 7 load balancer") and misleading taken literally, because real protocols refuse to sit in one box. TLS runs over TCP, presents a byte stream, and does key exchange — it has no OSI home. QUIC is transport, session and security at once, in user space over UDP. MPLS is routinely called "layer 2.5" because it fits nowhere. VXLAN (RFC 7348) carries Ethernet inside UDP inside IP inside Ethernet, which the model forbids and every data centre does. ICMP rides inside IP but controls IP itself.
Use OSI numbers as shorthand; reason about the four TCP/IP layers when you need to be right.
Chapter 3 — Link layer
Terminology
- Frame — the link layer's PDU: header, payload, frame check sequence.- MAC address — a 48-bit link-layer identifier burned into or configured on a NIC.- Broadcast domain — the set of interfaces a broadcast frame reaches. One VLAN is one broadcast domain.- Trunk port — a switch port carrying multiple VLANs, distinguished by 802.1Q tags; an access port carries one, untagged.
The Ethernet frame
IEEE 802.3, in ubiquitous Ethernet II framing: preamble + SFD (7 + 1 bytes, not part of the frame proper), destination MAC (6), source MAC (6), EtherType (2 — IPv4, IPv6, ARP, 802.1Q), payload (46–1500), FCS (4, CRC-32; a failing frame is silently discarded), then a 12-byte interframe gap. The 46-byte payload minimum makes the smallest legal frame 64 bytes. The 1500-byte maximum is the origin of the MTU number everyone quotes.
MAC addresses
Six hex octets. The first 24 bits are the OUI, assigned to a vendor by the IEEE. Two flag bits live in octet 1: the I/G bit (least significant) is 0 for unicast, 1 for multicast, with as broadcast; the U/L bit (second least significant) is 1 for locally administered, which every virtual NIC, container veth and randomised phone MAC sets.
> Watch out: modern phones and laptops randomise their MAC per network by default as an anti-tracking measure. Any access control, DHCP reservation or licence check keyed on MAC address is now unreliable by design. Use 802.1X or certificates.
What a switch actually does
One table, three rules. A frame arrives on port 3 with source MAC , so the switch learns that MAC is reachable via port 3 (entries age out, typically after 300 s). It looks up the destination MAC: found means forward out that one port, not found means flood out every port except the arrival port. Broadcast and multicast are flooded within the VLAN.
Two consequences. Unknown-unicast flooding is normal, briefly — a quiet server whose entry aged out receives VLAN-wide flooded traffic until it replies once. And loops are catastrophic, because Ethernet has no TTL: a frame in a physical loop circulates forever and broadcasts multiply at every switch, saturating the segment in seconds. Spanning Tree (802.1D, and the faster RSTP 802.1w and MSTP 802.1s) exists solely to block redundant links so the active topology is loop-free.
ARP
To send an IP packet on the local link, a host needs the destination's MAC. ARP (RFC 826) supplies it:
ARP has no authentication whatsoever: any host on the segment can answer for any IP. That is ARP spoofing, and it turns a shared LAN into an on-path attack surface — the attacker becomes the gateway and sees all victim traffic. Mitigations are switch features, not host features: Dynamic ARP Inspection, DHCP snooping, port security, and 802.1X to authenticate devices before they get a port at all. IPv6 replaces ARP with Neighbor Discovery (RFC 4861) over ICMPv6, which has the same trust problem and the same class of switch-side defences (RA Guard, ND inspection).
VLANs
A VLAN partitions one physical fabric into independent broadcast domains. IEEE 802.1Q inserts a 4-byte tag after the source MAC: TPID (16 bits, ), PCP (3 bits, 802.1p priority), DEI (1 bit), and VID (12 bits, VLAN 1–4094; 0 and 4095 reserved). Traffic between VLANs must be routed — which is exactly where firewall policy gets applied, and why "put it in its own VLAN" is a security statement, not just a topology one.
> Common pitfall: the native VLAN on a trunk is carried untagged. If user traffic uses the native VLAN, a double-tagged frame can hop VLANs. Set the native VLAN to an unused ID and tag everything that matters.
The 12-bit VID caps a fabric at 4094 segments, which is why multi-tenant data centres moved to VXLAN and its 24-bit VNI — roughly 16 million segments, carried as Ethernet-in-UDP so it routes across an IP fabric.
MTU, and why 1500
1500 is the Ethernet payload maximum, and because Ethernet is everywhere it became the default assumption for the whole internet. Jumbo frames (typically 9000) cut per-packet overhead but require every device on the path to agree, so they are a data-centre feature, never an internet one. Tunnels shrink the usable MTU: PPPoE takes 8 bytes, and IPsec, WireGuard, GRE and VXLAN each take their own bite. An endpoint that ignores this produces the classic symptom — pings fine, DNS fine, small pages fine, large transfers hang forever.
Path MTU Discovery (RFC 1191) is meant to solve it: the sender sets the IPv4 Don't Fragment bit and a router that cannot forward returns ICMP "Fragmentation Needed" (type 3, code 4) naming the smaller MTU. A firewall that blindly drops all ICMP turns the path into a PMTUD black hole. IPv6 raises the stakes — routers must never fragment (RFC 8200), so the source depends entirely on ICMPv6 Packet Too Big.
> Trick: "small requests fine, large uploads hang" is an MTU problem until proven otherwise. It is the highest-yield guess in all of network troubleshooting.
Wi-Fi is not wireless Ethernet
IEEE 802.11 shares Ethernet's framing vocabulary and almost none of its behaviour.
| | Wired Ethernet | Wi-Fi ||---|---|---|| Medium | dedicated per port | shared radio, half duplex || Access method | switched, effectively collision-free | CSMA/CA with per-frame link-layer ACKs || Loss cause | rare; congestion or a bad cable | routine; interference, distance, contention || Rate | negotiated once | adapts per frame to signal quality || Joining | plug it in | authenticate, associate, encrypt (WPA2-CCMP or WPA3-SAE) || Extra problem | none | hidden nodes; RTS/CTS mitigates |
Two consequences. Wi-Fi loss is not congestion, but TCP cannot tell and slows down anyway — one reason wireless throughput collapses unhelpfully at the edge of coverage. And airtime is the real resource: a distant client transmitting at a low rate occupies the channel far longer per byte and degrades everyone. When Wi-Fi is "slow", look at signal, channel occupancy and client count before blaming the uplink.
Firewalling starts here too. A stateless filter judges each packet alone; a stateful filter tracks connections so return traffic for an allowed outbound flow is permitted automatically. That is exactly the AWS security group (stateful, per-interface) versus network ACL (stateless, per-subnet) split in AWS Course — 01 · Network First.
Chapter 4 — Network layer
Terminology
- Prefix / CIDR block — a range of addresses sharing a leading bit pattern, written . The subnet mask is the same idea as a dotted quad.- Network address — all-zeros host portion; names the subnet. Broadcast address — all-ones host portion (IPv4 only).- Default gateway — the next hop for any destination not on a directly connected subnet.- Autonomous System (AS) — a network under one routing policy, identified by an AS number.
IPv4 addressing and CIDR
Thirty-two bits in four decimal octets; the prefix length says how many leading bits identify the network.
Class A/B/C is dead; CIDR (RFC 4632) replaced it with arbitrary prefix lengths, which is what made aggregation and efficient allocation possible. Usable hosts is , subtracting network and broadcast — except , which RFC 3021 permits on point-to-point links with both addresses usable, and , a single host route.
| Prefix | /30 | /29 | /28 | /27 | /26 | /25 | /24 | /23 | /22 | /21 | /20 | /16 ||---|---|---|---|---|---|---|---|---|---|---|---|---|| Addresses | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1,024 | 2,048 | 4,096 | 65,536 || Usable | 2 | 6 | 14 | 30 | 62 | 126 | 254 | 510 | 1,022 | 2,046 | 4,094 | 65,534 || Last mask octet | 252 | 248 | 240 | 224 | 192 | 128 | 0 | — | — | — | — | — |
Subnetting, step by step
1. Convert the prefix to a mask and find the interesting octet — the one that is neither 255 nor 0.2. Compute the block size: .3. Boundaries in that octet are multiples of the block size, starting at 0.4. Network address = the boundary at or below the given address; octets to its right become 0.5. Broadcast = next boundary − 1; octets to its right become 255.6. Usable range = network + 1 through broadcast − 1. Hosts = .
Worked example 1 —
Verify by ANDing: 77 is , mask octet 192 is , AND gives = 64. Correct.
Worked example 2 —
Here the interesting octet is the third, which is where most people slip.
The subnet spans exactly eight /24s, through . When the interesting octet is the third, remember the fourth octet runs its full 0–255 range in every row.
Worked example 3 — VLSM allocation
Given (1,024 addresses, –), serve Engineering (500 hosts), Sales (200), Ops (100), Guest Wi-Fi (50) and two point-to-point router links. Round each up to a power of two, then allocate largest first so every block lands on its own natural boundary:
> Common pitfall: allocating smallest first produces blocks that are not aligned to their own size, which is illegal. A /23 must start on an even /24 boundary; a /26 must start at .0, .64, .128 or .192. If a block does not begin at a multiple of its size, the plan is wrong.
Summarisation is the reverse: through are contiguous and 8 is a multiple of 4, so they aggregate to . This is how the global routing table stays finite — providers announce aggregates, not the thousands of customer prefixes inside them.
Special and private ranges
| Range | Purpose | Reference ||---|---|---|| , , | private | RFC 1918 || | carrier-grade NAT shared space | RFC 6598 || | loopback | RFC 1122 || | link-local / APIPA | RFC 3927 || | multicast | RFC 5771 || , , | documentation only | RFC 5737 |
The full special-purpose registry is RFC 6890. Note in particular: it is –, not everything beginning — a classic firewall-rule bug.
NAT and what it costs
NAPT (also called PAT) lets many private hosts share one public IPv4 address; the router keeps a mapping table and rewrites addresses and ports both ways.
NAT bought the IPv4 internet two extra decades. The bill:
- End-to-end addressing is gone. Inbound connections require port forwarding, UPnP/NAT-PMP, or a rendezvous server.- Peer-to-peer becomes hard. Two NATed hosts cannot connect directly without hole punching — hence STUN, TURN, ICE, and most of WebRTC's machinery.- Protocols that embed addresses break. Active FTP and SIP carry IPs in their payloads, so the NAT must deep-inspect and rewrite them ("ALGs") — fragile, and a recurring source of bizarre bugs.- State is finite and mortal. Idle mappings are reclaimed, often within minutes for UDP; long-lived idle TCP connections die silently unless keepalives are shorter than the NAT's timeout.- CGNAT destroys the IP as identity. Thousands of subscribers share one address, so rate limiting, geolocation, abuse blocking and audit logging all become coarse and unfair — and ports run out, producing failures that look like packet loss.
A NAT is not a firewall, though it accidentally behaves like one inbound. Say what you mean and configure a stateful firewall explicitly. In cloud terms, a NAT gateway is precisely this device, and the reason private-subnet instances reach the internet but cannot be reached from it.
IPv6
128 bits as eight groups of four hex digits, with two compression rules (canonical form is RFC 5952): drop leading zeros in a group, and replace the single longest run of all-zero groups with , once.
| Prefix | Meaning ||---|---|| | global unicast — the routable internet || | link-local; every IPv6 interface has one, always || (in practice ) | unique local addresses, RFC 4193 — the rough analogue of RFC 1918 || | multicast ( all-nodes, all-routers) || , | loopback, unspecified || | documentation, RFC 3849 |
Structural differences that matter: no broadcast (multicast replaces it, removing a class of broadcast storms); the subnet is /64, effectively always, because SLAAC requires it — sites get a /48 or /56, giving 65,536 or 256 subnets, so IPv6 subnetting is about organising prefixes rather than conserving addresses; a fixed 40-byte header with options moved to extension headers, so routers do less work per packet; and routers never fragment (RFC 8200).
SLAAC
Stateless Address Autoconfiguration (RFC 4862) lets a host configure itself with no server:
The interface identifier was originally derived from the MAC via EUI-64, leaking a stable hardware identity onto every network you joined. Modern stacks default to temporary privacy addresses (RFC 8981) plus a stable-but-opaque per-network identifier (RFC 7217), so a host typically holds several IPv6 addresses at once. The RA's M flag means "also use DHCPv6 for addresses", O means "use DHCPv6 for DNS and other information"; DHCPv6 itself is RFC 8415.
Dual stack and why adoption matters
A dual-stack host prefers IPv6 when a AAAA resolves. Happy Eyeballs v2 (RFC 8305) makes that safe: start the IPv6 connection, give it a short head start, race IPv4 behind it — so a broken IPv6 path costs milliseconds rather than a timeout. On IPv6-only networks, NAT64 (RFC 6146) with DNS64 (RFC 6147) synthesises addresses for IPv4-only destinations and translates at the edge.
Adoption matters for economic reasons before technical ones. The IANA free pool exhausted in 2011 and addresses now trade on a secondary market at real cost. Networks without enough IPv4 deploy CGNAT, which is expensive to run, degrades the user experience, and destroys the address as a unit of accountability. Large mobile operators run IPv6-only cores with 464XLAT because it is simply cheaper. Meanwhile IPv6 restores the end-to-end model, quietly removing whole categories of workaround. The pragmatic position is not "IPv6 or IPv4" — it is dual stack now, IPv6-primary as soon as dependencies allow, and never designing anything new that assumes 32-bit addresses.
Routing
A routing table maps destination prefixes to next hops.
Longest-prefix match
When several entries match, the most specific wins — longest prefix, regardless of table order. Given , , and :
| Destination | Matches | Winner | Next hop ||---|---|---|---|| | /0, /8, /16, /24 | /24 | || | /0, /8, /16 | /16 | || | /0, /8 | /8 | || | /0 | /0 | |
This one rule explains most "why did my traffic go that way" mysteries, cloud ones included: a entry pointing at a NAT gateway never beats a more specific entry pointing at a VPC endpoint or peering connection.
Static vs dynamic
Static routes are configured by a human or by IaC, do not react to failure, and scale to a handful of entries — right for stub networks, cloud route tables and default routes. Dynamic routing is a protocol between routers that reconverges around failures and scales to a million prefixes — right for anything with redundant paths.
Interior: OSPF
OSPF (OSPFv2 is RFC 2328; OSPFv3 carries IPv6) is a link-state IGP. Every router floods link-state advertisements describing its own links, so every router builds an identical map of the area and independently runs Dijkstra over it, with cost derived from bandwidth. Large deployments split into areas joined by a backbone (area 0) so flooding and SPF computation stay bounded. Convergence is fast — sub-second with tuned timers — because everyone sees the same topology. IS-IS occupies the same slot in large carriers; EIGRP is Cisco's distance-vector alternative.
Exterior: BGP
BGP-4 (RFC 4271) is the protocol that makes the internet one network. It is path-vector, running between Autonomous Systems: each AS advertises which prefixes it can reach and the AS path to get there, and each applies its own policy to decide what to accept, prefer and re-advertise. Policy, not shortest path, is the point — best-path selection walks a fixed list:
Step 1 comes first for a reason: money. LOCALPREF is where "prefer settlement-free peering over paid transit" is expressed. The default-free zone currently holds on the order of a million IPv4 prefixes and keeps growing — check the CIDR Report for the live figure rather than trusting a number in a blog post.
Hijacks and route leaks
BGP was designed among mutually trusting operators and authenticates nothing about who may announce what.
- Prefix hijack — an AS announces a prefix it does not hold. Because a more specific announcement wins under longest-prefix match, announcing a /24 out of someone's /16 pulls their traffic globally. In 2008 Pakistan Telecom announced a more specific YouTube prefix intending a domestic block and removed YouTube from much of the internet for roughly two hours. In 2018 an announcement covering Amazon Route 53 address space redirected DNS for a cryptocurrency wallet and enabled real theft.- Route leak — an AS re-advertises routes learned from one peer or provider to another, violating the intended relationship. Usually misconfiguration rather than attack, it typically funnels a large share of internet traffic through a network far too small to carry it, producing global congestion. RFC 7908 classifies six distinct leak types.
Defences, none complete: RPKI ROAs record which AS may originate a prefix and Route Origin Validation (RFC 6811) lets routers drop RPKI-invalid announcements — this stops naive origin hijacks but not path forgery or most leaks; prefix filters and IRR data on customer sessions, with max-prefix limits to shut a session that suddenly announces 500,000 routes; and MANRS as the industry norms package. The honest summary: the routing layer is held together by filtering discipline and mutual reputation, incrementally reinforced by cryptography. Treat global reachability as best-effort.
Chapter 5 — Transport layer
Terminology
- Port — a 16-bit endpoint number within a host. well-known, registered, above that dynamic (Linux defaults to , see ).- Socket — one endpoint. A TCP connection is identified by the 4-tuple: source IP, source port, destination IP, destination port.- cwnd — congestion window: what the sender believes the network can absorb. rwnd — receive window: what the receiver says it can buffer.- RTO — retransmission timeout: how long to wait for an ACK before resending.
UDP vs TCP
| | UDP (RFC 768) | TCP (RFC 9293, originally RFC 793) ||---|---|---|| Connection | none | three-way handshake || Reliability | none — lost is lost | acknowledgement and retransmission || Ordering | none | strict byte-stream order || Flow / congestion control | none; the app must supply it | both, mandatory || Header | 8 bytes | 20 bytes minimum || Message boundaries | preserved | none; it is a byte stream || Good for | DNS, DHCP, real-time media, games, QUIC | HTTP, SSH, SMTP, databases, file transfer |
UDP is not "unreliable TCP"; it is the raw packet service with ports and a checksum. Choosing it means taking responsibility for whatever reliability you need — exactly the trade QUIC makes in order to implement better reliability than TCP can.
Handshake and teardown
The handshake costs one full RTT before any application byte moves — which is why connection reuse matters so much and why TLS 1.3 and QUIC work so hard to collapse round trips. Both sides pick a random Initial Sequence Number; randomising it is a security requirement, since predictable ISNs allow off-path connection spoofing.
A half-open connection consumes server state, so flooding SYNs from spoofed sources fills the accept queue — the classic SYN flood. SYN cookies are the standard defence: the server encodes the connection state into the ISN it returns and keeps no state until the client's ACK proves receipt ().
TIMEWAIT holds the closer for twice the maximum segment lifetime (60 s on Linux) so stray delayed segments cannot be mistaken for part of a new connection reusing the same 4-tuple.
> Common pitfall: thousands of sockets in on a busy client is normal and healthy, not a leak. Thousands in is a bug — the application received a FIN and never called .
Sequence numbers and retransmission
TCP numbers bytes, not packets. The ACK field carries the next byte expected, acknowledging everything before it cumulatively; SACK lets the receiver additionally report non-contiguous blocks it holds, so the sender resends only what is actually missing.
Loss is detected two ways. Fast retransmit treats three duplicate ACKs as a gap and resends immediately; modern Linux adds RACK-TLP (RFC 8985), which infers loss from transmit timestamps and probes the tail of a flight, greatly reducing costly timeouts. Timeout (RTO) is computed from a smoothed RTT estimate and its variance (RFC 6298): , initial value 1 second, exponential backoff on repeated failure. An RTO is expensive — it stalls the flow and resets the congestion window to its minimum.
Flow control
The receiver advertises rwnd in every ACK; the sender may never have more unacknowledged data outstanding than that. This protects a slow receiver from a fast sender — purely end-to-end, unrelated to network capacity. The field is 16 bits, capping the window at 65,535 bytes, which Chapter 1 showed is far below the BDP of any long fast path. The window scale option (RFC 7323) multiplies it by a negotiated power of two, up to a gigabyte. It is negotiated only in the SYN, so a middlebox that strips unknown TCP options from SYNs silently caps every connection through it at 6 Mbit/s on a transatlantic path.
Congestion control
Flow control protects the receiver; congestion control protects the network, whose capacity nobody advertises. The sender may have at most bytes in flight. The classic algorithm (RFC 5681):
- Slow start — begin small (10 segments is the common initial window) and double cwnd every RTT. Despite the name it is the aggressive phase; it is "slow" only relative to blasting at line rate immediately.- Congestion avoidance — past , switch to additive increase: roughly one MSS per RTT, linear.- On loss — multiplicative decrease. Reno halves cwnd on fast retransmit; a full timeout collapses it to the initial window.
This AIMD shape is why loss hurts far more on long paths: recovery is one segment per RTT, so an 80 ms path recovers eight times more slowly than a 10 ms one.
| | CUBIC | BBR ||---|---|---|| Signal | packet loss | measured bottleneck bandwidth and minimum RTT || Growth | cubic function of time since the last loss event | paced sending at the estimated delivery rate || On long fat paths | recovers far faster than Reno | short queues, tolerates non-congestive loss || Weakness | fills buffers, aggravating bufferbloat and latency | fairness against loss-based flows depends on version || Status | Linux default since 2.6.19; RFC 8312, updated by RFC 9438 | developed at Google, widely deployed, actively revised |
Only the sender's algorithm matters per direction, so a server operator can change this unilaterally. Measure before and after on your own paths — the honest answer to "is BBR faster" is "it depends on your RTT, your loss profile, and what you are competing with."
Head-of-line blocking
TCP delivers bytes in order. If segment 5 of 10 is lost, segments 6–10 sit in the receiver's buffer, already arrived and undeliverable, until the retransmission lands. For a single file that is correct. For HTTP/2, which multiplexes many independent streams over one TCP connection, it is a serious flaw: loss affecting one image stalls every other response on the connection. This is the single biggest reason HTTP/3 abandoned TCP.
Ports and sockets
A listening socket is ; an established connection is the full 4-tuple — which is why one server port serves hundreds of thousands of clients simultaneously, since each connection differs in the remote half. Conversely a client opening many connections to one destination is limited by its ephemeral port range for that destination, around 28,000 on default Linux settings, and the cause of "cannot assign requested address" under load testing.
Chapter 6 — Application layer
Terminology
- Resolver — the client-side component turning names into addresses. A stub resolver asks; a recursive resolver does the work.- Authoritative server — holds the real published data for a zone, a contiguous portion of the namespace under one administration.- TTL — how long a record may be cached, in seconds.- SNI — Server Name Indication: the hostname sent in the TLS handshake so a shared IP can select the right certificate.
DNS
DNS (RFC 1034, RFC 1035) is a distributed, hierarchical, aggressively cached database on UDP port 53, falling back to TCP port 53 for large responses, with EDNS(0) (RFC 6891) negotiating larger UDP payloads. A stub resolver knows almost nothing and expects a final answer; a recursive resolver (your ISP's, or ) does the walking and caches; an authoritative server answers only for its own zones and otherwise returns a referral one level down.
Resolving
Records worth knowing
/ are addresses. is an alias and cannot coexist with other records at the same name, so never at a zone apex. lists mail exchangers with preferences. carries SPF, DKIM, DMARC and ownership proofs. names a zone's authoritative servers, carries the serial, refresh/retry/expire timers and the negative-caching TTL (RFC 2308). is reverse lookup, gives host, port, priority and weight, restricts which CAs may issue. , , and / are DNSSEC material, and / deliver service parameters — ALPN, port, address hints — in one lookup.
TTL and caching
TTL is the contract that makes DNS scale and the trap that makes migrations painful. A record with may be cached for a day by every resolver worldwide and you cannot recall it. The discipline is non-negotiable: lower the TTL to 60–300 seconds at least one full old-TTL period before a planned change, make the change, verify, then raise it again. Negative answers are cached too, governed by the SOA minimum — which is why a typo'd record can look broken for a while after you fix it.
DNSSEC and encrypted transports
DNS answers are unauthenticated by default, which historically enabled cache poisoning: race a forged answer to a resolver and pollute it for the whole TTL. Source-port randomisation and query-name mixing (RFC 5452 and successors) raised the cost but authenticate nothing. DNSSEC (RFC 4033/4034/4035) signs record sets, publishes the public key as , and has the parent zone publish a hash of it — a chain of trust from the root down, letting a validating resolver prove an answer is genuine or that a name genuinely does not exist. It provides authenticity and integrity, not confidentiality, and its cost is operational: key rollovers and expired signatures fail closed.
| | Port | Spec | Note ||---|---|---|---|| DoT — DNS over TLS | 853 | RFC 7858 | dedicated port, so operators can see and police DNS || DoH — DNS over HTTPS | 443 | RFC 8484 | indistinguishable from web traffic; filters lose visibility || DoQ — DNS over QUIC | 853/UDP | RFC 9250 | lower handshake cost than DoT |
These encrypt the stub-to-resolver hop only. They hide nothing from the resolver itself, which makes "which resolver do you trust" a policy question as much as a technical one.
HTTP/1.1 → HTTP/2 → HTTP/3
| | HTTP/1.1 (RFC 9112) | HTTP/2 (RFC 9113) | HTTP/3 (RFC 9114) ||---|---|---|---|| Framing | text, one request at a time per connection | binary frames, multiplexed streams | binary frames over QUIC streams || Concurrency | 6 TCP connections per origin | many streams on one TCP connection | many streams on one QUIC connection || Header compression | none | HPACK (RFC 7541) | QPACK (RFC 9204) || Transport | TCP | TCP | QUIC over UDP || HOL blocking | per connection, request level | gone in HTTP, remains in TCP | gone at both levels || Encryption | optional | in practice mandatory | mandatory, built in |
HTTP/1.1's workaround for concurrency was six connections per origin, which drove the sprite sheets, domain sharding and file concatenation that dominated front-end practice for a decade. HTTP/2 made those anti-patterns — but only moved head-of-line blocking down a layer, where TCP still enforces in-order delivery. HTTP/3 completes the idea.
QUIC
QUIC (RFC 9000, TLS integration in RFC 9001, loss recovery in RFC 9002) is a transport built on UDP, in user space, with TLS 1.3 fused into it. Moving to UDP was not a preference for datagrams; it was the only way to deploy a new transport at all, because middleboxes everywhere inspect and mangle TCP and will not pass an unknown IP protocol number. UDP is the escape hatch, and user-space implementation lets the protocol evolve at application release cadence rather than kernel upgrade cadence.
What it fixes: no transport head-of-line blocking, since QUIC streams are independent and a lost packet stalls only its own stream; connection migration, because a QUIC connection is identified by a connection ID rather than the 4-tuple, so moving from Wi-Fi to cellular changes the IP but not the connection and the session survives with no reconnect and no lost upload; fewer round trips, with transport and cryptographic handshakes combined into 1-RTT for a new connection and 0-RTT on resumption; encryption by default including most of the transport header, so middleboxes cannot ossify it the way they ossified TCP; and unambiguous packet numbers that are never reused for retransmissions, removing TCP's retransmission ambiguity.
Costs, stated plainly: higher CPU per byte than kernel TCP (improving with offload), some networks block or throttle UDP, and 0-RTT data is replayable so it must carry only idempotent requests. Discovery is via the header or an DNS record — the client starts on TCP and upgrades.
TLS 1.3
TLS 1.3 (RFC 8446) is both faster and smaller than TLS 1.2 (RFC 5246), and both properties come from the same decision: delete the insecure options rather than negotiate them.
Changes from 1.2: 1-RTT instead of 2-RTT, because the client guesses the key-exchange group and sends its share in the first flight. Forward secrecy is mandatory — RSA key transport and static Diffie-Hellman are gone, so a future compromise of the server key cannot decrypt recorded sessions. The cipher suite list is short and AEAD-only; CBC modes, RC4, static RSA, compression, renegotiation and custom DH groups were all removed, and most TLS vulnerabilities of the 2010s targeted exactly those. More of the handshake is encrypted, including the certificate. 0-RTT resumption exists, with the same replay caveat as QUIC.
Certificates and chains of trust
An X.509 certificate (RFC 5280) binds a public key to identities. Validation checks, in order: the signature chain reaches a root in the client's trust store; every certificate is within its validity period; the requested hostname matches a Subject Alternative Name; key usage permits this use; and the certificate is not revoked.
| Symptom | Real cause ||---|---|| "certificate has expired" | expired leaf — or a client with a wrong system clock || works in , fails in a browser or JVM | the server omits the intermediate; may have it cached, others do not || "certificate name mismatch" | wrong SNI, or a SAN list missing the hostname || "unknown authority" inside a container | the image has no CA bundle installed || works for one vhost, not another | SNI not sent, so the server returned its default certificate |
Supporting machinery: CAA records restrict which CAs may issue for a domain; Certificate Transparency (RFC 6962, updated by RFC 9162) publishes every issued certificate to append-only logs so mis-issuance is detectable; ACME (RFC 8555) automates issuance and renewal, which matters more every year as certificate lifetimes shorten. Automate renewal or you will eventually have an outage caused by a calendar.
Chapter 7 — Delivery and scale
Terminology
- Reverse proxy — a server that accepts client connections and forwards them to backends on the client's behalf. The origin is the authoritative server behind all caches.- PoP — point of presence: a CDN's edge location.- Cache key — the request attributes identifying a cache entry: usually method, host, path and query, plus whatever names.- Anycast — announcing one IP address from many locations so routing delivers each client to a nearby one.
Load balancing: L4 vs L7
| | L4 (transport) | L7 (application) ||---|---|---|| Decides on | IP addresses and ports | URL path, headers, cookies, method, host || Sees payload | no | yes || TLS | passes through | usually terminates || Per-connection cost | very low | higher; it parses HTTP || Can do | connection distribution, non-HTTP protocols | path routing, header rewriting, retries, canaries, rate limits, WAF || AWS equivalent | Network Load Balancer | Application Load Balancer |
A TCP connection handled at L4 pins to one backend for its whole life. At L7 each request can go somewhere different, which is what makes canary releases and per-endpoint routing possible.
| Algorithm | Behaviour | Use when ||---|---|---|| Round robin | strict rotation | backends identical, requests uniform || Weighted round robin | rotation with capacity weights | heterogeneous instance sizes || Least connections | fewest active connections wins | request durations vary widely || Least response time | combines connections and latency | backend performance is uneven || Source-IP hash | same client → same backend | crude affinity without cookies || Consistent hashing | a key maps to a backend; adding one moves 1/N of keys | caches and sharded stores || Power of two choices | sample two at random, pick the less loaded | large fleets; near least-connections quality, far less state |
> Trick: plain round robin plus a slow endpoint equals a queue on every backend. Least-connections is the safer default whenever request cost is not uniform, because it naturally routes away from anything that has become slow.
Health checks and affinity
Active checks probe each backend on an interval — cheap, predictable, the standard. Passive checks observe real traffic and eject a backend after N consecutive errors — faster to react, but needs traffic to learn. A TCP connect proves the process is listening; an HTTP that touches the database proves it can actually serve.
Design the endpoint carefully. A deep check that fails when a shared dependency degrades marks every backend unhealthy at once and takes the service fully down — a self-inflicted outage worse than degraded service. The usual compromise is a shallow liveness check deciding restarts and a deeper readiness check deciding traffic, with a floor guaranteeing the balancer never removes the last healthy backends.
Session affinity pins a client to one backend via a balancer-set cookie or a source-IP hash. It is a workaround for server-side state and it costs real properties: uneven load, lost sessions when a backend dies, and much harder deploys. Prefer stateless backends with session state in a shared store; use affinity only where an in-memory cache or a stateful long-lived connection genuinely requires it.
Reverse proxies, CDNs, anycast
A reverse proxy (nginx, HAProxy, Envoy, Caddy) is the load balancer's more general sibling, typically also handling TLS termination, HTTP version translation (HTTP/3 to the client, HTTP/1.1 to a legacy backend), compression, buffering, timeouts, retries, circuit breaking and access control. Concentrating these in one tier means applications do not reimplement them per service.
> Watch out: behind a proxy the backend sees the proxy's address as the client. Propagate the real one with / (RFC 7239) — and trust it only from known proxy addresses. A blindly trusted is a client-controlled header, and it will be used to bypass your IP allowlists and rate limits.
A CDN is a global fleet of reverse-proxy caches. A client resolves your hostname to a nearby PoP, which serves from cache or fetches from the origin, often via an origin shield that collapses many PoPs' misses into one origin request. You gain latency (bytes start closer), origin offload (the origin serves misses only), and DDoS absorption (the attack lands on distributed edge capacity). You must manage invalidation and cache-key correctness — anything cached wrongly is now wrong in hundreds of places at once.
Anycast announces the same prefix from many locations and lets BGP deliver each client to the routing-closest instance. It is how the DNS root servers, public resolvers and every CDN's edge addresses work: no DNS TTL delay when steering traffic, automatic failover when a site withdraws its announcement, and DDoS split across sites by the routing system itself. The limits: "closest" means shortest AS path, not lowest latency, and a route change mid-connection can move a client to a different site and break a long-lived TCP connection. That last problem is exactly what QUIC's connection migration is designed to survive, which is one reason CDNs adopted HTTP/3 early.
Cache-Control decides whether any of this helps
A CDN can only cache what you tell it to. Caching semantics are RFC 9111.
| Directive | Effect ||---|---|| | any cache may reuse for N seconds || | overrides for shared caches (CDN, proxy) only || / | shared caches may store / browser only || | may store, but must revalidate before every reuse || | must not be written to any cache at all || | once stale, never serve without revalidating || | do not revalidate within the freshness window, even on reload || | serve stale for N seconds while refreshing in the background (RFC 5861) || | serve stale for N seconds if the origin is failing (RFC 5861) |
Validators refresh cheaply: with , or with , producing a with no body. names request headers forming part of the cache key — is correct and necessary, fragments the cache into near-uselessness, disables it.
> Common pitfall: does not mean "do not cache" — it means "revalidate before reuse". The directive that means store nothing is . Confusing them either leaks private data into shared caches or throws away all the benefit of validation.
Chapter 8 — Practical diagnosis
What each tool actually proves
| Tool | Proves | Does not prove ||---|---|---|| | ICMP echo reached the host and returned; RTT and loss | that any service is up; ICMP is often deprioritised or blocked, so loss here may be fictional || | the forward path, via expiring TTL and ICMP Time Exceeded | the return path, which may differ entirely; nor real per-hop latency || | sustained per-hop loss and latency over time | that middle-hop loss is real — routers rate-limit ICMP generation; only loss at the final hop counts || | what DNS answers, from a chosen server, with TTLs | what your application resolves — that depends on its own cache and config || | the same, and it ships on Windows by default | as much detail as ; prefer where available || / | which local sockets exist, in which state, owned by which process | anything about the remote end || | a TCP connection to that port completed | that the service speaks the protocol you expect || | the full HTTP transaction with a timing breakdown | client-side rendering behaviour || | the chain, protocol version and cipher actually negotiated | whether your client's trust store accepts it || | exactly which packets crossed this interface | anything about packets dropped before this interface || | which routing entry the kernel will use | that the next hop is reachable || | achievable throughput between two hosts you control | anything about a third party's capacity |
Two rules govern all of them. Symmetry is not guaranteed — forward and return paths may differ, so a one-way problem is normal and traceroute shows one direction only. And ICMP is a second-class citizen — routers generate it at low priority and rate-limit it, so intermediate-hop loss in is usually an artefact.
The troubleshooting ladder
Work upward; each rung assumes the ones below passed. Stopping at the first failure is the entire technique, and most wasted debugging time comes from starting at layer 7.
1 — Physical and link. (is it UP with carrier?), , for Wi-Fi signal and rate. Down or no carrier means cable, port, driver or radio, and nothing above can work.
2 — Layer 2 neighbours. . A gateway stuck means ARP is not being answered: wrong VLAN, wrong subnet mask, port security, or the gateway is genuinely down.
3 — Layer 3 addressing and routing.
The critical split: if works but names fail, it is DNS — skip to rung 4. If it fails, stay at layer 3.
4 — DNS.
Different answers from different resolvers means propagation delay after a change, split-horizon DNS, or a stale/poisoned cache. Compare the TTLs.
5 — Layer 4 reachability. , . Read the failure mode, because it names the cause:
| Result | Means ||---|---|| Connection refused (RST) | reached the host; nothing is listening on that port || Connection timed out | SYN silently dropped: firewall, security group, or a black-holed route || Connects then hangs | reached the service and it is not responding — or an MTU black hole |
6 — TLS. , and check , since clock skew invalidates every certificate check. Verify expiry, SAN list, chain completeness and negotiated version.
7 — Application.
This one command decomposes "slow" into a layer:
| Dominant figure | Diagnosis ||---|---|| | resolver latency, cold cache, or a failing name server || − | network RTT and TCP handshake — a distance or path problem || − | handshake cost — check for TLS 1.2, missing resumption, an oversized chain || − | the server is slow. The network has done its job; go look at the application || − | transfer time — bandwidth, window sizing, or an uncompressed response |
8 — When it is "slow" rather than "broken".
is the underused one. It reports each connection's , and directly, turning Chapter 5's congestion-control discussion into observable numbers: a low with a climbing count is loss-induced throughput collapse, not a bandwidth shortage. Capture packets only once the ladder has narrowed the problem — a capture without a hypothesis is a haystack:
Practice Exercises
Exercise 1 — Subnet arithmetic by hand
For each, give the network address, broadcast, usable host range and usable host count. No calculators.· · ·
<details><summary>Solution</summary>
</details>
Exercise 2 — Design a VLSM plan
From , allocate non-overlapping blocks for 1,000 workstations, 400 VoIP phones, 200 servers, 60 printers, 25 cameras and four point-to-point router links. Leave the remainder contiguous.
<details><summary>Solution</summary>
</details>
Exercise 3 — Longest-prefix match
Given , , , , , name the next hop for , , , and .
<details><summary>Solution</summary>
</details>
Exercise 4 — Bandwidth-delay product
A 10 Gbit/s path has an RTT of 120 ms. (a) What is the BDP in bytes? (b) What window is needed to fill it? (c) What is the maximum single-connection throughput without window scaling?
<details><summary>Solution</summary>
</details>
Exercise 5 — Read a DNS delegation
Run . For each stage record which server was asked, whether the response was a referral or an answer, and the TTL on the final record. Run it again immediately against your system resolver and explain why the TTL is now lower.
Exercise 6 — Prove the failure mode
On a host you control, produce each outcome deliberately and record what and report: (1) connection refused, with nothing listening; (2) connection timed out, by adding then removing a firewall rule; (3) a TLS certificate name mismatch, by connecting via or requesting a hostname the certificate does not cover.
Exercise 7 — Decompose a slow page
Run the timing block from Chapter 8 ten times against a site hosted far from you, and record which component dominates. Then run it against a CDN-fronted asset on the same site and explain the difference in terms of Chapters 1 and 7.
<details><summary>Solution</summary>
</details>
Cheat-sheet
| What | How ||------|-----|| Usable hosts in a prefix | || Block size in the interesting octet | || Network address | round the address down to the block boundary || Broadcast address | next boundary − 1; octets to the right become 255 || Bandwidth-delay product | ; ÷ 8 for bytes || MSS on a 1500 MTU | (IPv4 + TCP), (IPv6 + TCP) || RFC 1918 private ranges | , (– only), || CGNAT shared space | || Route selection rule | longest prefix match wins; table order is irrelevant || BGP first tiebreaker | highest — policy before path length || Origin-hijack defence | RPKI ROAs plus Route Origin Validation (RFC 6811) || TCP connection identity | the 4-tuple: src IP, src port, dst IP, dst port || vs | is normal; many means the app never called || Lower a DNS TTL before a migration | at least one full old-TTL period in advance || vs | revalidate before reuse vs never store at all; fingerprinted assets get || Test path MTU | (1472 + 8 + 20 = 1500) || Is it DNS? | works but names fail → yes, it is DNS || Refused vs timeout | RST = nothing listening; timeout = firewall dropping || Decompose "slow" | timing block: dns / connect / tls / ttfb / total || Per-socket truth | for live , and || Read correctly | only loss at the final hop is real |
Where to go deeper
- Apply Chapters 3 and 4 in a cloud — AWS Course — 01 · Network First is this material with a control plane: VPC CIDRs are RFC 1918 planning, subnets are the subnetting arithmetic above, route tables are longest-prefix match, security groups are stateful firewalls, NACLs are stateless ones, and NAT gateways are Chapter 4's NAT.- Build a lab. Three Linux network namespaces joined by veth pairs, plus and , teach more in an afternoon than any diagram. Add FRRouting to run real OSPF and BGP between them.- Read one capture properly. Load a single HTTPS page load into Wireshark and account for every packet: handshake, TLS, HTTP/2 frames, ACK pattern, FIN. Doing this once changes how you read everything else.- Follow the specs. RFC 9293 (TCP), RFC 9000 (QUIC), RFC 8446 (TLS 1.3) and RFC 9110/9111 (HTTP semantics and caching) are unusually readable modern documents.- Watch routing live. RIPE RIS and RouteViews publish real BGP data; RIPE Atlas lets you run measurements from thousands of vantage points for free.
References
- RFC 1122 — Requirements for Internet Hosts: Communication Layers- RFC 1918 — Address Allocation for Private Internets- RFC 4632 — CIDR: Address Assignment and Aggregation Plan- RFC 1191 — Path MTU Discovery- RFC 8200 — Internet Protocol, Version 6 (IPv6) Specification- RFC 4291 — IPv6 Addressing Architecture · RFC 4862 — IPv6 SLAAC- RFC 2328 — OSPF Version 2- RFC 4271 — A Border Gateway Protocol 4 (BGP-4)- RFC 6811 — BGP Prefix Origin Validation- RFC 7908 — Problem Definition and Classification of BGP Route Leaks- RFC 9293 — Transmission Control Protocol (TCP)- RFC 5681 — TCP Congestion Control · RFC 9438 — CUBIC · RFC 6298 — TCP's Retransmission Timer- RFC 7323 — TCP Extensions for High Performance- RFC 1035 — Domain Names: Implementation and Specification- RFC 4033 — DNS Security Introduction and Requirements- RFC 8484 — DNS over HTTPS · RFC 7858 — DNS over TLS- RFC 9110 / 9111 / 9112 — HTTP Semantics, Caching, HTTP/1.1 · RFC 9113 — HTTP/2 · RFC 9114 — HTTP/3- RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport- RFC 8446 — TLS 1.3 · RFC 5280 — X.509 Certificate and CRL Profile · RFC 8555 — ACME- IEEE 802 standards- RIPE NCC — RIPE Atlas- Kurose & Ross, Computer Networking: A Top-Down Approach.- Stevens, Fall & Wright, TCP/IP Illustrated, Volumes 1 and 2.
Planned future extensions: topics that deserve their own posts rather than another section here.
- Subnetting drills — a generated worksheet of 50 problems with answers, plus the binary-AND method written out for people who prefer it to block sizes.- BGP in a lab — FRRouting across network namespaces: eBGP sessions, AS paths, LOCALPREF policy, deliberate route leaks, and RPKI validation with a local validator.- Wireshark, one capture at a time — annotated walkthroughs of a TLS 1.3 handshake, an HTTP/2 multiplexed page load, and a QUIC connection migration.- Kubernetes networking — the CNI model, Services, kube-proxy versus eBPF datapaths, Ingress and Gateway API, and where these fundamentals reappear under new names.- Network security in depth — DDoS classes and mitigation, WAFs, zero trust and mTLS between services, IPsec and WireGuard, and 802.1X on the wired edge.- Real-time media — WebRTC, jitter buffers, RTP/RTCP, adaptive bitrate, and why the metrics that matter for a video call are the opposite of those for a file transfer.


![Java Development [Basic] Part 1 — Language, OOP, Exceptions, I/O, Threads](/blog/assets/java.jpg)







