Executando verificação de segurança...
18

Aprendizado Superficial: falhei em uma entrevista por não ter lido um livro

Um relato sobre um dos meus processos seletivos, o feedback que recebi dos avaliadores e como isso me fez questionar meu método de aprendizado.

A entrevista

Recentemente, participei de um processo seletivo para uma das grandes empresas de e-commerce do mercado brasileiro. Foi a minha primeira experiência com uma entrevista técnica envolvendo pair programming e system design, então eu estava um pouco nervoso. Porém, conforme a entrevista foi passando, fui me sentindo mais confiante, e as respostas foram saindo com mais naturalidade.

O ponto alto da entrevista, para mim, foi justamente na parte teórica sobre os pilares da orientação a objetos e sobre SOLID. Eu havia lido diversos materiais na internet, então estava bastante confiante em responder a todas as perguntas.

Ao final da entrevista, eu não estava 100% satisfeito. Havia cometido alguns erros na parte de system design e tinha consciência disso, por isso já esperava a reprovação — que de fato veio.

Feedback e surpresa

O que mais me surpreendeu, então, não foi a recusa, mas sim o motivo fornecido no e-mail, que dizia que o candidato (eu mesmo) precisava melhorar, entre outras coisas, o "domínio sobre os princípios SOLID".

Eu havia estudado muito. Todos os conteúdos que li na internet, absorvi; não apenas decorei, mas entendi o que cada um deles dizia e como aplicar nos projetos. Então eu não conseguia entender.

Foi aí que decidi me aprofundar no assunto e ir diretamente a uma das melhores fontes de conhecimento que temos disponível há séculos: livros. Adquiri o livro Arquitetura Limpa: o Guia do Artesão Para Estrutura e Design de Software e o devorei de ponta a ponta.

O conteúdo do livro x o conteúdo de artigos da internet

Enquanto eu lia os capítulos 7 a 11 do livro, que falam sobre os princípios SOLID, uma coisa me saltou aos olhos: a explicação do autor é totalmente diferente das explicações que li na internet!

Ao ler o capítulo 7 — SRP: The Single Responsibility Principle — me lembrei da minha entrevista, das perguntas feitas e das respostas que dei. Ficou claro para mim onde errei.

No artigo The S.O.L.I.D Principles in Pictures, o seguinte exemplo é dado para o princípio S (Single Responsibility):

A class should have a single responsibility: If a Class has many responsibilities, it increases the possibility of bugs because making changes to one of its responsibilities could affect the other ones without you knowing.

Não está errado: uma classe deve ter apenas uma responsabilidade e, ao alterá-la, o comportamento não pode impactar outros componentes do código.

Vamos ver agora a explicação do Uncle Bob em seu livro?

A module should be responsible to one, and only one, actor. — Página 65, Robert C. Martin, Clean Architecture

Isso muda tudo, porque não estamos mais falando de classes, estamos falando de atores. Não estamos construindo nosso sistema com base nas funcionalidades do código, mas sim com base nas nuances daqueles que vão utilizá-lo — os atores.

Isso me leva de volta à minha entrevista e a uma das perguntas feitas:

A pergunta sobre single responsibility

Imagine que você possui uma classe com a responsabilidade de enviar e-mails, que recebe uma String com o template do e-mail que deseja enviar e expõe esse comportamento por meio de um Controller REST. Esse endpoint é utilizado pelo departamento de RH para o envio de e-mails. Recentemente, o departamento de marketing sentiu a necessidade de enviar e-mails; eles já têm o template e precisam apenas de um endpoint para fazer o envio.
A pergunta é: se o departamento de marketing utilizar o mesmo endpoint, estamos ferindo o princípio SOLID?

Respondi que "Não, afinal a classe ainda possui apenas uma responsabilidade: enviar e-mail."

Minha resposta, percebo agora, não foi satisfatória. Isso porque, de acordo com a primeira definição que estudei — e era a que eu conhecia até então —, dizia apenas que se uma classe tem muitas responsabilidades, a chance de criarmos bugs ao alterar uma funcionalidade e outra ser afetada ao mesmo tempo é grande.

