Итак обновление:
1. Поговорил по телефону с тем самым сеньор директором чего-то там. Разговор был простой и приятный, он рассказал о компании попросил рассказать о себе. Соответственно я рассказал о том где, что и сколько работал. Кем работал и что использовал тоже было там. Мои ответы собеседника удовлетворили и он попросил меня выслать резюме ему чтобы он отправил его hiring manager. Из необычного только то что мы говорили около 21:00 . Мне было все равно, а он сказал что если я не простив то ему удобно после 18. Надеюсь он звонил не с работы.
2. Через пару дней мне написал этот самый менеджер и предложил созвониться и поговорить, что мы и сделали. Тут было все так как оно обычно и бывает: почему вы хотите к нам, и далее "кем, где, сколько", опишите проекты и так далее. В конце он сказал что они готовы продолжать меня собеседовать и просил задать вопросы. Я спросил про их Glassdoor где народ пишет про 60 часов в неделю и другие странные вещи. На что он ответил что не все влились в дружную компанию и мол есть те кто всегда несчастен. После этого я сказал что если я пройду этап "домашнее задание" по "code review" то у меня будут ещё вопросы про $$ и другие дела
до технического интервью. После этого он сказал что всё ок и он готов выслать мне задание в удобные день и час, но я должен его выслать назад не позднее 3х часов с момента получения. Я сказал что суббота в обед будет самое оно. Так как говорили мы в пятницу вечером я прикинул что у меня будет время освежить "best practices" по этому самому "code review".
3.Суббота прошла без задания не в 12 ни в час дня я его не получил. Написал письмо, выразил свои сомнения в том правильно ли я все понял и так далее.
4. В 9 утра в понедельник во время еженедельной планерки я получаю радостное письмо что мол вот, давай, время пошло. Времени у меня оставалось не много и писал почти на коленке. В общем написал, жду ответ.
Вот задание, вот моё описание. Если кому есть что добавить что я не заметил - мне будет приятно:
Задание 1
Code Review this sample code:
Code: Select all
[RoutePrefix("api/spacex/rockets")]
public class RocketController
{
private readonly IRocketService RocketService;
private readonly IreuseRocketService reuseRocketService;
public RocketController(IRocketService rocketService,
IreuseRocketService reuseService)
{
RocketService = rocketService;
reuseRocketService = reuseService;
}
[Route("{rocketID:int}")]
[HttpGet]
public RocketDTO GetRocket(int rocketID)
{
return RocketService.GetRocket(rocketID);
}
[Route("")]
[HttpPost]
public void CreateRocket(NewRocketDTO newRocketDTO)
{
return RocketService.CreateRocket(newRocketDTO);
}
[Route("")]
[HttpPut]
public int UpdateRocket(UpdateRocketDTO updateRocketDTO)
{
return RocketService.UpdateRocket(updateRocketDTO);
}
[Route("{rocketID:int}/reuse")]
[HttpPost]
public RocketDTO MakeResusableRocket(int rocketID)
{
var rocket = RocketService.GetRocket(rocketID);
if(rocket.HasFlown == true){
if(rocket.HasLanded == true){
if(rocket.IsRefurbished){
return reuseRocketService.ReuseRocket(rocketID);
}
}
return rocket;
}
return rocket;
}
}
Ответ 1
Code Review:
1. Variable name style is inconsistent i.e. private readonly "RocketService" doesn't match reuseRocketService
2. CreateRocket method is void, but it is trying to return a result
3. MakeResusableRocket method uses nested "if" statement with redundant comparison to boolean var "true"
it would be prettier to create a variable to check all conditions:
var canReuse = rocket.HasFlown && rocket.HasLanded && rocket.IsRefurbished;
so the pseudocode would look like:
Code: Select all
public RocketDTO MakeResusableRocket(int rocketID)
{
var rocket = RocketService.GetRocket(rocketID);
var canReuse = rocket.HasFlown && rocket.HasLanded && rocket.IsRefurbished;
if(canReuse){
return reuseRocketService.ReuseRocket(rocketID);
}
return rocket;
}
4. Depending on the inner structure and business logic maybe it make sense to swap conditions i.e.:
var canReuse = rocket.IsRefurbished && rocket.HasFlown && rocket.HasLanded;
5. As far as I remember, attribute routing with the same route but different verb is allowed ("CreateRocket" and "UpdateRocket"),
However, I would suggest to name them so:
A. we are avoiding ambiguity: it makes the purpose of the method explicit
B. we are avoiding potential issue: if ever decide to separate them WEB API does not a allow a route to match on two different controllers
Задание 2
How can you optimize this? Pseudocode is fine:
Code: Select all
var partList = [..., 'booster', 'grid fin',...]
var otherPartList = [..., 'landing leg', 'booster',...]
for (int i = 0; i < partList.Length; i++)
{
for (int j = 0; j < otherPartList.Length; j++)
{
if (partList[i].Equals(otherPartList[j]))
{
Console.WriteLine(partList[i]);
}
}
}
Ответ 2
Optimization (pseudocode):
Code: Select all
int i = 0, j = 0;
var p1Length = partList.Length;
var p2Length = otherPartList.Length;
for (i = 0; i < p1Length; i++)
{
var item1 = partList[i];
for (j = 0; j < p2Length; j++)
{
var item2 = otherPartList[j];
if (item1.Equals(item2))
{
Console.WriteLine(item2);
}
}
}
What did you do and why is this faster?
1. I declared index variables out of the loop which will give us some improvement (no need to create a "j" variable again and again, I did "i" same way just to be consistent)
2. By creating variables to store arrays length I'm also saving some cycles. Arrays's length is not going to change so no need to check it every time for each array)
3. Accessing array item using indexer is going to slow down the code. I would suggest to use variables instead.
Ну и вопросы:
Work Experience
a. Describe in detail a favorite or challenging project that you have developed recently.
b. Explain the architectural decisions that were made and why.
c. Describe some challenges and how you overcame them.
d. What was your role on this project?
e. What were some lessons learned.
Ну как-то так. Может кому пригодится.
Мне вот любопытно кто что добавит в code review/Optimization ? Может я что-то упустил.