DrillLab
八股题库Question bank

105 道问答题,一道一卡105 questions, one card each

默认只显示问题 —— 先自己在心里答一遍,再展开对答案。答不上来就标「不会」,下次抽认卡会先抽它。Only the question shows by default. Answer it in your head first, then open the answer. Mark the ones you miss; the flashcard round puts those first.

0 / 105道自评过self-assessed
0Got it0模糊Shaky0不会No idea105还没做Not seen
正在读这台浏览器里的标记…Reading your marks from this browser…
标记不是打分,是给下一轮排队Marks are a queue, not a score

标「不会」的题会排到抽认卡最前面,标「会」的进低频池排最后。所以别客气 —— 觉得答得磕磕巴巴就标「模糊」。准备好了就去抽认卡“No idea” jumps to the front of the next round; “got it” drops to the back. So be honest — if it came out shaky, mark it shaky. Then go run a flashcard round.

题目Questions

筛出 2 道(共 105 道)。2 of 105 questions.
数据库Databases#317

关系型数据库 vs 非关系型数据库

Relational database vs Non-relational database

看答案Show answer

一句话:关系型先定好表结构、用 JOIN 关联、 强调一致性; 非关系型结构灵活、 按查询模式组织数据、 强调扩展性

关系型(MySQL、PostgreSQL)非关系型(MongoDB、Redis)
结构表 + 行 + 列,schema 固定文档 / 键值 / 图,schema 灵活
关联JOIN嵌套文档,或应用层自己拼
事务ACID 是强项有但较弱(MongoDB 4.0+ 支持多文档事务)
扩展纵向为主(加配置),分库分表麻烦横向为主(加机器)
适合数据关系复杂、要强一致—— 订单、账务、库存结构多变、读多写多、 单次查询取一整块—— 日志、内容、会话、缓存

选型的正确说法:「看数据形状和访问模式」——

  • 一次查询要取的东西总是在一起(一篇文章连着它的所有段落)→ 文档型合适。
  • 同一份数据要从很多角度关联查(用户 × 订单 × 商品 × 优惠券)→ 关系型合适,因为文档型要么冗余存多份、要么在应用层做 JOIN
  • 需要转账那样的强一致 → 关系型。

会追问:「MongoDB 没有 schema 是优点吗?」——是双刃剑。 前期迭代快,但约束跑到了应用层, 时间长了同一个集合里会存在好几代不同形状的文档。 所以实践中一般还是用 Mongoose 这类工具在应用层加回 schema
「现在还有清楚的界限吗?」—— 在模糊:PostgreSQL 的jsonb 让它能存文档并建索引, 所以「先上 Postgres, 需要文档就用 jsonb」是很常见的现实选择。

In one line: relational means you define the schema up front, relate rows with JOINs, and lean on consistency; non-relational means a flexible shape, data laid out for the queries you actually run, and easier scale-out.

Relational (MySQL, PostgreSQL)Non-relational (MongoDB, Redis)
ShapeTables, rows, columns — fixed schemaDocuments / key-value / graph — flexible schema
Relating dataJOINNested documents, or you stitch it in the app
TransactionsACID is the whole pointPresent but weaker (MongoDB 4.0+ has multi-document)
ScalingMostly vertical; sharding is painfulMostly horizontal — add machines
Good forComplex relationships and strong consistency — orders, ledgers, inventoryShifting shapes, heavy read and write, one query pulling a whole blob — logs, content, sessions, caches

The right way to talk about choosing: “Look at the shape of the data and the access pattern.”

  • Everything one query needs always travels together (an article and all its paragraphs) → document store fits.
  • The same data gets related from many angles (users × orders × products × coupons) → relational fits, because a document store either duplicates it or makes you JOIN in application code.
  • You need transfer-money-level consistency → relational.

Follow-up: “Is MongoDB being schema-less an advantage?” — it cuts both ways. You move faster early on, but the constraints move into your application code, and given enough time one collection holds three generations of document shapes. Which is why teams reach for something like Mongoose to put a schema back on top.
“Is the line still clear today?” — it is blurring. PostgreSQL’s jsonb stores documents and indexes them, so “start on Postgres, use jsonb where you need a document” is a very common real-world answer.

数据库Databases#318

主键 vs 外键

Primary key vs Foreign key

看答案Show answer

一句话:主键唯一标识本表的一行外键指向另一张表的主键, 用来表达关联并保证引用有效。

主键(Primary Key)外键(Foreign Key)
作用唯一标识一行指向另一表的主键
唯一性必须唯一可以重复(一个用户多个订单)
能否为 NULL不能可以(表示「暂时没关联」)
每表几个一个(可以是多列组成的复合主键)多个
索引自动建不一定自动建—— MySQL 会,PostgreSQL 不会