Novamente, não está errado.

Mas veja como, no cenário da pergunta apresentada na entrevista, a definição do Uncle Bob deixa a resposta muito mais clara: SIM!
Dois departamentos diferentes são atores diferentes, e utilizar o mesmo endpoint fere gravemente o primeiro princípio de SOLID.

O que deveríamos fazer então? Criar um novo endpoint especificamente para o departamento de marketing.

Isso, é claro, geraria bastante código duplicado — mas isso é tema para outro capítulo do livro (SYMPTOM 1: ACCIDENTAL DUPLICATION, páginas 65–66).

Outros artigos na internet trazem o mesmo senso que, não digo que está errado, mas para um iniciante no assunto pode trazer um entendimento completamente diferente daquele que é, de fato, a proposta do princípio SOLID descrito no livro de Robert C. Martin.

Vejamos o exemplo dado em A Solid Guide to SOLID Principles:

Awesome. Not only have we developed a class that relieves the Book of its printing duties, but we can also leverage our BookPrinter class to send our text to other media.
Whether it’s email, logging, or anything else, we have a separate class dedicated to this one concern.

public class BookPrinter {

    // methods for outputting text
    void printTextToConsole(String text){
        // our code for formatting and printing the text
    }

    void printTextToAnotherMedium(String text){
        // code for writing to any other location...
    }
}

O trecho de código apresentado junto com a citação não menciona um ponto importante: quais serão os atores dessas funcionalidades?.
Nós separamos o código, o que certamente vai ajudar na manutenção mas não fica claro quais são os atores das respectivas funcionalidades, o que, ao meu ver, não ajuda o leitor a entender o verdadeiro significado do princípio S de SOLID.

Novamente, não está errado, mas o conteúdo é totalmente diferente do livro.

Um último exemplo SOLID Design Principles Explained: Building Better Software Architecture:

For example, consider an application that takes a collection of shapes—circles and squares—and calculates the sum of the area of all the shapes in the collection.

A citação acompanha um exemplo de código que você pode conferir no artigo original, mas basta dizer aqui que no exemplo os atores em nenhum momento são mencionados no exemplo.

Estamos separando funções de código e não funcionalidades de negócio.

Conclusão

Em algumas comunidades que frequento online sempre vejo a pergunta: vale a pena aprender programação através de livros?.

Acredito que esse post talvez seja a minha pequena contribuição para aqueles que possuem essa dúvida.

Livros são fontes de informação e tal como qualquer outra fonte de informação devemos saber escolher boas fontes; fontes com boa aceitação da comunidade, autores com bom histórico etc. mas se minha opinião vale de alguma coisa deixo ela aqui: leiam livros!

O conteúdo de alguns posts encontrados na internet quase sempre será inferior às 300 páginas escritas por um profissional experiente.

Aviso

  • Aviso 1: Importante deixar claro aqui que não sou contrário a ler posts para se informar e acredito que eles contribuem bastante para o nosso aprendizado. O que trago aqui em formato de opinião é que, livros são fontes ricas de um conhecimento aprofundado e trará novas formas de pensar e novas ferramentas para trabalhar que muitas vezes não encontramos em postagens rápidas com apenas 10 parágrafos
  • Aviso 2: Se você precisa de uma informação pontual é claro que uma postagem de fácil leitura é preferível a um livro de 300 páginas, apenas tome cuidado com a fonte da sua informação.
  • Aviso 3: Você não precisa se apegar a apenas uma fonte de estudo. De fato no livro The Pragmatic Programmer: From Journeyman to Master o autor deixa uma dica importante: diversifique.
    Leia livros, leia artigos/posts, faça cursos, leia documentação, não se apegue a apenas um meio de aprendizado.
  • Aviso 4: Não desprezem os livros.

Mais publicações no meu blog: https://victor-vn.github.io/

Carregando publicação patrocinada...
3

