Google Interview Question for SDE1s


Country: India




Comment hidden because of low score. Click to expand.
5
of 7 vote

Hint: Binary Search on the Answer

- random April 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

I can add more description to that. Count the SUM of all volumes you have and then divide it by number of people K. You will get the best possible value that is SUM/K, but that's only a dream.

Now you can start the binary search by always trying to slice the cakes by some number x, 0<x<=SUM/K. In case there is not enough slices for people, you know the answer will be in the range 0<x. In case you have enough slices for people, memoize x and try to look for better in x<= SUM/K.

The only problem I see here is that we are counting with real numbers, so you may never stop. So after some time it may be good to start with already mentioned algorithms

- mbriskar May 22, 2015 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

1) ELP's algorithm is correct but not efficient enough, it is an O(n*n*k) algorithm.
2) ChaoSXDemon's algorithm is not enough to solve this problem, but with some modification, it did help to figure out how many pieces of cakes the largest cake will have in the optimal solution, so that it is possible to speed up ELP's algorithm to be O(n*k).

In ELP's algorithm, there is an assumption that in the optimal solution, there must be at least one cake Vx which gets no wasted at all and it can be divided into V without any volumes remained (namely, Vx % V == 0). We can prove this by assuming the opposite case in the optimal solution. If in the optimal solution, every cake has certain volumes wasted, the V we find in that case can be increased obviously, which means it is not the optimal solution. So there must be at least one cake Vx which gets no wasted at all.

ChaoSXDemon's algorithm can be used to figure out how many pieces of cakes the largest cake will have in the optimal solution. For the largest cake, it may be divided into [1...k] parts.
Here are the steps I copied from ChaoSXDemon's algorithm (assume cake0 is divided into k0 parts, and with step 5 modified):
1. Sort the input cake from largest to smallest.
2. Starting at the number of input people, guess that each person gets cake[0] / k0 units
3. Check and verify given cake[0]/k0 units can be assigned to k people
4. If step 3 worked, decrease k0 by one and assign this bigger unit and repeat step 3
5. If during step 4 any check failed, revert to previous value
5.1 if previous value can result k pieces in total (the number of guests given) for all cakes, return it as the best result
5.2 if previous value can result (k + 1) or more pieces in total for all cakes, this means even the largest cake can have some volumes remained (we can at least discard the extra one piece from the largest cake), which violates the assumption we conclude. So previous value is not the optimal solution, and we can figure out cake[0] will be divided into current value k0 parts. Since the largest cake has some volumes remained, we cannot compute the V directly by dividing V0/k0.

I will use an example to illustrate this, consider input:
vols={6, 5, 12}, k = 4

1. sort vols, vols = {12, 6, 5}
2. k0=4, V=12/4=3, total = 12/3 + 6/3 + 5/3 = 4 + 2 + 1 = 7 > 4, k0--
3. k0=3, V=12/3=4, total = 12/4 + 6/4 + 5/4 = 3 + 1 + 1 = 5 > 4, k0--
4. k0=2, V=12/2=6, total = 12/6 + 6/6 + 5/6 = 2 + 1 + 0 = 3 < 4
5. when k0=3, total = 5 = 4 + 1, so k0=3 is not in the optimal solution, k0 should be 2
So we already know in the optimal solution, the largest cake cake[0] (with volume 12) should be divided into 2 pieces. So cake[0] will be divided into 2 parts, and each part should be larger than 4 and less than 6, but we don't know the exact size of it yet since cake[0] has some volumes remained.

Since there will be at least one cake that can be divided without any waste, we need to find out that cake. Intuitively, you can use the V for k0=3 (V=4) to compute the remained volumes for each cake to find out which cake is the cake with smallest volume remained for each piece it has. When V=4,
1. for cake[1]=6, it has 2 units (6-4=2) remained, and each piece can be increased by 2.
2. for cake[2]=5, it has 1 unite remained, and each piece can be increased by 1.
3. We will pick the cake with smallest increment, and it will be the cake that gets no waste at all, and we can get V by computing V = 5 / 1 = 5 in this case.

The entire process will be O(n*k) + O(n).

Additionally, if you examine closely, you will find that to find the k0 for cake[0] from 1...k, you can use binary search to speed it up, which means this algorithm can be an O(nlgk) algorithm.

Any comment is appreciated. Thanks.

