Segunda-feira, 2 de Agosto de 2010

Em Fevereiro tornamos público um problema que foi usado nas entrevistas no SAPO durante 2009.

O problema, orientado a candidatos com um background forte em ambientes Linux/UNIX, consistia no seguinte:

"Encontras-te sozinho num Data Center e tens que resolver este problema sem recurso a meios exteriores (nada de telemóvel, nada de internet; o objectivo é resolveres tu o problema). Tens um servidor que não pode ir abaixo. Nessa máquina, alguém teve a brilhante ideia de executar um `chmod -x chmod`. Resolve o problema."

O primeiro ponto a apontar é o objectivo deste problema.

O objectivo não é avaliar se o candidato consegue resolver a situação, mas sim a sua reacção. O ideal seria um misto de excitação, pânico e um olho a saltar fora.

A pergunta serve, no entanto, para avaliar o conhecimento que a pessoa tem sobre estes sistemas e a capacidade de improviso/imaginação.

Durante alguns meses, a cada 3 entrevistas em que usávamos este problema, surgia uma resposta nova.

Hoje vamos abordar algumas delas.

Começamos por soluções que não se aplicam às circunstâncias descritas, como tirar o disco e levá-lo a outra máquina que ainda tenha o chmod operacional.

De seguida, partimos para outras soluções curtas e viáveis:

perl -e 'chmod 0755, "chmod"'

python -c "import os;os.chmod('testing', 0777)"




Algumas soluções semelhantes mas com ligeiras nuances:

cat /bin/chmod > new_executable

tar --mode 555 -cvf - chmod | tar xvf -

echo chmod | cpio -o | perl -pe 's/^(.{21}).../${1}755/' | cpio -i -u

 

Depois começam a surgir soluções que são dependentes da distribuição:


E há mais (getfacl, setfacl, chflags, etc.), cada uma mais inovadora que a anterior (como um `alias chmod='/lib/ld-2.11.1.so /bin/chmod`, ou o exemplo mais abaixo).


Convém neste ponto explicar o que se sucede quando se coloca uma questão destas numa entrevista.

A interacção em torno deste problema não se cinge a uma pergunta e uma resposta, mas sim à exploração do conhecimento e capacidade inventiva da pessoa.

Eis um exemplo baseado numa entrevista verídica:

Candidato - Tenho perl na máquina?

Entrevistador - Tens.

C - Então uso o chmod do perl, que é built-in!

E - Certo. Agora vou-te tirar o perl da máquina.

C - Hum... Tenho cc?

E - Tens.

C - Então posso fazer um programa em C que usa a system call do chmod para alterar as permissões ao chmod.

E - Certo. Agora vou-te tirar o compilador.

C - Hum... Disseste que não tenho acesso à net, mas não disseste nada sobre os outros servidores no Data Center. Abro um socket para outro servidor, faço um tar do chmod de lá preservando as permissões, trago-o para a máquina a faço untar.

E - Certo. Agora vou-te tirar as outras máquinas do Data Center.

C - OK... Bem, posso sempre lançar a BusyBox, que deve estar na máquina e que tem o chmod lá dentro!

E - OK, mas agora vamos-te tirar a BusyBox. Consegues arranjar outra maneira de resolver o problema?

[o candidato pensa um pouco, olha para cima e fala como se estivesse a falar consigo próprio]

C - Eia... Esta é mesmo rabuscada... Faço um attrib ou um ls extendido para forçar o inode para a cache; agora só tenho que editar o inode que está em cache sem que o kernel se aperceba, e posso usar o sed para isso, desde que seja root; vou ao kcore procurar as estruturas do VFS e altero-lhe o bit de execução; vou é ter que ler documentação; depois é só usar o chmod para lhe repor as permissões.


[breve pausa para recuperarmos]


(já agora, e a título informativo, o candidato do texto acima encontra-se hoje em dia a trabalhar no SAPO)


Para além de todas estas (e outras) soluções (e tentativas de solução) que nos foram aparecendo, surgiram também alguns comentários interessantes como:

- Resolver o problema? Qual problema? A máquina continua a funcionar!

 

E questões como:

- Mas porque raio é que a bin de um servidor estava writable?



publicado por jac às 10:00
link do post | comentar | ver comentários (1) | adicionar aos favoritos |

