Design a job posting service where recruiters can publish different types of job openings and candidates can create profiles and apply for jobs.
Each candidate profile contains skills and years of experience. Each job specifies its desired skills, the minimum number of matching skills and the minimum years of experience.
The service must allow recruiters to view their best matching applicants and candidates to view the best jobs for which they are eligible.
A candidate is eligible for a job when both conditions are satisfied:
The matching skill count is the number of distinct job skills that also appear in the candidate's profile.
JobPostingService()
Creates an empty job posting service with no jobs, candidate profiles or applications.
void postJobOpening(String recruiterId, String jobId, String jobTitle, String jobType, List<String> requiredSkills, int minimumSkillMatches, int minimumYearsOfExperience)
recruiterId: The identifier of the recruiter posting the job.jobId: The unique identifier assigned to the job.jobTitle: The displayed title of the job.jobType: The job type, such as full-time, part-time, internship or contract.requiredSkills: The distinct skills desired for the job.minimumSkillMatches: The minimum number of desired skills a candidate must have.minimumYearsOfExperience: The minimum required years of experience.Publishes a new job opening. Every jobId is globally unique.
void createOrUpdateCandidateProfile(String candidateId, List<String> skills, int yearsOfExperience)
candidateId: The unique identifier of the candidate.skills: The candidate's distinct skills.yearsOfExperience: The candidate's completed years of experience.Creates a candidate profile if the identifier is new. Otherwise, it replaces the profile's skills and years of experience. Existing applications remain associated with the candidate.
boolean applyForJob(String candidateId, String jobId)
candidateId: The identifier of an existing candidate.jobId: The identifier of an existing job.Records the candidate's application. Return true when a new application is created. Return false when the candidate has already applied for the same job.
A candidate may apply even when the candidate is not currently eligible. Future profile changes may make the candidate eligible.
List<String> getTopCandidates(String recruiterId, String jobId, int limit)
recruiterId: The identifier of the recruiter who owns the job.jobId: The identifier of the recruiter's job.limit: The maximum number of candidate identifiers to return.Return up to limit eligible applicants for the job. Rank applicants by the following rules:
List<String> getTopEligibleJobs(String candidateId, int limit)
candidateId: The identifier of an existing candidate.limit: The maximum number of job identifiers to return.Return up to limit jobs for which the candidate is eligible. The candidate does not need to have applied for these jobs. Rank the jobs by the following rules:
1 ≤ recruiterId.length(), jobId.length(), candidateId.length() ≤ 501 ≤ jobTitle.length() ≤ 1001 ≤ jobType.length() ≤ 301 ≤ requiredSkills.size() ≤ 501 ≤ skills.size() ≤ 1001 ≤ minimumSkillMatches ≤ requiredSkills.size()0 ≤ minimumYearsOfExperience, yearsOfExperience ≤ 501 ≤ limit ≤ 1,0001 and 30 lowercase English letters, digits or hyphens.jobId is globally unique.applyForJob is called only with an existing candidate and an existing job.getTopCandidates is called only when recruiterId owns jobId.100,000 method calls are made.JobPostingService()
postJobOpening(recruiterId = "r7", jobId = "backend42", jobTitle = "Backend Engineer", jobType = "full-time", requiredSkills = ["java", "spring", "aws"], minimumSkillMatches = 2, minimumYearsOfExperience = 3)
createOrUpdateCandidateProfile(candidateId = "cora", skills = ["java", "spring", "aws", "docker"], yearsOfExperience = 4)
createOrUpdateCandidateProfile(candidateId = "dev", skills = ["java", "spring"], yearsOfExperience = 7)
createOrUpdateCandidateProfile(candidateId = "mina", skills = ["java", "aws"], yearsOfExperience = 4)
applyForJob(candidateId = "cora", jobId = "backend42") returns true.
applyForJob(candidateId = "dev", jobId = "backend42") returns true.
applyForJob(candidateId = "mina", jobId = "backend42") returns true.
getTopCandidates(recruiterId = "r7", jobId = "backend42", limit = 3) returns ["cora", "dev", "mina"].
All three applicants are eligible. "cora" matches three skills. The other applicants match two skills, so their years of experience determine their order.
JobPostingService()
createOrUpdateCandidateProfile(candidateId = "sam9", skills = ["python", "sql", "aws", "docker"], yearsOfExperience = 5)
postJobOpening(recruiterId = "r2", jobId = "data18", jobTitle = "Data Engineer", jobType = "contract", requiredSkills = ["python", "sql", "spark"], minimumSkillMatches = 2, minimumYearsOfExperience = 3)
postJobOpening(recruiterId = "r5", jobId = "cloud11", jobTitle = "Cloud Engineer", jobType = "full-time", requiredSkills = ["aws", "docker", "kubernetes"], minimumSkillMatches = 2, minimumYearsOfExperience = 4)
postJobOpening(recruiterId = "r8", jobId = "machine6", jobTitle = "Machine Learning Engineer", jobType = "full-time", requiredSkills = ["python", "pytorch"], minimumSkillMatches = 2, minimumYearsOfExperience = 2)
getTopEligibleJobs(candidateId = "sam9", limit = 5) returns ["cloud11", "data18"].
The candidate matches two skills for each returned job. The cloud job comes first because it has the higher minimum experience requirement. The machine learning job is excluded because only one required skill matches.
JobPostingService()
postJobOpening(recruiterId = "r4", jobId = "mobile25", jobTitle = "Mobile Developer", jobType = "part-time", requiredSkills = ["android", "kotlin"], minimumSkillMatches = 2, minimumYearsOfExperience = 1)
createOrUpdateCandidateProfile(candidateId = "lee3", skills = ["android"], yearsOfExperience = 2)
applyForJob(candidateId = "lee3", jobId = "mobile25") returns true.
applyForJob(candidateId = "lee3", jobId = "mobile25") returns false.
getTopCandidates(recruiterId = "r4", jobId = "mobile25", limit = 10) returns [].
createOrUpdateCandidateProfile(candidateId = "lee3", skills = ["android", "kotlin"], yearsOfExperience = 2)
getTopCandidates(recruiterId = "r4", jobId = "mobile25", limit = 10) returns ["lee3"].
The existing application remains after the profile update, and the candidate becomes eligible after gaining the second required skill.