- nybon April 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Indeed as you pointed out that if an optimal solution cannot be divisible by the largest cake and k, k-1, ... 1, then my algorithm does not find the optimal solution. I thought about the log(n) part, but due to my calculate waste algorithm and the condition that if it return -1, my assignCake function will return the previous result, I had no way to tell the difference between if I had gone to far by cutting down half, or I have simply gone one step too far (thus previous result is correct).

How would you prove that there is always at least one cake that it has no waste?

- ChaoSXDemon April 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

It's not true that there always exists a cake that has zero wasteage. Consider the case k=5, n=3, volumes = {16, 11, 2}. The optimal volume is 5, which means the first cake will have 1 unit wasted, the second cake will have 1 unit wasted, and the last cake will have 2 units wasted. The argument that we can improve the volume if some part of every cake is wasted doesn't hold because it's not always the case that there is enough cake being wasted to allow you to go to the next bigger slice size.

If you assume the cake slice sizes can be real numbers, then yes, there must be at least one cake such that none of it is being wasted. And, to be fair, the problem statement doesn't say the slices must have integer volume. But based on the discussion above it does sound everyone's assuming integers, in which case the theorem is just not true.

- eugene.yarovoi April 24, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

"based on the discussion above it does sound everyone's assuming integers"
@eugene.yarovoi, no, everyone is assuming real number size for slice. You can check out ELP and ChaoSXDemon's output, they are all outputting real numbers instead of integers as results.

From the problem's description, I think it is fair to assume real number in this case since a cake's size cannot always be an integer in real life, and V1...Vn don't have to be an integer array at all (and OP doesn't mention this is an integer array).

- nybon April 26, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@ChaoSXDemon, I said it in the second paragraph, use proof of contradiction, you will easily reach the conclusion that there is at least one cake has no wastage.

- nybon April 26, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Pseudocode:
Go through each cake, dividing it up into between 1 and numCustomers slices. Then carry that slice size through the other cakes to see how much was wasted. If the wasted amount is less than the max then set it as the new max.
Ruby Code:
{{
def wasted_cake(cakes, ci, slices, numCustomers)
# if we can cut everything out of cake CI using slices, then return the waste
if slices > numCustomers then return nil end

sliceSize = cakes[ci].to_f / slices.to_f
numSlices = slices

cakes.length.times do |i|
if i == ci then next end

cake = cakes[i]
while numSlices < numCustomers && cake >= sliceSize
cake -= sliceSize
numSlices += 1
end
end

if numSlices == numCustomers then
return ($sum - sliceSize * numCustomers) else
return nil end
end

def cut_cakes(cakes, numCustomers)
$sum = 0
cakes.each do |cake|
$sum += cake
end

minWasted = Float::MAX
maxSlice = nil

cakes.sort!
cakes.length.times do |i|
(1..numCustomers).each do |slices|
wasted = wasted_cake(cakes,i,slices,numCustomers)
if nil == wasted then next end

if wasted < minWasted then
minWasted = wasted
maxSlice = cakes[i]/slices.to_f
else
break
end
end
end

return maxSlice
end

puts cut_cakes([1,2,300],5)
puts cut_cakes([1,2,3],1)
puts cut_cakes([1,2,3],2)
puts cut_cakes([1,2,3],3)
puts cut_cakes([1,2,3],4)
puts cut_cakes([1,2,3],5)
puts cut_cakes([1,2,3],6)
}}

60.0
3.0
2.0
1.5
1.0
1.0
1.0

- ELP April 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Sort the input cake from largest to smallest.
2. Starting at the number of input people, guess that each person gets cake[0] / k units
3. Check and verify given cake[0]/k units can be assigned to k people
4. If step 3 worked, decrease k by one and assign this bigger unit and repeat step 3
5. If during step 4 any check failed, revert to previous value and return the best result

The time complexity if O(kN) where k is number of people and N is the number of cakes. So if k = N or larger then it's basically O(N^2)

float calculateWaste(float* cakeUnits, int length, float piece, int k){
	int peopleLeft = k;
	float waste = 0;
	for(int i=0; i<length; i++){
		if(peopleLeft == 0){
			waste += cakeUnits[i];
		}else{
			if(cakeUnits[i] < piece) return -1;
			int maxPeople = (int)floor(cakeUnits[i]/piece);
			maxPeople = maxPeople > peopleLeft ? peopleLeft : maxPeople;
			waste += cakeUnits[i] - piece*maxPeople;
			peopleLeft -= maxPeople;
		}
	}
	return waste;
}