Segunda-feira, 19 de Julho de 2010

Em Fevereiro colocamos aqui um post com algumas questões de SQL que poderiam ser colocadas numa entrevista.

Vamos tornar a abordar o problema, com a seguinte tabela:

mysql> select * from e;
+-------+-------+
| nome  | valor |
+-------+-------+
| josé  |    20 |
| joão  |    10 |
| rui   |     5 |
| pedro |     3 |
| josé  |     5 |
| pedro |    10 |
| luís  |    25 |
+-------+-------+
7 rows in set (0.00 sec)

 

Algo que costuma ser feito já depois das queries é perguntar aos candidatos quais os tipos de dados das duas colunas.

Para efeitos deste post, vamos assumir uma base de dados MySQL com uma tabela definida da seguinte forma:

create table e (
nome varchar(50),
valor int
) ENGINE=InnoDB;

INSERT INTO e (nome, valor) VALUES
('josé', 20),
('joão', 10),
('rui', 5),
('pedro', 3),
('josé', 5),
('pedro', 10),
('luís', 25)
;

 

Vamos analisar as queries que propusemos no nosso post anterior.

 

mysql> select sum(valor) from e;
+------------+
| sum(valor) |
+------------+
| 78         |
+------------+
1 row in set (0.40 sec)


É das queries mais simples e quase todos os candidatos a escrevem correctamente.

 

mysql> select nome, sum(valor) from e group by nome;
+-------+------------+
| nome  | sum(valor) |
+-------+------------+
| joão  |         10 |
| josé  |         25 |
| luís  |         25 |
| pedro |         13 |
| rui   |          5 |
+-------+------------+
5 rows in set (0.04 sec)


Quase todas as pessoas sabem como se faz, mas já se encontra alguns candidatos que trocam a ordem de algumas cláusulas, que se esquecem do group by, etc.

 

mysql> select nome from e group by nome having count(1) > 1;
+-------+
| nome  |
+-------+
| josé  |
| pedro |
+-------+
2 rows in set (0.00 sec)


Neste ponto sim, já começamos a perder muito boa gente.

 

mysql> select group_concat(distinct nome) from e;
+-----------------------------+
| group_concat(distinct nome) |
+-----------------------------+
| josé,joão,rui,pedro,luís    |
+-----------------------------+
1 row in set (0.00 sec)


Tipicamente já só acerta estas queries quem tem experiência intensiva com bases de dados.

Faz sentido, porque é perfeitamente viável trabalhar com bases de dados sem usar extensivamente tudo o que elas nos oferecem.

Não será de facto por não saber algo deste género que um candidato ficará pelo caminho, mas são perguntas como esta que permitem ir discernindo o tipo de uso que a pessoa dá à base de dados.

Perguntas como esta e não só: perguntas sobre as perguntas.

Numa entrevista não declaramos a base de dados, apenas a desenhamos num quadro ou numa folha de papel.

Depois de termos abordado várias queries, aí sim, abordam-se outras temáticas:


Há sempre mais qualquer coisa que a conversa traz, como por exemplo o entrevistado sugerir que o tipo de dados do valor deveria ser um INT(3)...



publicado por jac às 10:00
link do post | comentar | ver comentários (1) | adicionar aos favoritos |

Segunda-feira, 24 de Maio de 2010

Quarta-feira, dia 26 de Maio, a PT estará presente na FEUP, numa sessão em que será apresentado o programa Trainees (completos com testemunhos em primeira pessoa) e em que serão realizadas algumas apresentações.

 

Há duas que estão a cargo do SAPO:

 

15:00 - Como funcionam as entrevistas técnicas (por José Castro)

 

15:30 - Como funciona o mundo da Publicidade Digital (por João Pedro Gonçalves)

 

O evento será semelhante ao realizado no IST no passado dia 21 de Abril.



publicado por jac às 12:19
link do post | comentar | ver comentários (1) | adicionar aos favoritos |

Segunda-feira, 8 de Fevereiro de 2010

Antes ainda de analisarmos o problema do chmod e as suas múltiplas soluções, eis um problema relativamente simples de SQL.

 

Tomemos como exemplo a seguinte tabela, onde anotamos quanto dinheiro emprestamos a cada pessoa, sendo que já emprestamos dinheiro mais que uma vez a algumas pessoas:

 

