In a bloom filter, what does a 'yes' answer guarantee and what does a 'no' answer guarantee?
answer
- one answer is trustworthy, one is not
- what can the structure never get wrong
- an item never added may still match
- asymmetric: definitely absent vs maybe present
basics
~20 sA bloom filter's 'no' is certain: that item was never added. Its 'yes' means only 'probably present' — a fraction of queries for items that were never added still come back positive. Negatives are facts, positives are hints.
solid answer
~50 sThe error is one-sided. A negative is exact: if the filter says no, the item was definitely never inserted, so you can skip the expensive lookup with confidence. A positive is probabilistic: the item is *probably* present, but some share of never-inserted items also test positive, and that share is a number you choose when you size the structure. The reason for the asymmetry is that insertion only ever sets bits and nothing clears them, so anything inserted must still test positive — while bits set by *other* insertions can accidentally cover every position a stranger checks. The practical consequence is a design rule: a positive must route to an authoritative check, never to an irreversible action. A service that locks accounts purely on a filter hit will eventually lock someone who was never on the list.
go deeper
Be ready to state both guarantees in one breath: a negative means the element was definitely never added, a positive means it is probably there. Say the word 'probably' out loud — that word is what the interviewer is listening for.
Explain where the one-sided error comes from: insertion only sets bits and nothing clears them, so anything added must test positive, while bits set by other elements can conspire to make a stranger test positive too.
Show how you design around the asymmetry: a positive routes to an authoritative check, and you size the error rate against the cost of that check. Name the workloads where no cheap confirmation exists, because those are the ones where the structure does not belong.
Own the question of who absorbs a wrong answer. A one-sided error is acceptable only when the positive path is confirmable and reversible; argue that constraint before you argue the memory savings, and set the error target from the fallback's real cost.
## The structure in one paragraph A bloom filter is a fixed array of `m` bits, all zero to begin with, plus `k` independent hash functions that map an element to `k` positions in that array. To add an element you compute its `k` positions and set those bits to 1. To test an element you compute the same `k` positions and look at those bits. That is the entire structure. Notice what is missing: the elements themselves are never written down anywhere. The filter holds bits, not keys, which is exactly why it can represent an enormous set in a few megabytes — and exactly why its answers cannot both be exact. ## Why a negative is a fact Suppose an element `x` was inserted at some point. Insertion set all `k` of its bits to 1, and in the standard form of the structure nothing ever resets a bit to 0. So every one of `x`'s positions is still 1 today, and a query for `x` cannot possibly find a zero. Contrapositive: if a query finds even one zero bit, `x` was never inserted. That is a proof, not a probability. This is what people mean by *no false negatives*, and it is the guarantee the whole design rests on — the entire value of putting a filter in front of an expensive lookup is that the negatives let you skip work with no risk of skipping something real. ## Why a positive is only a hint Now suppose `y` was never inserted. Its `k` positions were chosen by the hash functions without regard to what else is in the filter, and every other element you inserted has been setting bits all over the array. If it happens that all `k` of `y`'s positions were already set — possibly each by a different, unrelated element — the query finds no zero and reports 'maybe present'. That is a *false positive*. It does not mean the structure malfunctioned; it is the advertised behaviour, and its rate is a design input you buy with bits. Two consequences follow immediately. First, the false-positive rate is not fixed for all time: it climbs as you insert more elements, because a fuller array makes accidental coverage likelier. A filter sized for ten million entries and loaded with forty million will answer positive far more often than its design promised, silently. Second, the rate is a property of the filter, not of the query: repeating the same query gives the same answer forever, so a false positive for a particular element is permanent until the filter is rebuilt. ## The failure mode this question is really about The common wrong answer is to treat a hit as a fact. Imagine a login service that keeps a filter of accounts flagged for a forced password reset and blocks any account that tests positive. Every flagged account is caught — the no-false-negative guarantee delivers that. But a small percentage of ordinary accounts, never flagged, will also test positive and be blocked, and no amount of retrying will clear it, because the filter's answer for that username never changes. The correct shape is: negative means proceed, positive means *go ask the authoritative source*. The filter's job is to remove the vast majority of pointless authoritative lookups, not to answer the question itself. If there is no cheap authoritative source to ask, a bloom filter is the wrong structure for that decision. ## What the structure cannot do at all Because it stores bits and not elements, a bloom filter cannot enumerate its contents, cannot return a stored value alongside a key, and cannot tell you how many distinct elements it holds. You cannot ask it 'what is in here?' — only 'was this particular thing possibly added?'. In the standard form you also cannot remove an element, because bits are shared and clearing one may destroy another element's evidence, breaking the very no-false-negative guarantee that makes the structure useful. ## Where the tradeoff pays An exact set must store the keys, so its memory grows with both the number of elements and their length; a bloom filter's cost is a fixed number of bits per element regardless of whether the element is a six-character token or a two-hundred-character address. That is the whole bargain: give up exactness in one direction, and in exchange the memory bill stops caring how big your elements are. Everything else about using the structure well follows from being precise about which direction you gave up.
- Why can a bloom filter never produce a false negative?Because insertion only sets bits and, in the standard form, nothing ever clears one. If an element was added, all of the positions it checks were set to 1 at that moment and are still 1, so a query for it cannot find a zero. Finding a zero is therefore proof the element was never added.
- If a positive is only probable, what do you actually do with one?Treat it as 'now go ask the authoritative source'. The filter's value is that it removes most of the pointless authoritative lookups, so a hit should route into a cheap confirmation path — a disk read, a service call, a database probe. If no such confirmation path exists, the filter should not be making that decision.
- Can you list what a bloom filter contains, or count its elements?No. It stores bits, not elements, so there is nothing to enumerate and no way to recover a key. You also cannot get an exact count, and you cannot attach a value to a key — it answers exactly one question, about one element you already hold, and nothing else.
It is like a punch-card guest list: if the hole your name needs is unpunched, you were certainly never added, but a punched hole may have been made by someone whose pattern overlapped yours.
saying these in an interview costs you the question
- Says a positive result proves the element is present
- Claims false negatives are possible in the standard form
- Thinks the stored elements can be read back out
- Assumes the false-positive rate stays fixed as the filter fills
- Retries a query hoping for a different answer