float* assignCake(float* cakeUnits, int length, int k){
	float* result = new float[2];
	int totalPeople = k;
	result[0] = cakeUnits[0] / k;
	result[1] = calculateWaste(cakeUnits, length, result[0], totalPeople);
	float prevUnit = result[0];
	float prevWaste = result[1];
	while(result[1] > 0){
		printf("Unit: %3.4f Wasted: %3.4f\n", result[0], result[1]);
		k--;
		prevUnit = result[0];
		prevWaste = result[1];
		result[0] = cakeUnits[0] / k;
		result[1] = calculateWaste(cakeUnits, length, result[0], totalPeople);
	}
	result[0] = prevUnit;
	result[1] = prevWaste;
	return result;
}

int main(int argc, char** argv){

	float cakes[] = {4, 4, 2};
	int length = sizeof(cakes) / sizeof(cakes[0]);
	float* result = assignCake(cakes, length, 6);

	printf("%3.4f per person wasting %3.4f units\n", result[0], result[1]);

	system("PAUSE");
	return 0;
}

Outputs:

Unit: 0.6667 Wasted: 6.0000
Unit: 0.8000 Wasted: 5.2000
Unit: 1.0000 Wasted: 4.0000
Unit: 1.3333 Wasted: 2.0000
1.3333 per person wasting 2.0000 units
Press any key to continue . . .

- ChaoSXDemon April 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Why is this correct? You're assuming that the largest cake will always be fully used up. I don't see why this has to be the case in the optimal solution. How do you know that some wastage in the largest cake wouldn't optimize the overall cake utilization?

- eugene.yarovoi April 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The largest cake will contain (composed of) smaller cakes simple because it is larger. For example, {4, 4, 2}, 4 can be composed of 2+2. The algorithm divides the largest cake for everyone at first but as it progresses, it tries to divide less and less of the largest cake to everyone. During the last iteration, the largest cake will only be shared with one person. Keep in mind that we cannot mix cakes and so to minimize waste, we always want to share the max number of cake. The max number of cake being shared is always a ratio of the largest cake since a smaller number divide by the number of people will always be equal or less than the larger number divide by the number of people.

- ChaoSXDemon April 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@ChaoSXDemon, it doesn't work for this case if I understand your algorithm correctly.
vols = {12, 6, 5}, k = 4
The expected result should be V=5 while your algorithm will give V=4

- nybon April 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Although this algorithm is not enough to solve this problem, with some modification, it did help to figure out how many pieces of cakes the largest cake will have in the optimal solution. I will try to explain below.

- nybon April 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Objective:
1. Minimize the total waste by volume (not by flavor)
2. Maximize distribution (so maximum number of people must be served)

Constraints:
1. A person cannot have more than one flavor
2. More than one flavor cannot be distributed to a person
3. One flavor can be distributed to more than one person
4. Per person cake share V lies between Vmin and Vmax

Logic:
To minimize the waste by volume, the per person share must be adjusted to achieve the minimal waste.

Arrange the cakes in descending order Vmax to Vmin
	Setup a cake distribution list: KDistribList[]
	Setup the waste basket: wasteBasket
	For each cake in the list:
		Check if KDistribList size = K { 
			If YES, then add the remaining cakes to wasteBasket
			Exit; distribution is complete 
		}
		Count the number of times V goes into Vcake
		Throw the remainder into waste basket { wasteBasket = wasteBasket+ Vcake%V }
		If (Vcake/V <= (K - KDistribList.Size) { //Meaning there are spaces left
			add the Vs to distribution list KDistribList[] = [The Vs extracted from Vcake]			
		} else if (Vcake/V > (K - KDistribList.Size) { 
			//Meaning there are more pieces than spaces left
			add as much Vs to distribution list KDistribList[] that will fit
			add the remaining to wasteBasket { wasteBasket = wasteBasket+ Vcake%V }
		}

The above algorithm assumes that K => N, there are either same or more people than cakes. If there are more cakes than people (N > K), then the above algorithm still applies, but there will always be more cakes wasted in this scenario, but we will maximize the distribution (meaning every person will get a piece guaranteed.)

Also, since minimizing waste is an objective, the way to do so is to play around with the choice of V to see what yields the minimum wasteBasket value. So we will need to repeat this algorithm for different choices of V and check for wasteBasket minima.

what say?

- whitenoise April 25, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Given N cakes and K people with N >= K
Find the (N - K + 1)th volume cake in asc order.
This can be done in O(N) given that input is not sorted, or O(logN) if it is sorted.

- rixcat May 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1) Take the volume of the smallest cake Vsmallest
2) Divide all the cakes into slices of of size Vslice = Vsmallest
4) Obtain the number of slices Nslices you would get if you divided all the cakes into slices of size Vslice
3) If Nslice is less than the number of people, then dived the smallest cake into to slices and set Vslice into Vsmallest/2
4) Repeat until the number of slices is greater than or equal to the number of people
5) If Nslice was to large (to many slices per person to start) then elliminate the smallest cake and start with the second largest cake