| nome | valor |
|--------------|
| josé  | 20   |
| joão  | 10   |
| rui   | 5    |
| pedro | 3    |
| josé  | 5    |
| pedro | 10   |
| luís  | 25   |
|--------------|

 

Tendo por base esta tabela, o problema consiste em escrever várias queries SQL para:

Para quem quiser tentar responder a este problema sugere-se a criação da tabela e o teste das queries no computador.



publicado por jac às 10:00
link do post | comentar | ver comentários (4) | adicionar aos favoritos |

Segunda-feira, 1 de Fevereiro de 2010

Tipicamente as entrevistas no SAPO seguem o caminho que mais conforto dá ao candidato.


Se a pessoa trabalhou mais com determinada tecnologia, é esse o assunto que vamos abordar.


Se a pessoa passou mais tempo a realizar um tipo de tarefa, é essa a informação que vamos procurar.


Quando um candidato nos afirma que se sente muito confortável em ambientes Linux e, numa escala de 0 a 1, classifica a sua proficiência como um 0.9, por exemplo, este é um exercício que colocámos bastantes vezes no ano passado:


"Encontras-te sozinho num Data Center e tens que resolver este problema sem recurso a meios exteriores (nada de telemóvel, nada de internet; o objectivo é resolveres tu o problema). Tens um servidor que não pode ir abaixo. Nessa máquina, alguém teve a brilhante ideia de executar um `chmod -x chmod`. Resolve o problema."


Brevemente discutiremos o que se pretende com um problema deste género e algumas das respostas que fomos juntando durante o ano, quer nas entrevistas, quer no seio da nossa equipa.



publicado por jac às 10:00
link do post | comentar | ver comentários (8) | adicionar aos favoritos |

Segunda-feira, 11 de Janeiro de 2010

Recentemente colocámos neste blog um post com um dos problemas que usamos em muitas das entrevistas de 2009 no SAPO.

O problema consistia em desenhar (escrever) um algoritmo para resolver o seguinte problema, em pseudo-código:

    "Vais receber uma lista de números. Encontra a maior diferença entre quaisquer dois números nessa lista."

Hoje vamos analisar algumas das soluções com que nos deparámos nas entrevistas.

Estranhamente, uma solução que é apresentada com frequência é a seguinte:

    maior_diferenca = 0;

    for ( i = 1 ; i < length lista ; i++ ) {
        if ( lista[i] - lista[i-1] > maior_diferenca ) {
            maior_diferenca = lista[i] - lista[i-1];
        }
    }

    return maior_diferenca;

Esta é uma solução que não apresenta o resultado correcto e que demonstra uma série de problemas no raciocínio do candidato (problemas esses que não iremos abordar aqui, mas é de facto uma situação comum).

Eis a solução mais básica que poderia ser apresentada (seguindo-se a lista de problemas que a mesma apresenta):

    maior_diferenca = 0;

    for ( i = 0 ; i < length lista ; i++ ) {
        for ( j = 0 ; j < length lista ; j++ ) {
            if ( abs( lista[i] - lista[j] > maior_diferenca ) ) {
                maior_diferenca = abs( lista[i] - lista[j] );
            }
        }
    }

    return maior_diferenca;

Problemas de eficiência:

 


Erros e corner-cases:


Vejamos agora a mesma solução já com alguns destes problemas resolvidos:

    maior_diferenca = 0;

    tamanho = length lista;

    for ( i = 0 ; i < tamanho ; i++ ) {
        for ( j = i+1 ; j < tamanho ; j++ ) {
            diferenca = abs( lista[i] - lista[j] );
            if ( diferenca_actual > maior_diferenca ) ) {
                maior_diferenca = diferenca_actual;
            }
        }
    }

    return maior_diferenca;

Apesar de esta solução ainda não estar a prever os casos da lista vazia ou da lista com um único elemento, esta já é uma solução mais eficiente que a anterior.

Ainda assim, um bom candidato consegue, desde o início, compreender que não necessita realizar tantas operações, já que lhe basta encontrar o maior e o menor elemento da lista e calcular a diferença entre dois.

Infelizmente, isto faz com que alguns candidatos apresentem uma solução semelhante à seguinte:

    lista = sort  lista;
    max   = last  lista;
    min   = first lista;
    return max - min;

