20 perguntas da entrevista do desenvolvedor do iOS

preparando-se para sua entrevista do iOS

o grande dia está chegando. Seja um telefone, online ou em entrevista pessoal, é sempre um pouco estressante. Então, para aliviar o estresse que você fez algum trabalho de preparação – concluído o trabalho de casa sobre a empresa que você está entrevistando com, perseguido o gerente de contratação e metade da equipe de engenharia da empresa de sua escolha no linkedin & github, você roçou em alguns dos conhecimentos e habilidades que você não tenha usado de algum tempo, você está pronto para ir.

mas seguindo o lema dos Seals da Marinha dos EUA “dois é um e um não é nenhum” vamos passar por outra atualização rápida para ajudá-lo a ace Que iOS entrevista. Então, vamos direto para isso!

vamos começar com algumas das perguntas básicas para as quais espero que você já esteja pronto. Eles podem parecer óbvios, mas você ficaria chocado com quantos engenheiros falharam miseravelmente neles durante os 12 anos em que tenho feito entrevistas técnicas.

questões técnicas

Ok, agora que temos isso coberto, vamos pular para as questões técnicas.

veja aqui o slideshare para todas as perguntas da entrevista técnica!

Pergunta 1

em um construtor UITableViewCell:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

para que é utilizado o reuseIdentifier?

o reuseIdentifieré usado para indicar que uma célula pode ser reutilizada em um UITableView. Por exemplo, quando a célula parece a mesma, mas tem conteúdo diferente. O UITableView manterá um cache interno de UITableViewCell com o reuseIdentifier e permitirá que eles sejam reutilizados quando dequeueReusableCellWithIdentifier: for chamado. Ao reutilizar a célula da tabela, o desempenho de rolagem do tableview é melhor porque novas visualizações não precisam ser criadas.

Pergunta 2

explicar a diferença entre as propriedades sintetizadas atômicas e não atômicas?Atômico e não atômico refere-se a se os setters/getters para uma propriedade Irão atomicamente ler e escrever valores para a propriedade. Quando a palavra-chave atômica é usada em uma propriedade, qualquer acesso a ela será “sincronizado”. Portanto, uma chamada para o getter terá a garantia de retornar um valor válido, no entanto, isso vem com uma pequena penalidade de desempenho. Portanto, em algumas situações nonatomic é usado para fornecer acesso mais rápido a uma propriedade, mas há uma chance de que uma condição de corrida fazendo com que a propriedade a ser nulo em raras circunstâncias (quando um valor está sendo definido a partir de outro thread e o valor antigo, foi lançado da memória, mas o novo valor ainda não foi totalmente atribuído para a localização na memória para a propriedade).

Pergunta 3

explicar a diferença entre copiar e reter?

reter um objeto significa que a contagem de retenção aumenta em um. Isso significa que a instância do objeto será mantida na memória até que a contagem de retenção caia para zero. A propriedade armazenará uma referência a esta instância e compartilhará a mesma instância com qualquer outra pessoa que a reteve também. Cópia significa que o objeto será clonado com valores duplicados. Não é compartilhado com mais ninguém.

quer ace sua entrevista técnica? Agende uma sessão de prática de entrevista técnica com um especialista agora!

Pergunta 4

o que é o método swizzling no Objetivo C e por que você o usaria?

o método swizzling permite que a implementação de um seletor existente seja comutada em tempo de execução para uma implementação diferente em uma tabela de despacho de classes. Swizzling permite que você escreva código que pode ser executado antes e / ou depois do método original. Por exemplo, talvez para rastrear o tempo que a execução do método levou ou para inserir Instruções de log

#import "UIViewController+Log.h"@implementation UIViewController (Log) + (void)load { static dispatch_once_t once_token; dispatch_once(&once_token, ^{ SEL viewWillAppearSelector = @selector(viewDidAppear:); SEL viewWillAppearLoggerSelector = @selector(log_viewDidAppear:); Method originalMethod = class_getInstanceMethod(self, viewWillAppearSelector); Method extendedMethod = class_getInstanceMethod(self, viewWillAppearLoggerSelector); method_exchangeImplementations(originalMethod, extendedMethod); }); } - (void) log_viewDidAppear:(BOOL)animated { ; NSLog(@"viewDidAppear executed for %@", ); }@end