- Anonymous May 12, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I assume V1,V2, .... Vn are sorted.

slicesPerCustomer= f(N)

int f(i){
   if i=1 then return V1/K else
   if Vi / K > f(i-1) then return Vi / K else return f(i-1)
}

- andreas June 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

asume the v1, v2.....vn are all integers

bindary search v,

vmax = max (v1,v2,...vn);
vmin = min (v1, v2....vn);

while (vmin<vmax)
{
v = (vmin+vmax)/2;
if ( [v1 v2.....vn] has k times v ) then vmin = v;
else vmax = v;
}

return vmin;


time complexity: O (n log|vmax-vmin| )
example: 10000, 1, 1, ....3, 1... k=2, v=5000
8,7,6,3,1 k=3, v = 4
......

- huanxu4 June 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Convert it to a mathematical equation and use Newton iteration method to get the root.
The function is:
f(v)=sum{lowerBound(vi/v)}-k.
Here is the code:

/**
 * 
 * @param vs volume of cakes
 * @param k number of guests 
 */
	public double splitCake(double[] vs, int k){
		double lv=1;
		double rv=0;
		for(double d:vs)
			rv+=d;
		
		//newton method to find the root
		while(rv-lv>0.0001){
			double middle=(lv+rv)/2;
			double loss=lossFunc(vs, k, middle);
			if(loss>0)
				lv=middle;
			else if(loss<0)
				rv=middle;
			else{
				lv=middle;
				break;
			}
		}
		
		//System.out.println(lv);
		return lv;
	}
	
/**
 * \sum_{i=1}^n floor(v_i/v) - k
 * @param vs
 * @param k
 * @param v
 * @return
 */
	protected int lossFunc(double[] vs, int k, double v){
		int num=0;
		for(int i=0; i<vs.length; i++)
			num+=((int)(vs[i]/v));
		return num-k;
	}

- txbb June 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think the only problem with your code is that your loss function is the number of slices wasted and not how much cake is wasted.

- Jose Cuervo July 11, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Model it as a mathematical function and use Newton iteration to find the root.
f(v)=sum (lowerBound(vi/v))

Here is the code:

/**
 * 
 * @param vs volume of cakes
 * @param k number of guests 
 */
	public double splitCake(double[] vs, int k){
		double lv=1;
		double rv=0;
		for(double d:vs)
			rv+=d;
		
		//newton method to find the root
		while(rv-lv>0.0001){
			double middle=(lv+rv)/2;
			double loss=lossFunc(vs, k, middle);
			if(loss>0)
				lv=middle;
			else if(loss<0)
				rv=middle;
			else{
				lv=middle;
				break;
			}
		}
		
		//System.out.println(lv);
		return lv;
	}
	
/**
 * \sum_{i=1}^n floor(v_i/v) - k
 * @param vs
 * @param k
 * @param v
 * @return
 */
	protected int lossFunc(double[] vs, int k, double v){
		int num=0;
		for(int i=0; i<vs.length; i++)
			num+=((int)(vs[i]/v));
		return num-k;
	}

- txbb June 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Binary search over V.