Apesar da solução estar correcta, não é de todo eficaz, dada a complexidade de um sort numa lista com, por exemplo, 20,000 valores.

Eis uma outra solução seguindo esta ideia, ainda com alguns problemas:

    min = 0;
    max = 0;

    for ( i = 0; i < tamanho; i++ ) {
        if ( lista[i] < min ) {
            min = lista[i];
        }

        if ( lista[i] > max ) {
            max = lista[i];
        }
    }

    return max - min;

Esta é uma solução que não funciona, uma vez que basta que todos os números sejam positivos ou negativos para retornar o valor errado.

Uma melhor solução seria algo no seguinte sentido:

    min = null;
    max = null;

    for ( i = 0; i < tamanho; i++ ) {
        if ( min == null or lista[i] < min ) {
            min = lista[i];
        }

        if ( max == null or lista[i] > max ) {
            max = lista[i];
        }
    }

    if ( min != null and max != null ) {
        return max - min;
    }
    else {
        # ...
    }

Entre todas estas versões, há ainda mais uma série de variantes que outros candidatos apresentam.

Há também questões específicas de cada linguagem que podem fazer com que pequenas partes devam ser alteradas por uma questão de eficiência.

Ao ser confrontado com este problema, o candidato ideal:

 

Convém ainda deixar claro que este é apenas um problema que fez parte de um grande conjunto de desafios colocados aos candidatos e que não é apenas a resolução de um simples problema que dita o recrutamento ou não da pessoa.



publicado por jac às 10:00
link do post | comentar | ver comentários (10) | adicionar aos favoritos |

Terça-feira, 3 de Novembro de 2009

A título da SAPO Session desta semana, em que abordaremos o tema do recrutamento, divulgamos hoje um dos problemas que foi usado em muitas das entrevistas técnicas que realizamos este ano.

 

O objectivo é que o candidato escreva, em papel, um algoritmo para soluccionar o seguinte problema:

 

"Vais receber uma lista de números. Encontra a maior diferença entre quaisquer dois números nessa lista."

 

É suposto o algoritmo ser escrito em pseudo-código. Não é de todo necessário que o mesmo compile, mas é necessário que se consiga ler e perceber.

 

Este é um problema com muitas nuances que serão explicadas num outro post a ser publicado muito em breve, logo depois de darmos uns dias para que todos possam preparar a sua solução.

 

De notar que é esperado que o problema seja resolvido em menos de cinco minutos, e não no decorrer de vários dias de estudo e optimização.

 

Fica a sugestão aos leitores: resolva o problema, em papel. Aquando da publicação da solução, compare a sua com a esperada.



publicado por jac às 08:55
link do post | comentar | ver comentários (16) | adicionar aos favoritos |


Autores
pesquisar
 
Janeiro 2012
Dom
Seg
Ter
Qua
Qui
Sex
Sab

1
2
3
4
5
6
7

8
9
10
11
12
13
14

15
16
17
18
19
20
21

22
23
24
25
26
27
28

29
30
31



follow saposessions at http://twitter.com
posts recentes

chmod -x chmod

SQL nas entrevistas

PT na FEUP

Problemas de SQL

chmod

Encontrar a maior diferen...

Algoritmia e entrevistas

arquivos

Janeiro 2012

Dezembro 2011

Outubro 2011

Setembro 2011

Agosto 2011

Julho 2011

Junho 2011

Maio 2011

Abril 2011

Março 2011

Janeiro 2011

Outubro 2010

Setembro 2010

Agosto 2010

Julho 2010

Junho 2010

Maio 2010

Abril 2010

Março 2010

Fevereiro 2010

Janeiro 2010

Dezembro 2009

Novembro 2009

Outubro 2009

Setembro 2009

Agosto 2009

Julho 2009

Junho 2009

Maio 2009

Abril 2009

Março 2009

Fevereiro 2009

tags

todas as tags

últ. comentários
Boas, Apesar deste post já ser um pouco antigo gos...
Por sinal já foi desenvolvido e encontra-se neste ...
A informação que faltava está agora aqui: http://d...
A informação já está aqui: http://developers.blogs...
Boas,Onde é que isto vai ser? Há algum critério pa...
blogs SAPO
subscrever feeds