Taverna /dev/All

Fizz Buzz - simples mesmo? - a volta do meu canal

Resolvi colocar no meu canal uma série de vídeos sobre alguns conceitos básicos de computação e alguns algoritmos e estruturas de dados que me fascinam há anos é ante acho melhor descritos em vídeo.

Aí resolvi começar pela pergunta mais batida em provas técnicas: o fizz buzz. Aquele problema que 90% não consegue resolver de cara.

Na descrição do vídeo tem alguns links sobre o assunto. Segue o primeiro vídeo da série.

Coloca o link do canal aí :slight_smile:
Legal o vídeo, mas eu tenho um questionamento. Pergunto-me (isso soa horrível, o correto devia ser “me pergunto”) até que ponto as pessoas deixam passar as soluções mais simples devido à pressão de estar fazendo uma prova. Existe o fator tempo e existe aquele fator psicológico capaz de provocar os famosos “brancos” até em coisas que a pessoa saberia resolver em uma situação corriqueira. Não negando que esse fator pode ser derivado das pessoas não se sentirem seguras com o conteúdo, mas tem o fator do tipo “não posso falhar”, a pressão do tempo que algum outro problema mais difícil te consumiu, etc.
Eu mesmo já saí de inúmeras provas pensando aquele “puuuuuuuuuuuuuuuuutz, FizzBozzta (cara de vergonha)” ao reavaliar algumas coisas, mesmo fáceis.

Valeu!

Não há dúvida quanto a isto: galera realmente fica muito tensa na hora e acaba esquecendo até o próprio nome.

Mas aí entra a pergunta cruel: se a pessoa se embanana neste tipo de coisa, como vai ser no dia a dia onde questões realmente tensas acontecem e tem potencial pra gerarem prejuízos reais?

O endereço do canal é https://youtube.com/kicolobo

São situações diferentes: em um caso temos um problema trivial e inofensivo a ser resolvido em uma circunstância de alta pressão, como um teste para emprego. Em outras, o problema não é trivial ou inofensivo mas a pressão pode variar.
O meu ponto é como o funcionamento da cabeça das pessoas reage a estes tipos de situações. Idealmente, aguentaríamos pressão máxima como robôs, mas no mundo real nos atrapalhamos, nos cansamos, começamos em algum momento a fazer coisas que não faríamos em estado normal.
Considero que a receita para o desastre é juntar problemas complexos e com potencial de causar prejuízos a circunstâncias de altíssima pressão. Muitas firmas fazem isso, falham e a culpa é de quem não deu conta. Se o problema pode causar uma guerra nuclear, é melhor pensar nele de forma estratégica e não trabalhar reativamente aos rápidos ventos do mercado.

será que são situações tão diferentes assim sob o ponto de vista do indivíduo, que é o que realmente interessa em uma avaliação?

Pensa comigo: no primeiro caso, apesar do problema ser trivial para o mundo externo, não é nada trivial para quem realiza a prova. E há consequências aqui: você pode não conseguir o emprego que queria.

No outro caso, um problema não trivial mas cuja pressão pode variar. Mesma coisa: você pode gerar consequências para si mesmo (dependendo da situação) ou para o seu cliente.

O teste técnico então acaba que chega ao ponto de simular o mundo real, o que é válido: você não vai contratar alguém que sofre um breakdown em um teste técnico, contrataria?

mas a vida é assim, não? É importante lembrar que você não deixa a pessoa sob pressão o tempo inteiro, muitas vezes ela é que se coloca nesta posição (soa cruel isto). Explico melhor: concorda comigo que se você está bem preparado, lidar com situações críticas vai ficando mais simples e, consequentemente, a pressão é reduzida? Então não tem como: você tem de se preparar.

O caso do Fizz Buzz mostra bem um aspecto da personalidade do candidato que é ignorado: “a pessoa curte ler sobre problemas técnicos a serem resolvidos?”. Por que se curte, se se distrai com isto, mostra já de cara um processo de preparação que deveria - em teoria - não gerar um breakdown em uma prova.

Aí são empresas que não tem maturidade alguma: por que a falha nunca (ou quase) é consequência da ação de um único indivíduo. Aquela velha história: “ninguém larga a mão de ninguém” tem de ser aplicado no trabalho também.

Jamais questionaria a necessidade de estar bem preparado, e concordo que a pressão diminua conforme o preparo. Os breakdowns são em grande parte resultado da falta de segurança da pessoa com relação ao assunto em que vai ser avaliada.

