segunda-feira, 1 de setembro de 2008

Você é um dos melhores?

Como citei em um post anterior, 80 % das pessoas se considera dentro dos 10 % melhores (veja Oba, sou chefe! E agora?).
Quando perguntamos a um “programador” se ele tem boa lógica e se sabe programar bem, a resposta é sempre positiva. Mas quantos passariam em um teste?

Criei o desenho abaixo como brincadeira, mas “baseado” em fatos reais. Conheci alguns programadores que quando confrontados com testes bastante simples não tinham nem idéia por onde começar. Alguns, mesmo dando os passos iniciais, que para qualquer um que realmente tivesse condições de ser programador medíocre seria o bastante para desenvolver a solução, nem assim eles conseguiam. E se julgavam programadores e provavelmente até hoje estejam por aí, criando algum monstro.

Os programadores testados não percebem que a estrela de madeira não pertence ao brinquedo de plástico.

Um dos testes bem simples que aplico algumas vezes é assim:
Criar uma função que receba três strings que podem estar preenchidas ou não, independentes uma da outra, ou seja, ou todas podem estar vazias, ou apenas uma preenchida (não necessariamente a primeira) , ou duas, ou as três. Você deve retornar uma string com a soma das três strings, sendo que o texto em cada string deve ser separado do outro por uma vírgula. Mas atenção, quando a string estiver vazia, ela deverá ser desconsiderada.
Exemplos:
“”, “”, “” => “”
“”, “segunda”, “” => “segunda”
“primeira”, “”, “terceira” => “primeira, terceira”
“primeira”, “segunda”, “terceira” => “primeira, segunda , terceira”

Se você entendeu este teste e sabe exatamente como fazer, parabéns, mas alguns passaram mais de 2 horas tentando resolver e ... nada. Um chegou a passar dois dias tentando, e eu pedi para ele fazer outra coisa para mim. Este era ótimo em tarefas repetitivas, onde não era preciso pensar, e para isso ele se pagava. Pessoa extremamente prestativa, mas que, de modo algum, poderia se considerar programador.

Pare agora e tente resolver você. Depois veja algumas soluções abaixo, feitas em VB por ser uma linguagem de fácil entendimento por programadores de qualquer linguagem.

Solução 1:
Function Soma(ByVal Primeira As String, _
        ByVal Segunda As String, _
        ByVal Terceira As String) As String
  Dim Retorno As String
  Retorno = Primeira
  If Segunda <> "" Then
    If Retorno <> "" Then Retorno = Retorno + ", "
    Retorno = Retorno + Segunda
  End If
  If Terceira <> "" Then
    If Retorno <> "" Then Retorno = Retorno + ", "
    Retorno = Retorno + Terceira
  End If
  Soma = Retorno
End Function


Solução 2:
Function Soma(ByVal Primeira As String, _
        ByVal Segunda As String, _
        ByVal Terceira As String) As String
  Soma = SomaAux(SomaAux(Primeira, Segunda), Terceira)
End Function
Function SomaAux(ByVal Atual As String, ByVal Nova) As String
  If Nova <> "" Then
    If Atual <> "" Then Atual = Atual + ", "
    Atual = Atual + Nova
  End If
  SomaAux = Atual
End Function

Solução 3:
Function Soma(ByVal Primeira As String, _
        ByVal Segunda As String, _
        ByVal Terceira As String) As String
  Dim Retorno As String
  If Primeira <> "" And Segunda <> "" Then
    Retorno = Primeira + ", " + Segunda
  Else
    Retorno = Primeira + Segunda
  End If
  If Retorno <> "" And Terceira <> "" Then
    Retorno = Retorno + ", " + Terceira
  Else
    Retorno = Retorno + Terceira
  End If
  Soma = Retorno
End Function


Você tem outra solução? Comente!

Outro dia, vi um teste de empresa para programador .Net e fiquei confuso com o que eles pretendiam com aquele tipo de pergunta. Eram questionamentos muito técnicos, como a sintaxe do comando tal, o nome do arquivo da configuração tal, o tipo de tal e assim por diante, em resumo, nada sobre lógica de programação. Parecia teste para ver se a pessoa tinha boa memória e se havia estudado, mas não se seria um bom programador ou analista. Este tipo de pergunta, qualquer um poderia buscar no Google, mas lógica, isto a pessoa tem que ter, pois não tem no Google. Este mesmo teste tinha também algumas perguntas de SQL e estas sim, eram sobre conhecimento e lógica, como solicitação para montar comandos razoavelmente complexos.

Outra empresa, tem (ou tinha) um teste para programador que apresentavam um problema onde este deveria ser resolvido com um programa na linguagem Clipper. No teste, dizia que a sintaxe na importava, apenas a lógica. Teste perfeito, pois saber a sintaxe de um comando é coisa de 5 minutos (ou menos) para achar, mas lógica, nem uma vida inteira é suficiente para algumas pessoas. O que eu verifiquei neste teste é algo que até hoje tenho dúvida: Por que será que os melhores eram os que digitavam mais rápido? Será que os que digitavam lentamente não estavam conseguindo pensar direito? Tantas dúvidas, mas esta constatação: Os melhores digitavam rápida e ininterruptamente.

Essa avaliação de quantidade de toques e capacidade de lógica me parece bastante ligada, pois os melhores que conheci digitavam com grande velocidade e quase que o tempo todo. Os “Caras”, aqueles que se acham, digitam algumas letras, param, pensam (ou algo parecido), digitam mais algumas. Somente são rápidos nas teclas durante os joguinhos, neste eles são os bons. Os “Caras” digitando parecem gagos tentando discursar.