Pergunta 5

Qual é a diferença entre estados de execução não executados, inativos, ativos, em segundo plano e suspensos?

  • não está em execução: O aplicativo não foi iniciado ou estava em execução, mas foi encerrado pelo sistema.
  • inativo: o aplicativo está sendo executado em primeiro plano, mas atualmente não está recebendo eventos. (Pode estar executando outro código embora.) Um aplicativo geralmente permanece neste estado apenas brevemente à medida que faz a transição para um estado diferente.
  • ativo: o aplicativo está sendo executado em primeiro plano e está recebendo eventos. Este é o modo normal para aplicativos em primeiro plano.
  • Background: o aplicativo está em segundo plano e executando o código. A maioria dos aplicativos entra neste estado brevemente a caminho de serem suspensos. No entanto, um aplicativo que solicita tempo de execução extra pode permanecer neste estado por um período de tempo. Além disso, um aplicativo que está sendo iniciado diretamente em segundo plano entra nesse estado em vez do estado inativo.
  • suspenso: o aplicativo está em segundo plano, mas não está executando o código. O sistema move os aplicativos para esse estado automaticamente e não os notifica antes de fazê-lo. Enquanto suspenso, um aplicativo permanece na memória, mas não executa nenhum código. Quando ocorre uma condição de pouca memória, o sistema pode limpar aplicativos suspensos sem aviso prévio para criar mais espaço para o aplicativo em primeiro plano.

Pergunta 6

o que é uma categoria e quando é usada?

uma categoria é uma maneira de adicionar métodos adicionais a uma classe sem estendê-la. É frequentemente usado para adicionar uma coleção de métodos relacionados. Um caso de uso comum é adicionar métodos adicionais às classes integradas nas estruturas Cocoa. Por exemplo, adicionando métodos de download assíncrono à classe UIImage.

Pergunta 7

você pode detectar o bug no código a seguir e sugerir como corrigi-lo:

@interface MyCustomController : UIViewController @property (strong, nonatomic) UILabel *alert; @end @implementation MyCustomController - (void)viewDidLoad { CGRect frame = CGRectMake(100, 100, 100, 50); self.alert = initWithFrame:frame]; self.alert.text = @"Please wait..."; ; dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(10); self.alert.text = @"Waiting over"; } ); } @end 

todas as atualizações da interface do usuário devem ser feitas no thread principal. No código acima, a atualização para o texto de alerta pode ou não acontecer no thread principal, uma vez que a fila de despacho global não oferece garantias . Portanto, o código deve ser modificado para sempre executar a INTERFACE de usuário de atualização no thread principal

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(10); dispatch_async(dispatch_get_main_queue(), ^{ self.alert.text = @"Waiting over"; });}); 

Pergunta 8

Qual é a diferença entre viewDidLoad e viewDidAppear?
o que você deve usar para carregar dados de um servidor remoto para exibir na visualização?

viewDidLoad é chamado quando a visualização é carregada, seja de um arquivo Xib, storyboard ou criado programaticamente em loadView. viewDidAppear é chamado toda vez que a visualização é apresentada no dispositivo. Qual usar depende do caso de uso para seus dados. Se os dados são bastante estáticos e não são susceptíveis de mudar, então ele pode ser carregado em viewDidLoad e em cache. No entanto, se os dados mudarem regularmente, usar viewDidAppear para carregá-los é melhor. Em ambas as situações, os dados devem ser carregados de forma assíncrona em um thread em segundo plano para evitar o bloqueio da IU.

pergunta 9

que considerações você precisa ao escrever um UITableViewController que mostra imagens baixadas de um servidor remoto?

esta é uma tarefa muito comum no iOS e uma boa resposta aqui pode cobrir toda uma série de conhecimentos. A informação importante na questão é que as imagens são hospedadas remotamente e podem levar tempo para download, Portanto, quando pede “considerações”, você deve estar falando sobre:

  • faça o download da imagem apenas quando a célula for rolada para a visualização, ou seja, quando cellForRowAtIndexPath for chamada.
  • baixando a imagem de forma assíncrona em um thread de fundo para não bloquear a interface do Usuário para que o usuário possa continuar rolando.
  • quando a imagem foi baixada para uma célula, precisamos verificar se essa célula ainda está na visualização ou se foi reutilizada por outro dado. Se ele foi reutilizado, devemos descartar a imagem, caso contrário, precisamos voltar ao thread principal para alterar a imagem na célula.