「外键索引」那一条是加分点: PostgreSQL 里外键列不会自动建索引, 而 JOIN 和级联删除都要用到它 ——忘了手动建索引是很常见的性能问题

外键的核心价值是引用完整性: 数据库拒绝你插入一条 指向不存在用户的订单, 也拒绝你删掉还有订单的用户。这是数据库帮你兜住的一致性, 不用在应用层写检查。

会追问删除行为—— 这个一定要会:

  • RESTRICT /NO ACTION——有引用就不许删(默认,最安全)
  • CASCADE——连着子记录一起删(很方便也很危险, 删一个用户可能连带删掉几万条记录)
  • SET NULL—— 把子记录的外键置空 (适合「作者被删了,文章保留为匿名」)

还会追问:「主键用自增 id 还是 UUID?」—— 自增:短、索引局部性好、 但暴露数据量、分库时会冲突。 UUID:全局唯一、 适合分布式和前端预生成, 但更长、随机写入对 B+ 树索引不友好折中是 ULID / UUIDv7(带时间前缀,有序)—— 这个答出来会显得很专业。

In one line: a primary key uniquely identifies a row in its own table; a foreign key points at another table’s primary key, expressing the relationship and keeping the reference valid.

Primary keyForeign key
JobIdentifies one rowPoints at another table’s primary key
Unique?Must beCan repeat (one user, many orders)
Nullable?NoYes — meaning “not linked yet”
How many per tableOne (possibly composite, several columns)Many
IndexCreated for youNot always — MySQL does, PostgreSQL does not

That last row is the bonus point. In PostgreSQL a foreign key column gets no index automatically, and both JOINs and cascading deletes need one — forgetting to add it by hand is a very common performance bug.

The real value of a foreign key is referential integrity: the database refuses to insert an order pointing at a user who does not exist, and refuses to delete a user who still has orders. That is consistency the database holds for you, so you do not write the check in application code.

They will ask about delete behaviour — know these three:

  • RESTRICT / NO ACTION refuse the delete while references exist (the default, and the safest)
  • CASCADE delete the children along with it (convenient and dangerous; deleting one user can take tens of thousands of rows with it)
  • SET NULL — null out the child’s foreign key (fits “the author is gone, keep the article as anonymous”)

Another follow-up: “Auto-increment id or UUID?” — auto-increment is short, gives good index locality, but leaks how much data you have and collides when you shard. UUID is globally unique, good for distributed systems and for generating ids on the client, but longer, and random inserts are unkind to a B+ tree index. The middle ground is ULID or UUIDv7 — time-prefixed, so they sort — and saying that makes you sound like you have done this before.

Text建表时的三个要点示意Illustrative
1CREATE TABLE users (
2 id BIGSERIAL PRIMARY KEY, -- 主键:唯一、非空、自动建索引
3 email TEXT UNIQUE NOT NULL -- 唯一约束 ≠ 主键
4);
5
6CREATE TABLE orders (
7 id BIGSERIAL PRIMARY KEY,
8 user_id BIGINT NOT NULL
9 REFERENCES users(id)
10 ON DELETE RESTRICT, -- 还有订单就不许删用户
11 total NUMERIC(10,2) NOT NULL
12);
13
14-- PostgreSQL 不会自动给外键列建索引,JOIN 会慢
15CREATE INDEX idx_orders_user_id ON orders(user_id);
1CREATE TABLE users (
2 id BIGSERIAL PRIMARY KEY, -- primary key: unique, not null, indexed automatically
3 email TEXT UNIQUE NOT NULL -- a unique constraint is not the same as a primary key
4);
5
6CREATE TABLE orders (
7 id BIGSERIAL PRIMARY KEY,
8 user_id BIGINT NOT NULL
9 REFERENCES users(id)
10 ON DELETE RESTRICT, -- a user with orders left cannot be deleted
11 total NUMERIC(10,2) NOT NULL
12);
13
14-- PostgreSQL does not index a foreign key column for you, and the JOIN gets slow
15CREATE INDEX idx_orders_user_id ON orders(user_id);

这些题从哪来Where these come from

99 道来自面试题库 #269–#387;TypeScript 深度那 6 道是 DrillLab 自出的(senior 补强,卡片上有标注)。答案都是 DrillLab 写的,所以讲解里的代码块一律标「示意」。每道题都能点回它出处的那一节课。99 questions come from the interview bank (#269–#387); the 6 TypeScript deep-dive ones are DrillLab-made (marked on the card). All answers are written by DrillLab, so every code block here is labelled “demo”. Each card links back to the lesson it came from.