- M June 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. Assume the cakes are already sorted by volume, so V1 is smallest and Vn is largest
2. First try setting V=V1 and see if that works (usually doesn't)
3. Now, check the wastage from each cake, call them W1...Wn
4. Imagine we want to reduce V by as little as possible to produce 1 additional piece
5. We can do so by picking the cake with the most wastage, and setting V such that we can produce that 1 additional piece from this cake. If there's a tie for most wastage, use the cake with largest volume.
6. Repeat this process until we have enough pieces

For example, assume the volumes are {10, 14, 16, 22, 30} and K=10 people.
First set V=10. That would produce {1, 1, 1, 2, 3} pieces, or 8 total.
Calculate wastage as {0, 4, 6, 2, 0}.
We realize that the 3rd cake has the most wastage (6), so we should try to produce the additional piece from this cake. To produce 2 pieces from cake 3, V should be 8.

Now we can produce {1, 1, 2, 2, 3} pieces, or 9 total.
Calculate wastage as {2, 6, 0, 6, 6}.
So we should use last cake to produce the additional piece, and set V=30/4 or 7.5
Now we can produce {1, 1, 2, 2, 4}, or 10 pieces.

Sorry I don't have proof that this greedy algorithm works, nor even 100% sure it works.

- Sunny June 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Let k be the total number of people, going to have the cake.
-> First take each cake say v1, divide it with k, and store it into float, if the value is not a perfect integer.
Ex: float f = v1/k;
-> now take that float value and assign it to integer using math.floor. which will round to the perfect integer.
-> Now subtract this integer from float, which will give minimum wastage in cake.
-> So total number of cakes x float values gives minimum wastage.
Ex: Let volume of cake = 15 kg.
People = 4.
float f = 15/4; f = 3.75
int perHead = Math.floor(3.75); perHead = 3;
float wastage = f - perHead; wastage = 0.75;
So, total wastage = wastage * total number of cakes.

- Prashanth April 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Prashanth
lets say there are 3 cakes (1,2,3 unit volume) and 6 people (k).

am a bit lost as to how do I arrive at: cutting slices of 1 unit from each cake and not leaving any wastage behind.

could you perhaps point it out ?

- VJ April 17, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi VJ,
So if you do like that, then there will not be any wastage.
float f = 1/6; it depends on the volume of cake. for ex, if it is 1000 gm, then 1000/6 = 166.667...., so each one will get 166 gms and wastae per cake is 0.667 gms.
So, out of 3 cakes, if all are of equal weight, then wastage = 0.667 * 3

- Prashanth April 17, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I don't think you understood the problem. Each person can only receive one type of cake. Let's say your 3 cakes are volume 400, 400, 200 and you have 6 people. The optimal distribution is to split each cake of size 400 into 3 pieces, and waste the entire cake of 200. Each person gets 133.3333... There is no way to split the cakes between 6 people such that less than 200 units of cake volume are wasted and that each person receives a slice from exactly one cake. You couldn't give each person 166 units of volume and have each person receive only one type of cake.

- eugene.yarovoi April 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Imagine there are 2 cakes and you are the second person to choose a piece. Since person 1 is sure to claim the biggest cake, you have the choice to either pick the smaller cake or half of the bigger cake.
Behind you is your friend who also wants some cake, assuming you chose to split the larger cake, then your friend can either claim the smaller cake or split the bigger cake with the 3 of you

So this seems like a greedy algorithm,

(defn maxPos [ls] (.indexOf ls (apply max ls)))

(defn distributeCake [cakeVol people]
           (loop [claims (vec (repeat (count cakeVol) 0))
                  peopleLeft people]
             (if (= 0 peopleLeft) claims
               (let [maxPos (maxPos (map #(/ %1 (inc %2)) cakeVol claims)) ]
                 (recur (assoc claims maxPos (inc (claims maxPos))) (dec peopleLeft))))))

(distributeCake [32 42 52 133] 55)
=> [6 9 11 29]

(apply min (map / [32 42 52 133] (distributeCake [32 42 52 133] 55)))
=> 133/29  , or the smallest volume

edit: I guess I didn't explain the last step. Once you optimize for the solution where not everyone recieves the same volume as an intermediate step, you can find the volume everyone gets by dividing each volume by how many people and returning the minimum.

- rzhng April 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hi,
From the above question, its clear that every one should get equal volume of cake and he should not get the same flavor again, So can you please recheck your solution with the matching query.

- Prashanth April 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Does this not solve this problem:

1. Obtain the GCD of the volumes of the cake.
2. Divide all the cakes with this volume.
3. Distribute those pieces equally among the K people.

we will waste (K-1)GCD_Vol in this way.

- Anonymous April 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

GCD will give us no remainder, take the above example where cakes are {4, 4, 2}. Obviously the GCD is 2 since 4/2 = 2 and 2/2 = 1 and anything else will create remainders. But the optimal unit of cake is 1.3333333 and obviously that does not equal to 2. Finally (K-1)*GCD_Vol = 5*2 = 10 which is not 2.0 unit of wasted cake.

- ChaoSXDemon April 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Does this not solve this problem:

1. Obtain the GCD of the volumes of the cake.
2. Divide all the cakes with this volume.
3. Distribute those pieces equally among the K people.

we will waste (K-1)GCD_Vol in this way.

- Chaitanya April 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

No, take the above example of cakes {4, 4, 2}. The GCD is 2 and dividing all cakes by this volume yields 1.0 instead of 1.3333. Finally the (k-1)GCD_Vol is 5*1= 5.0 which is not 2.0 units of waste.

- ChaoSXDemon April 20, 2013 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More