outras boas respostas falarão sobre o Cache offline das imagens, usando imagens de espaço reservado enquanto as imagens estão sendo baixadas.

pergunta 10

o que é um protocolo, e como você define o seu próprio E quando é usado?

um protocolo é semelhante a uma interface de Java. Ele define uma lista de métodos necessários e opcionais que uma classe deve/pode implementar se adotar o protocolo. Qualquer classe pode implementar um protocolo e outras classes podem então enviar mensagens para essa classe com base nos métodos de protocolo sem que ele saiba o tipo da classe.

@protocol MyCustomDataSource- (NSUInteger)numberOfRecords;- (NSDictionary *)recordAtIndex:(NSUInteger)index;@optional- (NSString *)titleForRecordAtIndex:(NSUInteger)index;@end

um caso de uso comum está fornecendo uma fonte de dados para UITableView ou UICollectionView.

pergunta 11

o que é KVC e KVO? Dê um exemplo de uso de KVC para definir um valor.

KVC significa codificação de valor-chave. É um mecanismo pelo qual as propriedades de um objeto podem ser acessadas usando string em tempo de execução, em vez de ter que saber estaticamente os nomes das propriedades no tempo de desenvolvimento. KVO significa Key-Value Observing e permite que um controlador ou classe observe as alterações em um valor de propriedade.

Vamos dizer que há uma propriedade name em uma classe:

@property (nonatomic, copy) NSString *name;

podemos acessá-lo usando o KVC:

NSString *n = 

E podemos modificar o valor enviando a mensagem:

Questão 12

o Que são os blocos e como são utilizados?

os blocos são uma maneira de definir uma única tarefa ou unidade de comportamento sem ter que escrever uma classe Objective-C inteira. Sob os blocos de tampas ainda são objetos C objetivos. Eles são de um nível de linguagem recurso que permite técnicas de programação como lambdas e encerramentos para ser suportada em Objective-C. Criação de um bloco é feito usando o ^ { } sintaxe:

 myBlock = ^{ NSLog(@"This is a block"); }

Ele pode ser invocado como assim:

myBlock();

é, essencialmente, um ponteiro de função que também tem uma assinatura que pode ser usado para aplicar o tipo de segurança a nível de compilação e tempo de execução. Por exemplo, você pode passar um bloco com uma assinatura específica para um método como esse:

- (void)callMyBlock:(void (^)(void))callbackBlock;

se você deseja que o bloco Receba alguns dados, pode alterar a assinatura para incluí – los:

- (void)callMyBlock:(void (^)(double, double))block { ... block(3.0, 2.0);}

pergunta 13

quais mecanismos o iOS fornece para suportar multi-threading?

  • NSThread cria um novo thread de baixo nível que pode ser iniciado chamando o método start.
NSThread* myThread = initWithTarget:self selector:@selector(myThreadMainMethod:) object:nil];; 
  • NSOperationQueue permite que um pool de threads seja criado e usado para executar NSOperations em paralelo. NSOperation s também pode ser executado no thread principal perguntando NSOperationQueuepara o mainQueue.
NSOperationQueue* myQueue = init];; ;
  • GCD ou Grand Central Dispatch é um recurso moderno do Objective-C que fornece um rico conjunto de métodos e APIs para usar, a fim de suportar tarefas comuns de multi-threading. O GCD fornece uma maneira de enfileirar tarefas para despacho no thread principal, em uma fila simultânea (as tarefas são executadas em paralelo) ou em uma fila serial (as tarefas são executadas em ordem FIFO).
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_async(myQueue, ^{ printf("Do some work here.\n");});

pergunta 14

Qual é a cadeia de resposta?

quando um evento acontece em uma visualização, por exemplo, um evento de toque, a visualização dispara o evento para uma cadeia de objetos UIResponder associados ao UIView. O primeiro UIResponder é o UIView em si, se ele não lidar com o evento, então ele continua até a cadeia até UIResponder lida com o evento. A cadeia incluirá UIViewController s, pai UIView s e seus associados UIViewController s, Se nenhum deles lidar com o evento, então o UIWindow é perguntado se ele pode lidar com isso e, finalmente, se isso não lidar com o evento, então o UIApplicationDelegate é perguntado.

