How campus and off-campus hiring works
30 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)You registered for a placement drive, but nobody explained who runs it, who gets filtered out first and when you actually start work. Knowing the path before you register means fewer surprises and a better plan.
Campus, pool and off-campus drives
A campus drive is a hiring event a company runs at your own college, together with the TPO (Training and Placement Officer), the staff member who manages placements. You register through the college placement cell.
Three routes lead to a job: a campus drive, a pool drive and an off-campus application. They differ in who invites the company and who registers you. The block below shows each route in one line.
Campus drive: Company -> your TPO -> students of your collegePool drive: Company -> host college / online -> students of many collegesOff-campus drive: Company careers page, referral or job portal -> you apply directlyA pool drive (pool campus) is one drive for students of several colleges, held at one host college or online. An off-campus drive is any application you make directly: the company careers page, a hiring challenge, a referral or a job portal. Nobody registers you; you watch for openings yourself.
Service and product companies
A service company builds and maintains software for other businesses (clients). A product company builds its own software, such as an app or a platform, and sells or runs it. Many companies do some of both.
Both kinds hire freshers, but their drives often look different. The example below puts two sample drive styles side by side.
Example 1 · Two drive styles side by side
from dataclasses import dataclass
@dataclassclass DriveStyle: name: str freshers_hired: int test_sections: int interview_rounds: int
service = DriveStyle("Service-style drive", 800, 4, 2)product = DriveStyle("Product-style drive", 25, 2, 3)
for d in (service, product): print(d.name) print(f" Freshers hired: {d.freshers_hired}") print(f" Test sections: {d.test_sections}") print(f" Interview rounds: {d.interview_rounds}")Service-style drive Freshers hired: 800 Test sections: 4 Interview rounds: 2 Product-style drive Freshers hired: 25 Test sections: 2 Interview rounds: 3
What this code does
- The numbers are an illustration of the common pattern, not data about any real company: many hires and more test sections on one side, fewer hires and more interview rounds on the other.
- A
dataclassholds the four facts of one drive style; reading a drive notice is the same idea: note hires, sections and rounds before you plan.
Common patterns in fresher hiring:
- Volume: service companies often hire hundreds or thousands of freshers in one season; product companies usually hire fewer.
- Test focus: service drives often weigh aptitude sections heavily; product drives often weigh coding and DSA more.
- Rounds: product companies often add a second or third technical interview.
- Roles: service drives often hire for a general trainee role; product drives often name a team.
These are patterns, not rules. They change by company, role and year, so always read the drive notice.
The typical pipeline: from filter to offer
The hiring pipeline is the ordered list of rounds every candidate passes through: eligibility filter, online test, technical round(s), HR round and offer letter. Each round removes some candidates.
Each round removes many candidates, so the numbers shrink at every step. The example below shows a sample drive with made-up numbers and the percentage that passes each step.
Example 2 · The pipeline as a funnel
stages = ["Registered", "Eligible", "Cleared online test", "Cleared technical", "Cleared HR (offers)"]counts = [1200, 900, 180, 72, 54]
print(f"{stages[0]}: {counts[0]}")for stage, count, before in zip(stages[1:], counts[1:], counts): print(f"{stage}: {count} ({100 * count / before:.1f}% of the previous stage)")
overall = 100 * counts[-1] / counts[0]print(f"Overall: {overall:.1f}% of registered students got an offer")Registered: 1200 Eligible: 900 (75.0% of the previous stage) Cleared online test: 180 (20.0% of the previous stage) Cleared technical: 72 (40.0% of the previous stage) Cleared HR (offers): 54 (75.0% of the previous stage) Overall: 4.5% of registered students got an offer
What this code does
- In this sample drive the online test removes the most people: only 20% of eligible students pass it. That is common, and it is why steady practice for the test, for every round in the test, pays off so well.
- Each percentage is counted against the stage before it, while the overall figure is counted against everyone who registered.
Some drives add a group discussion, a separate coding round or a managerial round. In this sample the online test removes the most people, which is common, so steady practice for it pays off most.
Eligibility criteria: CGPA, backlogs, gaps and branch
Eligibility criteria are the minimum conditions a company sets before it lets you write the test: a CGPA cut-off, the number of backlogs allowed, any year gap in your education and the branches allowed.
Portals check the rules in a fixed order and stop at the first one you fail. The checker below applies branch, CGPA, backlog and gap rules, then compares two backlog rules.
Example 3 · An eligibility checker
from dataclasses import dataclass
MIN_CGPA = 6.5MAX_GAP_YEARS = 1BRANCHES = {"CSE", "IT", "ECE"}
@dataclassclass Student: name: str branch: str cgpa: float active_backlogs: int gap_years: int
def check(s): if s.branch not in BRANCHES: return f"not eligible (branch {s.branch})" if s.cgpa < MIN_CGPA: return f"not eligible (CGPA {s.cgpa} < {MIN_CGPA})" if s.active_backlogs > 0: return f"not eligible ({s.active_backlogs} active backlog)" if s.gap_years > MAX_GAP_YEARS: return f"not eligible (gap of {s.gap_years} years)" return "eligible"
students = [ Student("Ananya", "CSE", 8.1, 0, 0), Student("Rahul", "MECH", 7.9, 0, 0), Student("Sneha", "IT", 6.2, 0, 0), Student("Imran", "ECE", 7.0, 1, 0), Student("Kavya", "CSE", 6.5, 0, 2),]for s in students: print(f"{s.name}: {check(s)}")Ananya: eligible Rahul: not eligible (branch MECH) Sneha: not eligible (CGPA 6.2 < 6.5) Imran: not eligible (1 active backlog) Kavya: not eligible (gap of 2 years)
What this code does
- The checks run in the same order a portal usually applies them, and the first failing rule gives the reason.
- Kavya meets the cut-off exactly (6.5 is not less than 6.5), so CGPA passes; she is filtered out by the gap rule instead. Cut-offs are usually written as "6.5 and above", so equal counts as passing.
Example 4 · Active backlogs versus backlog history
active_backlogs = 0backlog_history = 1
rule_a = active_backlogs == 0 # "no active backlogs"rule_b = active_backlogs == 0 and backlog_history == 0 # "no backlog history"
print("Drive A (no active backlogs):", "eligible" if rule_a else "not eligible")print("Drive B (no backlog history):", "eligible" if rule_b else "not eligible")Drive A (no active backlogs): eligible Drive B (no backlog history): not eligible
What this code does
- The same student passes one drive and fails another because the two rules count different things.
- When a notice only says "no backlogs", ask your TPO which meaning the company uses before you assume you are eligible.
A CGPA cut-off is usually written as "6.5 and above", so equal passes. An active backlog is a subject you have not cleared yet; a backlog history means you failed a subject earlier, even if you cleared it later. Some drives allow a history but no active backlogs, and some allow neither.
From registration to joining day
The joining date is the day you start work, usually after your final exams. Campus offers are often made months earlier, so the gap between offer letter and joining can be long.
The usual order is registration, online test, interviews, result, offer letter, document checks and joining. The example below counts the days between steps of a sample timeline.
Example 5 · A sample timeline in days
from datetime import date
steps = ["Registration", "Online test", "Interviews", "Offer letter", "Joining"]dates = [date(2026, 8, 1), date(2026, 8, 20), date(2026, 9, 5), date(2026, 9, 25), date(2027, 7, 15)]
for i in range(1, len(steps)): days = (dates[i] - dates[i - 1]).days print(f"{steps[i - 1]} -> {steps[i]}: {days} days")
print(f"Registration to joining: {(dates[-1] - dates[0]).days} days")Registration -> Online test: 19 days Online test -> Interviews: 16 days Interviews -> Offer letter: 20 days Offer letter -> Joining: 293 days Registration to joining: 348 days
What this code does
- The dates are a sample for a final-year student; real gaps vary by company and year.
- The hiring rounds take about two months, but the wait from offer to joining is almost ten months. Use that time to finish your degree with no backlogs, because many offers depend on it.
Some companies send the offer letter only after you graduate, or put you on a waiting list before a joining date is fixed. Keep checking your college email and the company portal during that gap.
Next step
Check your understanding
12 quick questions