Mas não acho que seja só isso. O ponto que toquei é quando pessoas, mesmo bem preparadas, deixam passar detalhes simples em situações de alta pressão - quem nunca? Quando o relógio está sorrindo você é um, quando o relógio começa a fazer cara feia e bater o pé, você é outro. Mesmo que você tenha feito bem a maior parte da prova, às vezes alguma coisa ali te consumiu o tempo e você começa a se apressar, lembrando que aquilo é decisivo para você, e assim é possível que algum detalhe besta vá escapar.

O FizzBuzz tem uma aparência de pegadinha para quem está sob a pressão do tempo, pois é formulado (provavelmente de propósito) com o caso mais abrangente ao final. Se for assim, ele é feito para provocar breakdowns, fazer o quê? Lembro de já ter lido sobre ele no seu blog, naquele momento eu o resolvi mentalmente numa boa, afinal não estava fazendo prova. Eu certamente não cairei nessa pegadinha por estar vacinado agora, mas não posso dizer que nunca mais cairia em alguma.

Sobre situação “diferente” que mencionei, pode ser que não tenha detalhado o suficiente o que quis dizer. Em todo trabalho “sério” existe uma pressão intrínseca, ligada às consequências se se fazê-lo errado, mal-feito ou estourando o prazo. E existe a pressão gerada externamente, tanto pela falta de preparo da pessoa, que não adquiriu a manha de pesquisar, fazer experimentações, querer entender as ferramentas e o problema a fundo, quanto pelas políticas da empresa, que muitas vezes assume demandas além de sua capacidade, possui um gerente que fica de meia em meia hora perguntando “tá pronto?”, não admite repriorizar as coisas quando alguma requer atenção maior. Em qual desses ambientes o trabalho com potencial de gerar problemas, vai gerar com mais probabilidade?

Em resumo, o FizzBuzz possui potencial maior de causar problemas em uma prova (para quem está fazendo e quer o emprego) não apenas pela falta de preparo de quem está fazendo em lógica em programação (que é uma causa, não discuto), mas também porque é colocado de forma a gerar pressão extra em uma circunstância que já é de alta pressão, que não tem nada a ver com o FizzBuzz em si.

Desculpa se eu escrevo demais, eu vim para cá aliviar um pouco a pressão dos meus trabalhos para não fazer cagada com coisas bestas :slight_smile:

1 Curtida

Kkkkk, pelo contrário, acho que seus pontos são ótimos.

No caso do fizz buzz o objetivo até onde sei não é gerar pressão, mas só val mudar se a pessoa tem raciocínio algoritmico mínimo. E o interessante (É daí a polêmica dele na época) é que a maior parte das pessoas saindo da graduação ou pós-graduação trem multa dificuldade em resolver um problema relativamente simples.

Kico,

Parabéns pela iniciativa!

Em relação ao vídeo do FizzBuzz, eu só não concordo lá muito com a suposta melhoria da sua segunda solução em relação à primeira.

Li recentemente o livro 99 Bottles of OOP da Sandi Metz e Katrina Owens e o livro é bem interessante porque desmistifica a “boa” solução que nós programadores tendemos a criar.

Nele as autoras nos convidam a criar uma solução nós mesmos e depois tentam mostrar que a solução delas é mais simples e mais fácil de ser mantida (em comparação com a nossa e outras soluções alternativas que elas mesmo inventaram) usando argumentos mais objetivos (porque não dá pra ser 100% objetivo em nada), com ferramentas que podemos utilizar para analisar o código visando métricas como a complexidade ciclomática & cia.

A sua primeira solução com os três if-else talvez fosse boa o suficiente e mais fácil de ser mantida. A complexidade ciclomática das duas soluções é 4 - olhando rapidamente, posso estar equivocado - mas a segunda introduz algo mais complexo e que dificulta a nossa vida e é a causa de muitos bugs, que é o tal do estado mutável, com a concatenação e reutilização da mesma variável.

Claro que se trata do FizzBuzz e esse tipo de discussão pode nem ter lugar aí, já que o assunto principal do post é que a maioria dos programadores não consegue construir nem uma solução chulé, mas é que ando praticando bastante o TDD e noto que o lado bom do TDD é que ele, quando aplicado corretamente, nos força a buscar a solução mais enxuta, sem desperdício, diminuindo o custo de manutenção do código. O TDD inclusive, infelizmente, quase nunca nem dá as caras nesse tipo de entrevista técnica.