Se você tem a oportunidade de desenhar um presente para fora, vale a pena fazer para impressionar o entrevistador:

insira a descrição da imagem aqui

Pergunta 15

Qual a diferença entre a utilização de um delegado e de notificação?

ambos são usados para enviar valores e mensagens para as partes interessadas. Um delegado é para comunicação individual e é um padrão promovido pela Apple. Na delegação, os eventos de aumento de classe terão uma propriedade para o delegado e normalmente esperam que ele implemente alguns protocol. A classe delegating pode então chamar os métodos de Protocolo _delegate_s.

a notificação permite que uma classe transmita eventos em todo o aplicativo para quaisquer partes interessadas. A classe broadcasting não precisa saber nada sobre os ouvintes para este evento, portanto, a notificação é muito útil para ajudar a dissociar componentes em um aplicativo.

 postNotificationName:@"TestNotification" object:self];

pergunta 16

Qual é a sua preferência ao escrever UI? Arquivos Xib, Storyboards ou programáticos UIView?

não há resposta certa ou errada para isso, mas é uma ótima maneira de ver se você entende os benefícios e desafios com cada abordagem. Aqui estão as respostas comuns que ouço:

  • Storyboard e Xib são ótimos para produzir rapidamente UI que correspondem a uma especificação de design. Eles também são muito fáceis para os gerentes de produto verem visualmente o quão longe está uma tela.
  • Storyboard também são ótimos em representar um fluxo através de um aplicativo e permitir uma visualização de alto nível de um aplicativo inteiro.
  • as desvantagens do Storyboard são que, em um ambiente de equipe, eles são difíceis de trabalhar de forma colaborativa porque são um único arquivo e a mesclagem se torna difícil de gerenciar.Storyboards e arquivos Xib também podem sofrer de duplicação e tornar-se difíceis de atualizar. Por exemplo, se todos os botões precisam parecer idênticos e de repente precisam de uma mudança de cor, então pode ser um processo longo/difícil fazer isso em storyboards e xibs.
  • a construção programática de UIView pode ser detalhada e tediosa, mas pode permitir um maior controle e também uma separação e compartilhamento mais fáceis de código. Eles também podem ser mais facilmente testados por unidade.

a maioria dos desenvolvedores irá propor uma combinação de todos os 3 onde faz sentido compartilhar código, em seguida, re-utilizável UIViews ou Xib arquivos.

pergunta 17

como você armazenaria com segurança os dados privados do Usuário offline em um dispositivo? Quais outras práticas recomendadas de segurança devem ser tomadas?

novamente, não há uma resposta certa para isso, mas é uma ótima maneira de ver o quanto uma pessoa investigou a segurança do iOS. Se você está entrevistando com um banco, eu quase definitivamente esperar que alguém sabe algo sobre isso, mas todas as empresas precisam dar segurança a sério, então aqui está a lista ideal de tópicos que eu esperaria ouvir uma resposta:

  • Se os dados é extremamente sensível, em seguida, ele nunca devem ser armazenados off-line no dispositivo, pois todos os dispositivos são crackable.
  • o chaveiro é uma opção para armazenar dados com segurança. No entanto, sua criptografia é baseada no código pin do dispositivo. Os usuários não são forçados a definir um pin, portanto, em algumas situações, os dados podem nem ser criptografados. Além disso, o código pin dos usuários pode ser facilmente hackeado.
  • uma solução melhor é usar algo como SQLCipher, que é um banco de dados SQLite totalmente criptografado. A chave de criptografia pode ser aplicada pelo aplicativo e separada do código pin do Usuário.

outras práticas recomendadas de segurança são:

  • comunique-se apenas com servidores remotos por SSL/HTTPS.
  • se possível, implemente a fixação do certificado no aplicativo para evitar ataques man-in-the-middle ao WiFi público.
  • Limpe os dados confidenciais da memória substituindo-os.
  • certifique-se de que toda a validação dos dados que estão sendo enviados também seja executada no lado do servidor.

pergunta 18