A grande maioria das empresas não testa nada, confia que se a pessoa diz que é programador, é o que basta. Pergunto-te, meu leitor, na sua empresa, quantos ficariam se hoje fosse aplicado um teste de lógica ou de conhecimento do sistema em que trabalham?

Você concorda que os melhores podem ser identificados pelo modo que digitam? Comente!

5 comentários:

Anônimo disse...

Function Concatena(ByVal s1 As String, ByVal s2 As String, ByVal s3 As String) As String
Dim r As String

r= replace(trim(s + ', ' + s2 + ', ' + s3),',,')

if mid(r,1,1)=',' then
r = mid(r,2)

if mid(r,len(r)-1,1)=',' then
r = mid(r,1,len(r)-1)

Concatena = r
End Function

Se nao me falha a memoria isso deve resolver. Claro, contando que nao venha virgula nas strings... Visto que era pra ser uma solucao simples.

Legal o blog!

Roberto disse...

DNS, muito boa solução. Fiz pequenos ajustes para corrigir alguns detalhes. Ficou assim:

Function Concatena(s1, s2, s3) As String
Dim r As String
r = Replace(s1 + ", " + s2 + ", " + s3, ", , ", ", ")
If Left(r, 2) = ", " Then
r = Mid(r, 3)
End If
If Right(r, 2) = ", " Then
r = Mid(r, 1, Len(r) - 2)
End If
Concatena = r
End Function

Mas como a minha preocupação maior é com a manutenção, ficaria com receio se um dia fossem 4 parâmetros? O programador que fosse alterar, se não fosse muito atento e não testasse bem, geraria um erro. Se apenas alterasse a linha:
r = Replace(s1 + ", " + s2 + ", " + s3 + ", " + s4, ", , ", ", ")
aparentemente estaria correto. Mas em algumas situações, pau.

Se você reparar nas soluções apresentadas, todas são facilmente extensíveis para mais parâmetros, com simples Ctrl+C e Ctrl+V. Tem mais código, mas estão mais seguras quanto a futuros erros e fáceis de entender.

Com meus exemplos, quis apresentar algumas respostas aceitáveis, mas a minha escolha seria a rotina abaixo, por ser a mais fácil de estender (veja que estou com 5 parâmetros):
Function Concatena(s1, s2, s3, s4, s5) As String
Dim v()
Dim r As String
Dim x As Integer
v = Array(s1, s2, s3, s4, s5)
For x = 0 To UBound(v)
If v(x) <> "" Then
r = r + ", " + v(x)
End If
Next
Concatena = Mid(r, 3)
End Function

Ela é curta, simples, fácil de entender e de estender.

Unknown disse...

Concordo com a tua colocação. Existem muitos que se dizem programadores, que conhecem várias linguagens, mas no momento de fazerem alguma coisa que exige raciocínio todo o conhecimento que dizem ter foi por agua abaixo! Na minha empresa, eu costumo utilizar um teste para medir o raciocinio lógico do programador. Divido este teste em 3 partes, uma parte relacionada a perguntas e testes de lógica, alguns problemas de programação, os quais podem ser escritos em qualquer linguagem, inclusive algoritmo e algumas consultas de SQL. Graças a este teste sempre consegui selecionar programadores que possuiam uma lógica razoavelmente boa, nunca tendo errado. Em contra partida, durante o tempo que me ausentei da empresa e foi necessário contratar outros programadores, o teste não foi aplicado e o resultado não foi dos melhores.
Agora, algo que eu nunca prestei atenção foi a relação entre a velocidade da digitação do código e a capacidade de raciocinio. Algo que eu posso afirmar é que quem possui capacidade de raciocinio consegue resolver um problema de forma mais rápida do quem não possui raciocínio, pois estes, acabam se dispersando, saindo para tomar café, para "pensar" na solução até conseguirem resolver o dito problema. Já presenciei casos onde o programador criou uma variavel e não sabia dizer para que servia....É F...isso, mas existe.
Abraço

Unknown disse...

Public Function soma_string(Optional string1, Optional string2, Optional string3)
If Trim(string1) <> "" Then string1 = string1 & ","
If Trim(string2) <> "" Then string2 = string2 & ","
If Trim(string3) <> "" Then string3 = string3 & ","
somastring = Trim(string1) & Trim(string2) & Trim(string3)
If Right(somastring, 1) = "," Then somastring = Left(somastring, Len(somastring) - 1)
soma_string = somastring
End Function

Roberto disse...

Alexandre,

É legal ver que um requisito tem inúmeras soluções possíveis. Bem interessante a tua rotina, mas na minha experiência de mais de 20 anos, aprendi a atalhar, então, se você me permite, dei uma alterada nela. Veja como ficou:

Public Function Concatena(string1, string2, string3)
  If Trim(string1) <> "" Then string1 = ", " & Trim(string1)
  If Trim(string2) <> "" Then string2 = ", " & Trim(string2)
  If Trim(string3) <> "" Then string3 = ", " & Trim(string3)
  Concatena = Mid(string1 & string2 & string3, 3)
End Function

Baseado nela, melhorei um pouco mais, veja:

Public Function Concatena(string1, string2, string3)
  Concatena = Mid(Concatena_Virgula(string1) & Concatena_Virgula(string2) & Concatena_Virgula(string3), 3)
End Function
Public Function Concatena_Virgula(strTexto) As String
  If Trim(strTexto) <> "" Then
    Concatena_Virgula = ", " & Trim(strTexto)
  Else
    Concatena_Virgula = strTexto
  End If
End Function