O livro dá o exemplo e mostra como usar a refatoração para melhorar o código quando a demanda chega, antes de tentar antecipar problemas futuros e que podem não acontecer nunca, levando a produção de código desnecessário, aumentando o custo de manutenção.

Abraço!

PS: Vídeo sobre a complexidade acidental & TDD: https://www.youtube.com/watch?v=WSes_PexXcA

1 Curtida

Fala Pedro!

Vou buscar este livro, não conhecia, vou comprar!

Neste caso do FizzBuzz não creio que o estado seria algo tão complexo e problemático (você me falando sobre estado me faz lembrar deste livro: Structure and Interpretation of Computer Programs (que é gratuito e pode ser baixado aqui: https://web.mit.edu/alexmv/6.037/sicp.pdf)) por que ele é muito próximo e limitado em seu escopo (a iteração do loop).

(sobre estado, este é um dos fatores que me faz ter um pé atrás com a OOP em si, o que daria uma discussão massa - na realidade, já existe, tá neste link aqui da Taverna - Orientação a objetos - será realmente tão boa assim?)

E fica mais fácil de manter por que você na realidade além de ter um número muito menor de linhas, também tem um número menor de pontos de alteração (2 variáveis ao invés das n), mas é como disse: FizzBuzz é um destes problemas que, apesar de bobo, possibilita uma infinidade de soluções possíveis pro mesmo problema, e é justamente aí que mora toda a graça da programação.

ps: eu já estou com outro problema que vai virar vídeo provavelmente hoje

É… Realmente essa conversa pode ser meio overkill pro pobre do FizzBuzz :slight_smile:

E é impressionante como um probleminha bobo pode ter tantas soluções e gerar tanta discussão.
Nem acreditei quando vi as estatísticas em relação ao uso dele em entrevistas (acho que em um post do blog Coding Horror)

Voltando à solução, realmente ter um número menor de linhas conta bem a favor!

Mas além disso tudo ainda tem a questão do método fazer duas coisas em vez de uma só reponsabilidade, como o side-effect de imprimir ao mesmo tempo que calcula. Isso pode ser resolvido extraindo o método que só monta a String, tornando a função pura e fácil de testar.
Já a questão do estado poderia ser atenuada ou resolvida removendo a concatenação de Strings com a extração das constantes FIZZ (em vez da literal “Fizz”) e BUZZ (em vez de “Buzz”), fazendo com que, pelo menos com compiladores (tô pensando em Java agora) que otimizam bem o código, a concatenação de constantes como FIZZ + BUZZ ocorra em “tempo de compilação”.

No fundo ainda isso tudo é subjetivo… Cada programador vai encontrar uma solução diferente
No final das contas a gente tem que lidar com os trade-offs de uma alternativa ou de outra.

Já a questão do TDD lida com algo que é muito interessante que é mudar a nossa maneira de pensar, ou o “mindset”. Ao escrever código para fazer com que o teste fique verde, devemos usar menos fosfato e evitar criar soluções super-inteligentes, evitando a complexidade acidental que tende a aparecer com nossas “ideias geniais”. Evita antecipar problemas que não existem e podem nunca existir. Ao refatorar o código já verde, aí sim usamos a nossa mente, mas pra resolver problemas mais específicos, como remover duplicidade e tornar o código mais fácil de ser mantido. Ou seja: aí pensamos somente em uma coisa sem nos preocuparmos com outras coisas até mais “mundanas”, como se o código tem bug e se a feature básica está pronta ou não (garantidas com os testes que vamos acumulando).

Por isso, quando vi o vídeo pensei que a sua primeira solução, que foi a mais rápida de fazer, fosse a mais desejável

Às vezes o que sai da nossa mente de primeira, a coisa mais simples, pode ser a melhor solução mesmo… (e claro: dá pra pensar em mil exceções e desdobramentos)

Obs: SICP! Tive que começar a ler umas três vezes até entender de verdade a otimização à la tail-recursion sem gastar espaço, que é um conceito alienígena pra quem tá acostumado com Java e o acúmulo de stacks usando recursão.

dá pra ver claramente que TDD tá sendo seu tema nos últimos tempos por este trecho aqui. :smiley:

itexto