o que é MVC e como é implementado no iOS?
quais são algumas armadilhas que você experimentou com ele? Existem alternativas ao MVC?

MVC significa Modelo, Vista, controlador. É um padrão de design que define como separar a lógica ao implementar interfaces de usuário. No iOS, a Apple fornece UIView como uma classe base para todos _View_s, UIViewController é fornecido para suportar O controlador que pode ouvir eventos em uma exibição e atualizar a exibição quando os dados mudam. O modelo representa dados em um aplicativo e pode ser implementado usando qualquer NSObject, incluindo coleções de dados como NSArray e NSDictionary.

algumas das armadilhas que as pessoas atingem são inchadas UIViewController e não separam o código em classes além do formato MVC. Eu recomendo a leitura de algumas soluções para este:

  • https://www.objc.io/issues/1-view-controllers/lighter-view-controllers/
  • https://speakerdeck.com/trianglecocoa/unburdened-viewcontrollers-by-jay-thrash
  • https://programmers.stackexchange.com/questions/177668/how-to-avoid-big-and-clumsy-uitableviewcontroller-on-ios

Em termos de alternativas, isso é muito aberta. A alternativa mais comum é MVVM usando ReactiveCocoa, mas outros incluem VIPER e usando código reativo funcional.

pergunta 19

um gerente de produto em sua empresa relata que o aplicativo está travando. Qual é o seu trabalho?

esta é uma grande questão em qualquer linguagem de programação e é realmente projetado para ver como você problema resolver. Você não recebe muita informação, mas algumas entrevistas lhe darão mais detalhes sobre o assunto à medida que avança. Comece simples:

  • obtenha as etapas exatas para reproduzi-lo.
  • descubra o dispositivo, versão iOS.
  • eles têm a versão mais recente?
  • obtenha logs do dispositivo, se possível.

uma vez que você pode reproduzi-lo ou ter mais informações, em seguida, começar a usar ferramentas. Digamos que ele trave por causa de um vazamento de memória, eu esperaria ver alguém sugerir o uso da ferramenta de vazamento de instrumentos. Um candidato realmente impressionante começaria a falar sobre como escrever um teste de unidade que reproduz o problema e depurar por meio dele.

outras variações desta questão incluem UI lenta ou o congelamento do aplicativo. Novamente, a ideia é ver como você resolve problemas, quais ferramentas você sabe sobre isso ajudaria e você sabe como usá-los corretamente.

pergunta 20

o que é AutoLayout? O que significa quando uma restrição é “quebrada” pelo iOS?

AutoLayout é uma maneira de definir UIViews usando um conjunto de restrições que especificam o local e o tamanho com base em outras visualizações ou com base em valores explícitos. O AutoLayout facilita o design de telas que redimensionam e traçam seus componentes melhor com base no tamanho e na orientação de uma tela. _constraint_s incluem:

  • definir a distância horizontal/vertical entre 2 Visualizações
  • definir a altura/largura como uma proporção em relação a uma visualização diferente
  • uma largura/altura/espaçamento pode ser um valor estático explícito

às vezes, as restrições entram em conflito entre si. Por exemplo, imagine um UIView que tem 2 restrições de altura: diz-se fazer o UIView 200px alta, eo segundo diz fazer a altura duas vezes a altura de um botão. Se o tempo de execução do iOS não puder satisfazer essas duas restrições, ele precisará escolher apenas uma. O outro é então relatado como sendo “quebrado” pelo iOS.

perguntas padrão

” Conte-me sobre você.”