Falando sobre o tema livros...
Lembro de mês passado estar sem nenhuma ideia de projeto para o trabalho e estava divagando muito em relação a isso.
Parei um tempo e comecei a ler "O Programador Pragmático" (livro que você chegou a citar no final), incrivelmente durante a leitura me deu um mind-blowing relacionado a uma fala que minha supervisora trouxe em uma reunião e que eu vi uma oportunidade de construir um projeto.

Antigamente eu tinha uma rotina certinha de leitura, mas acabei perdendo o hábito. Depois desse caso, voltei a ler com frequência e vejo que minhas ideias e novos conhecimentos têm aflorado com frequência.
Então parto da ideia de que sim, os livros podem te ajudar e muito em relação aos seus estudos e experiências!

2

Minha contrib:

Cara continuando um pouco a discussão, isso vai além dos princípios S.O.L.I.D, não sei se você chegou a entrar neste ponto, mas estes principios estão intimamente ligados ao processo de arquitetar um sistema, dentro deste processo estudamos algo que é chamado lei de Conway, essa lei nos diz que o design de um sistema é influenciado pela estrutura organizacional do grupo que o produz.

O caso que você passou reflete exatamente isso, peguemos pelo seu exemplo, a entidade Email para o ator RH tem um significado, para o ator Marketing significa outra coisa, e por que utilizar de um mesmo endpoint para enviar emails fere diretamente o principio S do S.O.L.I.D ? pq cada ator enxerga a entidade email de maneira diferente, isso implica que as regras de negócio para cada ator é diferente, enquanto a equipe de marketing utilizam de recursos que o email nos fornece, e ve cada email como um novo lead de capitação de clientes, o setor de RH os enxerga como possíveis candidatos, cada processo é diferente um do outro, em termos de objetivos, restrições e resultados.

Sobre a parte de duplicação de código nós entramos em Design, onde podemos utilizar dos principios estabelecidos e amplamente aceitos como Gang of Gour por exemplo para remediar essa questão.

Caso se interesse em aprofundar seus conceitos sobre arquitetura de sistemas recomendo 2 leituras fascinantes:

"Fudamentos de Arquitetura de Software: Uma Abordagem de Engenharia", Neal ford e Mark Richards

"Padrões de Aruitetura de Aplicações Corporativas", Martin Fowler

Ambos os livros nos dão um visão abrangente sobre como um software enterprise é desenvolvido, e sobre como um arquiteto de software deve pensar afim de alcançar seus objetivos.

Bons estudos!!

3

Meus 2 cents extendidos,

Mas aqui acho que a pergunta na entrevista foi capciosa.

Numa situacao real, conversando com os atores e entendendo a especificacao - poderia ficar claro que cada um iria tratar o envio de forma diferente, dai a necessidade de separacao e conformidade SOLID.

Mas a pergunta foi (como apresentada): "dois departamentos diferentes que precisam enviar email, podem usar o mesmo endpoint ?" - ok, ate dou o desconto que um "depende" poderia ser uma resposta mais cuidadosa, mas olhando apenas o cenario estrito da pergunta, nao fica clara a ofensa ao SOLID porque nao ficou claro que cada ator teria uma interpretacao diferente no uso da classe.

Se a espeficacao nao eh clara, pode gerar interpretacoes (e por isso acho que perguntas de entrevistas/testes/etc precisam ser o mais inequivocas possivel).

Meu ponto eh: os principios SOLID fazem sentido ? Sim - mas o uso correto das especificacoes e pleno entendimento da situacao/contexto onde serao aplicados tambem precisa ser atendido.

2

Ai você tem um ponto muito bom, concordo plenamente que a pergunta ficou muito esparsa para o cenário descrito, em um cenário destes tomar o máximo de cuidado possível ao se afirmar algo é pouco rsrs, creio que em casos assim brecha é aberta para que o entrevistado retorne a pergunta ao próprio entrevistador afim de obter informações mais precisas, isso além de te colocar em um resultado provavelmente maior do que a expectativa, demonstra uma capacidade de lidar de forma criativa com situações difíceis, pois com algo tão abstrato assim existe a possibilidade de múltiplos cenários, pois em recurso(endpoint) que é literalmente apenas enviar o e-mail sem uma lógica e objetivos por trás não fere os princípios, pois ficaria algo genérico, mas nesse sentido concordo que fizeram uma questão um tanto capciosa.