este é realmente complicado! Muitas pessoas lêem seu currículo em voz alta (esquecendo que estou olhando bem para ele!), listando todas as aulas que tomaram na faculdade, todas as posições que já ocuparam (e isso realmente contribui para os engenheiros de nível sênior) e todas as responsabilidades (que muitas vezes são as mesmas em 2 ou 3 empresas em que determinada pessoa trabalhou. Então, 20 minutos depois, eu ainda não sei nada de novo / fora do currículo sobre o candidato, estamos 20 minutos dentro, e até então eu acredito que eles poderiam muito bem ser robôs (e robôs tendem a não se encaixar muito bem com equipes dinâmicas).

então faça a si mesmo (e ao gerente de contratação) um favor preparando um passo de elevador de 2 minutos de seu histórico – mantenha-o simples, conciso e breve e, em seguida, adicione algo pessoal no final. Você adora correr? Você está treinando o time de futebol da sua filha? Fã duro de Star Wars? Adicionar um pouco de personalidade é um grande quebra-gelo, e fará uma transição incrível para a parte mais profunda da entrevista.

“descreva um problema interessante e como você o resolveu.”

sua chance de ouvir este é basicamente 99%, então é melhor você ter uma ótima resposta pronta para eles! Aqui estão algumas dicas: pense em um projeto particularmente incrível do qual você se orgulha. Percebeste? Muito bom! Agora, pegue um pedaço de papel e resuma-o em 5 pontos.
1.º ponto de bala – breve história de as circunstâncias por trás do projeto
2º bala – a natureza do projeto em si
marcador 3 – os problemas que você tem, me deparei enquanto a resolução dele/
4thbullet – como resolver as dificuldades acima de
5ª ponto de bala – o que você aprendeu com ele.

agora, Encontre alguém que ouça (um amigo, parceiro, colega) e pergunte se a história faz sentido (menos quaisquer aspectos técnicos se a pessoa com quem você está falando não for seu colega). É uma ótima maneira de validar se a história se mantém unida.

você ficaria chocado quantas vezes eu ouvi coisas como ” e então eu fui para John, e ele usou a ferramenta que ele criou para remover o bug crítico que então…….”. Quem é o Tom? O teu gerente? Estagiário? Peer? Por que você foi para ele de todos na sua empresa? Qual é a ferramenta mágica que ele montou? Qual bug crítico exatamente ele removeu e como? Qual foi o resultado?

você tem a ideia 😃

bônus adicional? Agora você tem 5 pontos de bala que você pode usar como uma folha de fraude durante a sua entrevista sem olhar como aquele cara que está lendo seu currículo em voz alta.

agora vamos pular para as perguntas estranhas que alguns gerentes de contratação gostam de jogar para derrubá-lo do seu jogo.

  • como você testaria uma torradeira?
  • quantas Canetas você pode caber em um avião?
  • quantas janelas existem em São Francisco?
  • quantas bolas de golfe podem caber em um ônibus escolar?
  • quantos Big Macs o Mcdonald’s vende todos os anos nos EUA?

a lista continua e continua. Embora não tenha nada a ver com suas habilidades técnicas, ele faz um bom trabalho ao verificar como você lida com bolas curvas e para ver se você é capaz de resolver problemas passo a passo lógicos. Na maioria dos casos, não há respostas perfeitas para esse tipo de pergunta (embora você possa pesquisá-las no google para sua paz de espírito). É tudo sobre como você explica sua lógica ao seu entrevistador.

aqui está a resposta para a questão das bolas de golfe de Michael Beauchamp, então você tem a ideia do que estou falando:

eu acho que um ônibus escolar padrão tem cerca de 8 pés de largura por 6 pés de altura por 20 pés de comprimento – isso é apenas um palpite com base nas milhares de horas que fiquei preso atrás de ônibus escolares enquanto o tráfego em todas as direções é interrompido.Isso significa 960 pés cúbicos e, como existem 1728 polegadas cúbicas em um pé cúbico, isso significa cerca de 1,6 milhão de polegadas cúbicas.

eu calcular o volume de uma bola de golfe para ser cerca de 2,5 polegadas cúbicas (4/3 * pi * .85) como .85 polegadas é o raio de uma bola de golfe.

divida essas 2,5 polegadas cúbicas em 1.6 milhões e você cria 660.000 bolas de golfe. No entanto, uma vez que há assentos e porcaria lá ocupando espaço e também uma vez que a forma esférica de uma bola de golfe significa que haverá espaço vazio considerável entre eles quando empilhados, vou arredondar para 500.000 bolas de golfe.

ver? Passo. E de repente é uma questão relativamente simples e lógica. Apenas fique calmo e, em vez de tentar encontrar um número instantâneo em sua cabeça, ande com o entrevistador através de sua linha de pensamentos com você.

precisa de prática da vida real? Sinta-se à vontade para agendar uma entrevista simulada com Matt, que faz entrevistas técnicas há 12 anos, e peça seu feedback!

Deixe uma resposta

O seu endereço de email não será publicado.