2

Olá, pessoal. Obrigado pelas respostas. Com certeza lerei os livros indicados e seguirei os conselhos nas próximas entrevistas.

Durante esta entrevista eu tentei tirar algumas dúvidas acerca da proposta que eles trouxeram, mas acredito que isso não me aproximou da resposta que os entrevistadores queriam. Talvez porque a minha compreensão sobre os princípios que eles estavam questionando era totalmente diferente da deles.

Neste post procurei não focar no processo seletivo, no conteúdo da pergunta ou na minha atuação na entrevista. Acredito que todos estes pontos poderiam ser explorados em outras postagens para abrir o debate.

A pergunta talvez tenha sido capciosa como pontuou o amigo, ou talvez eu não tenha tido maturidade para fazer as pergunta corretas (acredito fortemente que isso influenciou bastante rs) ou ainda os entrevistadores tinham uma convicção daquilo que é correto com base no conhecimento deles e no que eles aplicam no projeto e eu não pude corresponder.

Acho que todas essas reflexões cabem mas o que tentei trazer aqui foi meu espanto com a quantidade de material na internet que, na minha opinião, não tem o rigor técnico que tem um livro (a depender do livro, claro).

Ao ler o livro eu fui exposto a um ponto de vista que não tive em todos os mais de 10 artigos que li do assunto. É quase como se nenhum destes artigos tivessem sido baseados nos livro, ou como se um artigo tivesse "alimentado" o outro, gerando uma rede de informação que não diverge, não apresenta outro ponto de vista e portanto cria um consenso.

O consenso neste caso é de que ao separar duas funcionalidades em classes diferentes você já está atendendo ao princípio S de SOLID. Ao ler o livro do Uncle Bob eu vi que esse consenso não existe, uma outra interpretação do princípio me foi apresentada o que me levou a questionar a qualidade de algumas fontes.

1

A questão sobre a pergunta, vejo que em entrevista devemos responder sempre como na matemática, onde só existe um resultado para a questão.
Já fiz essa bobagem de responder algo baseado em minha experiência e foi burrice.

1
1

Meus 2 cents,

Vou ser um pouco polemico aqui: acredito que entrevistas e testes tem de ser o mais objetivos possivel e com respostas inequivocas - sem pegadinhas ou detalhe nas entrelinhas. (nao precisam ser testes praticos, podem envolver teoria, mas desgosto de respostas que tem de ser escolhidas pela posicao da virgula no enunciado).

Ao longo dos anos tirei algumas dezenas de certificacoes, fiz provas (e apliquei muitas enquanto instrutor e avaliador) - e tenho especial carinho pelas provas de certificacao RHCE/X da RedHat- voce tinha um cenario, diversos desafios e tinha de resolve-los.

Lembro tambem com carinho de uma prova de admissao em Delphi - eram 4 horas para desenvolver um sistema seguindo a especificacao (na epoca todo mundo era fullstack, entao levantar o banco, criar tabelas, fazer o front e as regras de negocio era feijao-com-arroz). Dava trabalho - mas voce sabia o que esperavam como resultado.

Acho importante as orientacoes que Design Patterns, SOLID e Object calisthenics dao para quem esta aprendendo e criando seu repertorio de codigos/solucoes.

Mas principios como YAGNI e KISS tambem ajudam a nao cair na armadilha do over-engineering.

EDIT: Quanto a livros - sim ! Leia o quanto puder, sempre - mas desenvolva o senso critico para nao cair nas arapucas de que certos autores vendem.

Enfim, lamento por nao ter tido sucesso nesta entrevista - espero que em breve voce consiga uma nova posicao. Saude e Sucesso !

-1

Gostei muito do seu artigo, ele coaduna um pouco com o meu que foi postada há uns dias atrás. Eu sempre foco bastante na parte conceitual fundante da programação e da Engenharia de Software. Uma vez aprendido o conceito, a prática é a consequência lógica disso.