Categoria: Livro

  • Comunicação Indolente

    Comunicação Indolente

    Sou extremamente entusiasmado com tecnologia e adoro até mesmo aquelas tecnologias que chegam pra quebrar tudo que já existe. Tecnologias disruptivas, na maioria das vezes, empurram a sociedade pra frente. Na terminologia usada na política eu seria chamado de “progressista”. O oposto de um “conservador”.

    Mas ser um progressista não deveria impedir as pessoas de apontarem os problemas causados por novas tecnologias. É necessário que isso aconteça para que a sociedade coloque essas novas tecnologias problemáticas como pauta para novos “progressos”.

    Tecnologias usadas nas redes sociais, os tais “algorítmos”, produtos construídos no bojo da Inteligência Artificial (Machine Learning, Deep Learning, etc), Deep Fake, e etc já estão se mostrando bastante problemáticas em muitas aplicações. Não quero que elas acabem (até porque seria impossível) mas precisamos entender elas melhor e ajustar o seu uso.

    Mas não pretendo tratar desses grandes tópicos aqui. Eu sequer teria capacidade para abordar esses assuntos. Vou tratar de uma tecnologia bem mais prosaica: as novas ferramentas de comunicação empresarial.

    Vou falar sobre o Slack mas acho que os pontos aqui também se aplicariam a ferramentas similares como o Teams, Rocket Chat, e até certo ponto, o Discord. E vou falar mais do Slack porque é a que tenho usado por mais de 5 anos infelizes.

    Comunicação

    Existe uma classe de medicamentos chamada de “genéricos”. A piada (ruim) diz que os medicamentos genéricos servem para curar problemas genéricos.

    Se existe uma classe de problemas genéricos essa classe é a dos “Problemas de Comunicação”.

    Eu aposto uma jujuba que em quase toda reunião de feedback, sprint review, ou post-mortem/lessons-learned, alguém vai logo dizer “ah! mas isso foi um problema de comunicação”, ou, “acho que é só a gente melhorar a comunicação”.

    A comunicação… ah essa malvada! Sempre essencial e importante e tantas vezes negligenciada.

    A comunicação é composta de vários elementos: emissores, receptores, mensagens e meios e para que ela funcione bem todos esses elementos precisam funcionar corretamente. Se tudo isso funcionar corretamente a gente acaba com uma comunicação efetiva.

    Não importa se a comunicação é síncrona, assíncrona, rápida, lenta, detalhada, superficial, urgente, importante, online, offline, etc. Tudo isso pode variar e mesmo assim você pode ter uma comunicação efetiva.

    Vai falar que comunicação assíncrona é melhor para aquele cara que quer avisar que o sistema principal da empresa caiu. Uma plataforma de chat, um mensageiro eletrônico ou até mesmo um telefone são muito mais adequados para comunicar essa ocorrência do que um e-mail em um grupo de discussões, um telegrama ou uma carta.

    O oposto disso seria o processo de comunicação necessário na criação de um novo produto. Não me parece que usar um chat seja o melhor lugar para conduzir a comunicação necessária nesse processo.

    Imagine todas aquelas informações importantes sobre o projeto morrendo na timeline do chat como se fossem lágrimas na chuva.

    Nesse caso uma reunião presencial (quando possível), uma reunião online com um documento compartilhado ou uma thread em um bom fórum/grupo de e-mail funcionaria bem melhor. No caso do fórum/grupo você ainda incluiria aquele coleguinha que não pôde participar da reunião por um motivo qualquer (ex. férias, doença, compromisso pessoal, …).

    Indolência

    Eu comecei esse artigo com uma reclamação no Twitter. Logo vi que parte das pessoas não entenderam muito bem o meu ponto por lá. Sabe porque? Porque o Twitter é uma péssima ferramenta de comunicação para expressar tudo o que estou colocando aqui.

    Por esse motivo achei importante escrever exatamente o que eu penso aqui. Um meio muito mais adequado para comunicar ideias mais elaboradas. Eu precisei ser menos indolente (slack) e menos negligente (slack) na minha comunicação.

  • A Virtude da Paciência

    A Virtude da Paciência

    Eu tenho dois filhos que fazem parte das gerações Z e Alpha. Essas últimas gerações tem algumas características em comum e uma delas é a de que eles querem tudo na hora, só clicando um botão. Eles não querem profundidade. Preferem respostas rápidas. On-demand. Just in Time.

    Eu sou de outra geração (acho que é a Gen X) mas já tinha essa mesma ansiedade. Quando eu era criança falava que iria aprender tudo o que a humanidade sabia. Achava que todo o conhecimento da humanidade era o que estava dentro dos 10 volumes da Enciclopédia Trópico que a gente tinha em casa. Era bastante coisa para uma criança mas, ei!, eu tinha uma vida toda pela frente!

    Todo o conhecimento da humanidade

    Aí a criança cresceu e o mundo foi crescendo junto. Os horizontes se expandiram. Começou a ficar claro que a humanidade sabe muito mais coisas do que aquilo que estava na Trópico. O entusiasmo de aprender tudo virou um: ih! fodeu!

    Acabei deixando meu plano de saber tudo o que a humanidade sabe on hold (mais um na lista de projetos paralelos sem finalizar) e optei por desenvolver um MVP: aprender tudo sobre computação. Como já dá pra ver a primeira característica de um bom programador já estava presente: subestimar o tamanho dos problemas.

    Trinta anos depois de ter estabelecido essa meta eu posso dizer com tranquilidade: tá foda! 🙂 Não desisti ainda, mas preciso dizer para todo mundo que está começando na computação que não é fácil e leva tempo.

    Não conheço muito sobre outras áreas e profissões mas imagino que não seja muito diferente. Se embrenhar por uma carreira sempre vai exigir dedicação e tempo.

    É claro que hoje eu consigo aprender uma nova linguagem de programação muito mais rápido do que acontecia 20 anos atrás. Também consigo entender o que uma ferramenta faz com poucos parágrafos de texto ou em uma boa conversa no boteco com amigos da área (saudades disso!).

    Porque eu consigo entender e aprender algumas dessas ferramentas tão rápido? Porque depois desse tempo todo eu adquiri experiência.

    Experiência é o produto de dois fatores: prática deliberada e tempo.

    Sem a prática deliberada você não ganha experiência. Sem tempo você também não ganha experiência.

    Oportunidades

    Grandes Oportunidades requerem Grandes Experiências

    Tio Benedito (eu acho)

    Já faz algum tempo que o setor de Tecnologia da Informação anda muito aquecido. Tem um mundo vagas abertas para diversos tipos de posições e com o aumento de oportunidades de trabalho remoto esse mercado expandiu ainda mais.

    Por conta dessa efervescência tem muitas pessoas chegando ou migrando para a área de TI. E eu acho isso ótimo! Pra falar a verdade eu acho até que “tá pouco, manda mais”!

    Nesse processo tem chegado todo tipo de pessoas com todo tipo de experiências, expectativas, e necessidades. Para alguns é uma jornada para a vida. Para outros é só mais uma ‘corrida pelo ouro’. Pra ser honesto eu não ligo muito para as motivações dessas pessoas porque cada um sabe quando o boleto vence.

    Mas no meio desse pessoal que está chegando tem um grupo que me preocupa um pouco mais: os jovens que anseiam por resultados rápidos.

    Eles me preocupam porque, como meus filhos, eles anseiam por resultados e respostas rápidas para tudo. Inclusive para suas carreiras. E é mais provável que esses resultados não cheguem tão rápido para quem está só começando. Bons resultados surgem com boas oportunidades e a probabilidade de uma boa oportunidade surgir para uma pessoa com pouca experiência é muito baixa.

    Então é preciso adquirir muita XP antes de encarar os chefões do jogo.

    É fácil. Mas é Difícil.

    Sempre que alguém me pergunta se é muito difícil aprender a programar eu respondo: é fácil mas é difícil. Obviamente, depois da brincadeira boba, eu explico melhor.

    Para se tornar um programador é necessário dominar várias técnicas (ex. dividir um problema grande em problemas menores, experimentação, etc), algumas ferramentas (ex. computador, linguagem de programação, editor de texto, controle de versão, banco de dados, etc) e algumas práticas (ex. escrever testes, revisar código, etc).

    Como você pode ver um programador não aprende só programação. Tem um portfólio completo de coisas que precisam ser estudadas em maior ou menor profundidade para se tornar um programador melhor e melhor.

    Algumas dessas coisas vão ser fáceis de aprender e entender. Outras serão bem desafiadoras. E eu não consigo fazer uma lista classificando quais são fáceis e quais são difíceis porque isso varia muito de pessoa para pessoa. Eu sofri para aprender programação OO. Amigos meus ‘sacaram’ o paradigma lendo um livro.

    Mas insisto em dizer que todo mundo consegue se tornar um programador mas não espere que seja só fazer um curso mágico e pimba! Sou um programador! Nem mesmo uma boa universidade sozinha vai fazer isso pra você.

    Se você pode fazer uma boa universidade aproveite a oportunidade e faça. Vai te ajudar muito na sua jornada. Mas lembre-se de que a jornada é sua e é você que precisa praticar programação.

    Aprender programação se parece muito com aprender uma arte marcial. Você não aprende Kung fu lendo um livro ou assistindo vídeo de aulas no Youtube. A menos que você seja o Neo no filme Matrix você só aprenderá Kung fu praticando.

    Señor Developer

    Foto de um fazendeiro mexicano usando chapeu e com um bigode bem grosso com a legenda "Respect! I'm a señor developer"

    O que eu disse até aqui não tem relação com a discussão infrutífera sobre “Senior Developer” que vez ou outra explode em algumas redes sociais.

    Essa classificação de senioridade é muito aberta e subjetiva. Ela varia de empresa para empresa e de programador para programador.

    Eu tenho minha definição sobre o que é um programador Senior e ela inclui o atributo experiência (ter um bigode grosso é outra coisa que conta para senioridade… brincadeirinha 🙂). Mas para outras empresas ou até mesmo para outros amigos meus isso não é tão relevante. E tudo bem!

    Algumas pessoas atribuem senioridade para programadores com experiências relevantes, outros definem que um profissional senior é capaz de ajudar outros colegas de trabalho. Como eu disse, isso varia muito e ficar discutindo o assunto é pura perda de tempo.

    Não seja fiscal de senioridade. Se importar muito com isso é um sinal de que algo precisa melhorar em você.

    Ceja Bem Vindos!

    Foto de uma fachada de restaurante com uma placa escrito: "Ceja bem vindo e esprimente a linguiça"

    No mais eu gostaria de dizer à todos que estão chegando e deixar aberto minhas redes sociais para todos vocês que sentirem que precisam de alguma ajuda nesse processo.

  • Bastidores de um Processo Seletivo…

    Bastidores de um Processo Seletivo…

    … para pessoas programadoras

    Como sou programador eu procuro sempre ter uma abordagem voltada para solução de problemas. Mesmo quando o problema que se apresenta não seja solucionável com software.

    No momento que a empresa onde eu trabalhava precisou aumentar a equipe fiquei de frente com alguns problemas importantes: como encontrar e contratar profissionais com o perfil que a gente precisava? Qual o perfil de profissional que a gente precisava?

    A empresa estava construindo os alicerces de uma plataforma de software. A pequena equipe que já trabalhava com a gente era muito qualificada e experiente. Também valorizavam a qualidade das práticas e processos de desenvolvimento para entregar sempre o melhor resultado.

    Então a gente tinha que contratar programadores que prezam a qualidade das soluções desenvolvidas e fazer essas contratações em ritmo bom.

    Perceberam que os dois requisitos podem soar contraditórios? Qualidade ou velocidade? Ambos!… Nessas situação a gente travou um limiar no aspecto qualidade e criou um processo que pudesse agilizar e uniformizar todas as contratações.

    Processos & Práticas

    Nesse artigo eu vou descrever o processo de seleção que construi, junto com minha equipe e o departamento de Recursos Humanos da empresa. Essa é a versão do processo que estava em uso até o momento que eu deixei a empresa. Não sei se eles ainda estão usando mas eu suspeito que não.

    O processo não é perfeito e, como disse, prioriza um perfil de profissional bastante específico: profissionais apaixonados por programação que querem trabalhar em uma equipe que desenvolve software. São profissionais que priorizam muita qualidade e boas práticas.

    Falei esse monte de coisas aqui em cima mas o que eu realmente queria fazer era criar o ambiente perfeito para o programador que existe em mim amaria trabalhar. ?

    Esse processo não é muito eficaz para empresas que precisam crescer o seu time de desenvolvimento de forma muito rápida ou que estejam em um estágio onde o mais importante é criar soluções rápidas para os problemas que se apresentam. E vocês verão que ele é bem longo.

    O processo todo é dividido em 8 fases. Cada prospecto/candidato tinha um card no JIRA que tinha algumas customizações que exigia o preenchimento de certas informações fossem feitas antes de se avançar para a próxima fase. Cada fase do processo era representado por uma coluna no JIRA.

    Aviso para candidatos

    Algumas informações desse artigo podem ser muito valiosas para vocês também. Entender como um desse processos funciona te permite fazer engenharia reversa e hackear o sistema. Espero que vocês façam bom uso desse material.

    Etapas do processo

    Etapa 0: Captação

    Antigamente as empresas descreviam as vagas com seus requisitos, colocavam em alguns forums e sites de emprego e ficavam esperando a enxurada de candidatos. Aí era só jogar todos esse candidatos nos diversos filtros, avaliar eles e escolher o mais adequado entre todos os finalistas. Essa abordagem passiva para contratar programadores não funciona mais tão bem.

    Hoje é muito difícil contratar bons programadores. Contratar bons programadores com experiência está se tornando quase impossível. Não sei se isso vai ser assim pra sempre mas já é uma realidade faz vários anos.

    Por conta disso a abordagem passiva para buscar candidatos precisa ser modificada e as empresas, agora, precisam ser pró-ativos na captação de bons prospectos/candidatos (leads). Uma vez que você encontra esses candidatos devemos iniciar o processo de “venda” da vaga para ele.

    Na empresa onde eu trabalhava a gente tinha diversas técnicas de captação. Eu vivia me embrenhando em redes sociais e grupos de desenvolvimento de software em busca de projetos bacanas e sempre que esbarrava em um programador interessante eu criava um card no JIRA com as referências desse prospecto.

    A empresa também incentivava (e financiava) os programadores da nossa equipe a participar de eventos de tecnologia e levar a palav… digo… apresentar as oportunidades que trabalho que a gente tinha aberto. A gente também tinha um orçamento para patrocinar esses eventos e poder ter uma presença mais marcante nessas ocasiões.

    A equipe de RH também ajudava muito na captação buscando leads em plataformas como Linkedin, Stackoverflow, etc.

    Eu fiz um breve “treinamento” (uma reunião rápida pra passar umas dicas) com a equipe de recrutadores explicando como abordar esse leads sem soar muito intrusivos. Ensinando a não ter nenhuma abordagem massiva (spam, mail marketing, etc) e sempre abordar cada lead depois de ter lido perfil e se informado sobre o possível candidato. Também expliquei como se comportar em comunidades de FLOSS e nunca postar uma vaga sem antes se apresentar e perguntar quais são as regras daquele grupo para anunciar vagas abertas.

    As descrições das vagas precisam “vender o produto”. Então elas precisam ser muito completas e contar até mesmo detalhes das tecnologias, processos, benefícios, etc. Apesar disso, nessa empresa, a gente não anunciava a faixa salarial e sempre dávamos respostas vagas como ‘acima da média de mercado praticadas no Glassdoor’. Não consegui convencer todo mundo sobre a importância de divulgar a faixa salarial. Mas esse assunto é complicado o suficiente e provavelmente merece um artigo só sobre ele.

    O processo todo deveria ter como alicerce o respeito total com os candidatos. Respeito com a pessoa, com o tempo da pessoa, e com a dedicação dela ao processo.

    Etapa 1: Entrevista Inicial

    Com o contato do prospecto e o estudo prévio dele já podemos entrar em contato e marcar a entrevista preliminar caso ele tenha interesse em nos atender.

    O dia e horário que você marcar essa entrevista já vai dizer um pouco sobre o ritmo de trabalho da empresa. Então fique esperto com entrevistas em horários bizarros como fins-de-semana ou tarde da noite. A menos que o candidato peça um horário diferente tente falar com ele em horário comercial.

    Se ele topou envie o convite por e-mail e marque em sua agenda e JAMAIS se atrase para essa entrevista. É crucial que você respeite o candidato desde o primeiro contato. Lembre que é a sua empresa que precisa dele.

    Essa parte do processo é a que vou detalhar menos porque ela era conduzida majoritariamente pelas psicólogas do RH da empresa que, por questões de ética profissional, não podiam detalhar o que faziam. Recomendo muito usar profissionais de psicologia no processo de recrutamento das empresas. A quantidade de informações úteis que eles conseguem trazer para o processo é incrível.

    Na entrevista inicial uma das psicólogas iniciava o contato online com o candidato, fazia algumas perguntas para ver se o candidato se encaixava no perfil de profissional que a empresa dava preferência e começava algumas anotações sobre pontos de atenção para serem explorados nas próximas etapas.

    Um exemplo: a empresa tem trabalho remoto e o candidato diz que nunca trabalhou remoto antes. Isso obviamente não desclassifica o candidato mas prepara os avaliadores das próximas etapas para ver se o candidato consegue se desenrolar bem nessa modalidade de trabalho.

    Aliás, essa etapa dificilmente ‘desclassificava’ alguém. Ela era muito mais útil para fornecer subsídios para os avaliadores. Em alguns raros casos a recrutadora era desrespeitada durante essa entrevista e, nestes casos, obviamente, o candidato caia por ali mesmo.

    Uma vez que a psicóloga estava confortável pra enviar o candidato para a próxima fase ela já apresentava o teste técnico (próxima fase), explicava como proceder com o teste e já deixava um contato para eventuais dúvidas. O teste não tinha prazo máximo pra ser feito mas a psicóloga contactava o candidato regularmente (semanalmente) pra perguntar se estava tudo ok com o teste. Algumas vezes os candidatos abortavam o processo e não avisavam nada pra gente e essas ligações serviam pra gente mover o card desse candidato pra coluna de finalização.

    Uma observação importante: a recrutadora também era a coordenadora do processo de cada candidato. Ela que “batia o bumbo” para que os processos andassem e os prazos fossem cumpridos. Ela também centralizava a comunicação com o candidato para garantir que ela estava dentro dos padrões.

    Etapa 2: Teste Técnico (Candidato)

    Eu não gosto de testes de quadro branco e acho esses testes de sites como HackerHank bastante limitados. Por mais que seja bem difícil e trabalhoso especificar um teste técnico que consiga abranger a avaliação de todas as habilidades importantes em um candidato eu acho que vale o investimento.

    O teste técnico é peça muito importante de todo o processo. Não só porque ele vai avaliar se o candidato tem o mínimo de conhecimento para trabalhar nos projetos que a empresa precisa. O teste técnico serve como subsídio para algumas etapas posteriores.

    O teste técnico que criamos possuíam as seguintes características:

    1. Venda seu peixe. O documento com o teste é uma boa oportunidade para mostrar como vai ser legal trabalhar junto com você na empresa.
    2. Projeto completo. O teste tem que pedir um projeto completo. Do desenvolvimento até o deployment em produção. Indique sites que possibilitem o deploy gratuito desse teste para o candidato (ex. Heroku).
    3. Definição de escopo e requisitos objetiva. O teste tem que ser enviado para o candidato com um único documento contendo todo o escopo do projeto. Se você espera que o candidato saiba inglês, por exemplo, envie esse documento em inglês. O documento deve especificar apenas o Quê precisa ser feito. Nunca diga como fazer à menos que isso faça parte das práticas que o candidato precise dominar mas que seja muito difícil ou demorado para ensinar. Exemplos de coisas que você pode pedir:
      1. Código com strings e identificadores em inglês;
      2. Usar alguma linguagem que a empresa use (para que possa ser avaliado);
      3. Testes automatizados;
      4. Documentação (no idioma que você quer avaliar no candidato);
      5. Armazenado em controle de versão;
      6. Seguir um coding style específico;
      7. Praticar conceitos de 12 Factor-App;
      8. API em um estilo específico (ex. REST, GraphQL, gRPC, etc)
    4. Simples e factível em 1 dia. Bons profissionais, geralmente, já estão trabalhando. É importante entender que eles não tem tempo para investir em um teste longo e trabalhoso.
    5. Não-relacionado à atividade da empresa. Não faz muito tempo algumas empresas usavam testes técnicos para obter desenvolvimento gratuito de candidatos. Por conta disso programadores são bastante desconfiados de testes que pedem o desenvolvimento de algo que a empresa possa usar sem pagar.
    6. Código aberto por padrão. Exceto em casos onde o candidato pede explicitamente para manter o teste dele fechado deixe ele como opensource. Isso diminui as dúvidas sobre o uso do código sem pagamento. Algumas pessoas me perguntavam se isso não pode ser usado por outros candidatos para copiar testes. Sim. E tudo bem, afinal, todo desenvolvedor sempre acaba copiando um código aqui e ali. Nas etapas seguintes é possível levantar o que foi copiado e a motivação para isso. Se foi plágio completo você consegue detectar fácil.
    7. Exercitar vários aspectos do trabalho. O teste pode ter uma regra de negócio elaborada, implementar uma API REST, armazenar os dados em um DB, ter modelos diferentes interagindo, etc. Problemas pontuais com coisas como carrinho de compras, gestão de assinaturas e pagamentos, gestão de conteúdo, logística e entregas, etc são ótimas fontes de ‘problemas de negócio’ que podem ser explorados para criar um teste. Lembre apenas de limitar bem o escopo para que seja possível criar algo em um dia.
    8. Validade limitada. O teste tem que ter uma validade limitada. A validade serve para que você reabilite candidatos que eventualmente não foram selecionados em um processo anterior a participar novamente. Ele fez o teste-1 e não foi adiante 6 meses atrás mas ele estudou os pontos que você indicou e quer aplicar para uma vaga novamente. Se o teste mudou ele pode reaplicar.
    9. Produzir contexto extra-código. O teste precisa permitir que o programador trabalhe nele como ele trabalharia na sua empresa porque não devemos avaliar apenas o código produzido. Precisamos ver a documentação do projeto, a linha do tempo dos commits e as mensagens de commit, abordagens alternativas para solução do problema, etc.
    10. Sem prazo para entrega. É importante deixar claro para o candidato que o objetivo dele é fazer o melhor teste que ele puder e não o tempo que ele leva para fazer isso. O tempo para realizar o teste precisa ser descartado completamente da avaliação porque cada candidato tem uma situação completamente diferente de outro candidato. Tem candidato que tem emprego e outro que não tem. Tem candidato que tem atividades paralelas e outros que não tem. Tem candidato que está estudando um tópico novo para fazer o teste e outros que já sabem tal tópico. É importantíssimo reforçar isso para o candidato sempre que entrarmos em contato com ele para que esse contato não se pareça com alguma forma de pressão por entrega. Diga que ele será avaliado pelo que ele entregar e não pelo tempo que ele levou pra entregar.

    Abaixo você consegue ver um exemplo de teste técnico:

    Assim que o candidato concluir o teste e enviar o material pra você a próxima etapa começa. Chegou a hora de avaliar o teste.

    Etapa 3: Avaliação Técnica

    A avaliação do teste precisa ser feita por um programador da equipe ou gestor que tenha trabalhado como programador da equipe. Ele vai pegar o código do candidato e uma ficha de avaliação com perguntas claras e objetivas sobre tudo o que a empresa espera do candidato e preencher essa avaliação.

    Mais do que a avaliação em si, nesse momento é bem importante que apareçam dúvidas na cabeça do avaliador. Essas dúvidas precisam ser anotadas juntamente com os resultados da avaliação porque elas serão extremamente úteis na próxima etapa do processo seletivo.

    Na empresa onde implementamos esse processo a gente criou uma planilha com um questionário com perguntas bem objetivas agrupadas em tópicos. Cada pergunta dessa gerava uma nota entre 0 (min) e 3 (max). Cada nota dessas tinha um peso variando entre 1 e 3 que posteriormente era usada em uma média ponderada.

    No final a gente gerava um gráfico do tipo radar com um eixo em cada tópico (ex. Documentação, Modelagem de Banco, Commits, etc) e uma lista de notas e observações do avaliador.

    Você pode baixar um modelo dessa avaliação aqui:

    Quando o volume era menor a gente colocava dois programadores para avaliar o mesmo teste e depois fazia uma ‘acareação’ mediada entre os avaliadores para evitar problemas de interpretação. Mas em um determinado momento o volume de testes para revisar ficou grande demais e só um programador fazia a avaliação de cada teste.

    Fizemos essa mudança porque raramente encontrávamos divergências muito grande e em todas as vezes o motivo da divergência era a falta de objetividade na pergunta do questionário que era prontamente corrigido.

    Essa avaliação não pode demorar muito pra ser feita e, se isso acontecer por algum motivo, é importante manter o candidato informado.

    Em alguns casos o candidato vai muito mal e recebe avaliações muito ruins e seguir com o processo provavelmente seria um desperdício de tempo para todos.

    Nesses casos é muito importante devolver uma resposta para o candidato e, se possível, indicar os pontos de estudo e melhoria para ele. Eu tinha uma lista de links para artigos ou livros para indicar que ajudariam o candidato a cobrir todos os pontos onde ele precisava melhorar.

    Esse feedback precisa ser mais abrangente do que específico:

    From: [email protected]
     
    Olá [candidato],
    
    Após a avaliação do seu teste técnico [url do
    teste] nós optamos por não seguir adiante com
    seu processo seletivo nesse momento.
    
    Agradecemos o seu tempo e dedicação até aqui e
    gostaríamos de vê-lo novamente no futuro quando
    lançarmos um novo teste técnico para a vaga.
    
    Para isso gostaríamos de sugerir a leitura dos
    seguintes materiais:
    
    * [link para um artigo sobre apis rest]
    * [link para um livro sobre modelagem OO]
    * [link para livro sobre TDD]
    * [link para um bom curso de Python no youtube]
    
    Se você tiver qualquer dúvida ou tiver
    interesse em nos dar um feedback sobre
    o processo até aqui é só entrar em contato.
    
    Obrigado,
    Equipe Empresa Co.
    

    Esse e-mail não é o lugar para escrever coisas como ‘você não foi aprovado porque a sua modelagem de banco estava toda errada’. Prefira indicar um bom livro sobre modelagem relacional. Dê preferência para conteúdo gratuito. Lembrem-se que o candidato pode estar numa situação financeira complicada.

    Na empresa onde eu trabalhei eu pedi verba para comprar ebooks e enviar para candidatos que não eram aprovados. Mas a verba não foi aprovada.

    Etapa 4: Entrevista Técnica

    Assim que a avaliação do teste técnico ficava pronta um gestor de tecnologia poderia prosseguir com o agendamento da entrevista técnica com o candidato. Ele fazia isso sempre buscando o melhor horário para o candidato. A entrevista também precisava ter uma duração fixa pré-determinada. Deve-se evitar dividir essa entrevista em etapas distintas. Ter ela em uma única sessão garante que você vai avaliar o candidato em sua plenitude de humores.

    Conduzir uma boa entrevista exige mais técnica do que experiência. Pode ser que eu escreva só sobre isso em um artigo futuro então vou só pontuar algumas coisas que a gente fazia lá.

    Antes de ir para a entrevista técnica o gestor já se preparava usando as informações das avaliações feitas pela recrutadora na entrevista inicial, as anotações da avaliação técnica e dando uma conferida no Linkedin ou no Github do candidato. Eu evitava redes sociais não profissionais (Twitter, Instagram, Facebook, etc) porque nas poucas vezes que olhei essas redes acabei sentindo que a entrevista ficou enviesada de forma negativa.

    Os gestores que faziam essas entrevistas já tinham alguma experiência com processos de recrutamento mas, mesmo assim, a gente ainda sugeria certos procedimentos para tentar padronizar a experiência. A gente sugeria que o entrevistador criasse um plano para a entrevista com algumas perguntas-guia para fazer para o candidato. Meus planos geralmente tinham umas 3 perguntas padrão que giravam em torno de relacionamento com equipe, processos e experiências anteriores, e umas 2 ou 3 perguntas que variavam em função do resultado das avaliações. Nem sempre eu usava essas perguntas mas sabia que elas estavam lá caso a entrevista ficasse meio truncada.

    Condução da entrevista

    Essa etapa não era muito padronizada então vou descrever como eu conduzia as minhas entrevistas. Como eu já disse eu iniciava a entrevista com um plano construído sobre as avaliações anteriores e uma breve olhada nas redes sociais profissionais do candidato.

    Sabendo que essa entrevista costuma ser a que deixa os candidatos mais nervosos e que muitos candidatos, mesmo aqueles com muita experiência, podem ‘travar’ nesse momento eu dedicava um bocado de tempo no começo só para deixar o ambiente mais leve e as coisas mais calmas. Você precisa que o candidato esteja tranquilo para conseguir uma boa entrevista.

    A entrevista técnica sempre começava com algumas perguntas básicas e despretensiosas sobre o candidato. Começar a conversa perguntando sobre algum hobby ou coisas positivas que surgiram na entrevista inicial tira o peso da entrevista e diminuíam o nervosismo do candidato.

    Um exemplo do que eu fazia era só perguntar coisas que o candidato sabe como responder com 100% de certeza. Perguntas como: “Qual seu nome?” ou “Qual sua idade?” estão nessa categoria. “Quais linguagens de programação você gosta?” não está nessa categoria porque o candidato vai começar a pensar sobre qual é a resposta que o entrevistador quer ouvir.

    Eu tomava muito cuidado com perguntas sobre a intimidade do candidato (ex. “Você é tem namorada(o)?”). Até pra perguntar se o candidato era casado(a) ou tinha filhos eu evitava. Se eu não estivesse 100% certo de que essas perguntas eram seguras eu não fazia. Por isso o planejamento prévio é essencial.

    Uma dica que sempre dou para quem está começando a fazer entrevistas é: você não precisa ser algo que você não é. Se você não é engraçado não precisa ser engraçado. Só tente ter empatia pelo candidato para poder ajudar ele.

    Quando você sentir que o candidato está mais calmo você pode serguir com o seu plano para a entrevista. Chegou a hora de falar pouco e ouvir muito.

    Aqui eu partia para as perguntas técnicas. É muito comum que programadores estejam mais confortáveis com a parte de hard skills então a transição para essas perguntas acontecia de modo mais natural.

    Eu usava o teste do candidato para formular questões bem objetivas. Perguntas do tipo: “Aqui nesse ponto do seu código você fez isso. Porque você fez assim e não assado?” (ex. “Vi aqui nessa parte do seu teste que você modelou esse relacionamento em 1-para-N… mas e se essa entidade estiver em M contextos, não seria melhor um N-para-M?”).

    Eu prestava atenção no que estava sendo dito (ex. “eu optei por modelar 1-para-N porque na descrição do problema não existia o requisito que pediria uma modelagem N-para-M”), mas também observe o que não está sendo dito. No exemplo anterior dá pra inferir que o candidato segue bem as especificações mas pode não ser muito pró-ativo em questionar essas especificações. Eu encadeava mais perguntas pra dirimir essa dúvida e não ficar só com a minha “inferência”.

    Também gostava de fazer perguntas que podiam ser respondidas corretamente de vários modos diferentes e emendar uma segunda pergunta contrapondo a resposta. Exemplo: “Se você tivesse desenvolvendo um ORM como você faria pra persistir um objeto no banco de dados? Faria obj.save() ou storage.save(obj)?” e a próxima pergunta seria: “Mas [a outra abordagem] não teria a vantagem de [vantagem da outra abordagem]?”. Esse tipo de pergunta permite ver o candidato reagindo à uma situação de argumentação e defesa de seus pontos de vista. Alguns candidatos até explicaram a teoria e as referências para as duas abordagens (Active Records vs. Data Mappers). Esse foi contratado, né? ?

    Uma vez que as questões técnicas foram esclarecidas eu partia para as “perguntas difíceis”. Aqui eu queria entender mais sobre os soft skills do candidato. Nesse momento o candidato estava mais amaciado com as coisas que ele (teoricamente) sabia e conseguiria responder com a guarda mais baixa.

    Eu voltava então a fazer perguntas relacionadas ao comportamento e relacionamento do candidato com as equipes que ele teve.

    Queria saber como era a relação dele com gestores, o que ele gostava no trabalho, o que ele detestava, o que ele gostaria de mudar, o que ele conseguiu mudar, o que ele não conseguiu mudar, porque ele não conseguiu mudar, etc.

    Eu sempre tomava notas durante a entrevista. Precisava fazer isso para alimentar o nosso relatório sobre o candidato.

    Finalmente chegamos ao fim da entrevista. Você agradece o candidato e avisa que ele receberá um retorno num prazo específico. Cumpra esse prazo.

    Retorno

    O retorno para o candidato podia ser de 2 tipos:

    1. Paramos: agradecíamos o candidato pelo tempo investido no processo, informávamos que ele pode voltar a tentar a vaga no futuro, indicávamos caminhos que ele poderia tomar para ser melhor sucedido na próxima oportunidade, e deixávamos um canal sempre aberto para comunicação com ele. Esse retorno era por e-mail mas eventualmente o RH entrava em contato direto com o candidato.
    2. Continuamos: parabenizávamos o candidato e informávamos que a próxima etapa seria uma dinâmica de Pair Programming remoto com um dos nossos desenvolvedores. Pedíamos um espaço na agenda do candidato para essa atividade.

    Etapa 5: Dinâmica de Pair Programming Remoto

    A equipe de tecnologia da empresa onde implementamos esse processo sempre trabalhou remotamente. Trabalhar remoto é uma atividade que pede certos soft skills importantes (ex. auto-gestão, auto-organização, etc) e o nosso processo precisava avaliar se o candidato tinha essas características, se era necessário desenvolvê-las, ou se a empresa seria incapaz de desenvolver essas qualidades no profissional caso ele fosse contratado.

    Quebramos a cabeça pra descobrir um modo de fazer essa avaliação e, certo dia, participando de um Coding Dojo com alguns amigos eu tive a ideia de tentar algo parecido para avaliar a dinâmica de trabalho remoto do candidato. Deu super certo e se tornou a etapa que me deixava mais entusiasmado com os resultados.

    Montamos um servidor remoto (usando AWS Cloud9) com a linguagem Python, framework de teste, editor de textos e conectávamos um desenvolvedor da nossa equipe e o candidato para fazer pair programming. Além dos dois programadores um gestor (geralmente o mesmo que fez a entrevista técnica) ficava na audiência coordenando a atividade e observando a dinâmica.

    O gestor então apresentava o problema que seria abordado na dinâmica. Eram problemas de Coding Dojo já conhecidos (ex. mostrar números decimais com algarismos romanos). Nenhum dos programadores pode saber qual vai ser o problema de antemão. Tem que ser uma surpresa para ambos.

    É muito importante deixar claro para ambos que o objetivo da dinâmica é ver a dupla trabalhando e não a resolução do problema. Deixe claro para o candidato que se não der tempo de resolver o problema está tudo bem.

    Uma vez apresentado o problema os programadores começavam a trabalhar nele usando TDD e baby steps. Em intervalos de 5 minutos (cronometrados) os programadores são obrigados a trocar de posições como piloto e co-piloto do teclado.

    Assim que o timebox foi atingido o programador pode deixar a sala e o gestor pode conversar com o candidato sobre a dinâmica.

    A gente usava essa oportunidade para perguntar sobre situações que aconteceram durante a sessão de pair programming. Fazíamos muitas perguntas sobre comportamento (ex. “naquele momento o [nome-do-dev] propôs algo que você não concordou/entendeu e mesmo assim você seguiu com a proposta dele, porque você não parou pra questionar ele sobre a decisão?”).

    Também é possível ver se o candidato consegue expressar bem suas ideias e propostas.

    Essa etapa tem que ter duração fixa e não precisa ser longa. Na empresa a duração dessa etapa começou com uma hora de duração e foi diminuindo até durar 40min.

    Algumas vezes a gente colhia as impressões do programador da nossa equipe que fez pareou com o candidato para complementar nossa avaliação.

    Era muito raro um candidato cair nessa etapa. Se o candidato foi muito mal e a gente entendesse que não daria para prosseguir a gente falava que ele receberia o feedback em alguns dias e procedia com o e-mail de agradecimento e etc.

    Se o candidato tivesse ido bem nessa etapa ele já recebia uma lista de dias e horários para a entrevista final com o CEO. Era a única ocasião onde o candidato não tinha o controle total sobre a agenda do processo. Infelizmente a agenda do CEO era uma selva e tinha muito poucos buracos para ocupar com as entrevistas com candidatos. Mas ele fazia questão de entrevistar todo mundo de todos os setores da empresa.

    Etapa 6: Entrevista Final

    A entrevista final com o CEO era a etapa de consolidação & arremate do processo. Ela existia para determinar se o candidato tinha fit com a cultura da empresa mas também era usada para dirimir alguns questionamentos que ainda estavam aberto sobre o candidato.

    Para isso o CEO recebia um “dossiê” com tudo o que foi levantado sobre o candidato nas etapas anteriores bem como alguns pontos de atenção que a gente detectou nas etapas anteriores. A gente chamava esses pontos de atenção de red flags (bandeiras vermelhas).

    Uma das coisas que essa entrevista tentava avaliar era o nível de comprometimento com a empresa que a gente podia esperar do candidato. Para a empresa era importante que o candidato fosse trabalhar lá com um certo nível de comprometimento e não chegar lá como um trampolim para outra vaga que pagasse mais. Afinal o time dessa empresa era muito reconhecido no mercado e passar por ele “valorizava o passe” de qualquer profissional.

    Nessa etapa todos os candidatos já chegavam travados pelo nervosismo. Afinal, era o CEO da empresa… Então o CEO com a maior calma e paciência ia acalmando o candidato antes de partir para as perguntas.

    Durante a entrevista o CEO contrapunha as resposta do candidato com anotações do relatório que ele tinha recebido para tentar encontrar, explorar e esclarecer divergências.

    Assim que a entrevista terminava o candidato era avisado de que ele receberia o resultado final do processo em alguns dias. Geralmente era no dia seguinte mesmo. Assim que o CEO terminava a entrevista com o candidato era bem comum ele já reunir o comitê que iria decidir sobre a contratação.

    Decisão Final

    Essa etapa era rápida e a decisão era colegiada. Um candidato só era contratado se houvesse unanimidade desse colegiado que era formado por todos os gestores e recrutadores que participaram do processo daquele candidato.

    A decisão era rápida porque todos já tinham tido acesso ao relatório final com todas as informações levantadas ao longo de todo o processo. Bastava avaliar as forças e fraquezas de cada candidato, traçar um plano para potencializar as forças e lidar com os pontos de atenção do candidato e decidir sobre a contratação.

    Feedback

    A etapa de feedback tem duas versões. O feedback para o candidato que foi contratado e o feedback para o candidato que não vai seguir para contratação naquele momento.

    Para os candidatos que não seguiriam a gente enviava um e-mail bastante completo para informar que a gente não seguiria adiante com a contratação, agradecíamos a dedicação do candidato, indicávamos alguns caminhos para futuras tentativas e deixávamos uma linha de comunicação aberta para esse candidato.

    Na linha do respeito ao candidato, algumas vezes, a gente entrava em contato direto com o candidato. Geralmente quando eram candidatos muito jovens que, eventualmente, não conseguiriam lidar muito bem com a não-contratação. As psicólogas avaliavam se isso era necessário ou não e por isso disse que ter esse tipo de profissional envolvido no processo é super importante.

    Para os candidatos que foram aprovados a gente mandava um e-mail de congratulações com as primeiras instruções do nosso processo de on boarding que, modéstia à parte, também ficou lindão (e provavelmente vou descrever aqui).

    É possível que o candidato recuse a oferta nessa etapa. Esteja preparado para isso e peça, educadamente, que, se possível, o candidato explique o motivo da recusa para ver se é possível melhorar algo no processo. Lembrem que o feedback é uma via de mão dupla e o candidato é o protagonista.

    A gente também colhia feedback dos candidatos contratados durante o on boarding. A gente tinha um formulário (Google Forms) interno onde o novo funcionário preenchia suas impressões, apontava problemas e sugeria melhorias. As recrutadoras do RH colhiam essas informações e traziam os feedbacks de forma anônima para nossas reuniões de processos.

  • Palestrante

    Palestrante

    Hoje eu estava lendo o artigo Stepping Back from Speaking do Martin Fowler e me identifiquei com muitas coisas que ele disse. Na verdade parece um artigo que eu teria escrito para falar sobre o assunto. Exceto pelo fato dele ser “O” Martin Fowler e eu ser só o Osvaldo, eu passo (ou passava) por tudo o que ele diz ter passado para dar palestras em eventos de tecnologia.

    Quando eu era mais novo costumava ser bastante introvertido. Isso mudou quando uma professora de educação artística notou que meu talento para trabalhos manuais era bem limitado e decidiu organizar grupos de teatro na minha turma. Fiz ou ajudei a fazer do roteiro à cenografia e até atuei no palco. Ali eu pude perceber que conseguiria me apresentar para uma audiência.

    O tempo passou e a vida aconteceu… veio o trabalho como programador e pude voltar a ser o cara que fica ali no canto, de cabeça baixa, codando.

    Mas aí surgiu o meu envolvimento com as comunidades de FLOSS e, principalmente, com a comunidade Python. Nessas comunidades eu achava super importante compartilhar as coisas que eu aprendia. E a forma de fazer isso quase sempre envolvia falar para uma grande audiência (qualquer coisa maior que uma mesa de bar já conta como ‘grande audiência’ pra mim).

    E aí acontece aquilo: as primeiras apresentações são péssimas, vão melhorando para ficarem muito ruins e um dia, quando menos se espera, eu estava mandando bem.

    Uma das coisas que a gente aprende fazendo palestras é que é muito importante respeitar a audiência. Respeitar a audiência é garantir que você fez o seu melhor para trazer algo relevante para eles. Fazer isso com muito carinho e muita qualidade. Tem gente ali que investiu tempo e dinheiro que vão faltar mais na frente na esperança de ter um retorno por esse investimento. Eu me sinto obrigado a fazer valer esse investimento.

    Em eventos de tecnologia é bastante comum ver os palestrantes montando suas apresentações em slides poucas horas antes de apresentar. Tem gente que tem esse talento mas eu não tenho. Sempre cheguei com minhas apresentações preparadas e ‘testadas’ (algumas vezes testava em encontros locais ou eventos menores). O dia antes da apresentação era só pra atualizar uma ou outra informação que eventualmente tinha surgido desde a última revisão.

    Causo: durante a PythonBrasil de São Paulo alguns ladrões de notebooks entraram no evento e roubaram meu notebook (e mais um outro da minha amiga Karyn). Minha apresentação estava nele e infelizmente, por negligência minha, não estava sincronizado na nuvem. Eu pedi para retirarem a minha apresentação do evento porque eu não conseguiria fazer ela mesmo conhecendo bem o conteúdo dos slides. Eu entrei em pânico com a ideia de não entregar uma boa apresentação.

    No dia em que tenho que fazer a minha apresentação, tal como acontece com o Martin Fowler, eu entro em um estado tão estressante e fico tão ansioso que fica parecendo que estou tendo um ataque de pânico. Eu chego a ter problemas intestinais nos momentos que antecedem a minha fala.

    Não abandono o plano porque já sei, por experiências prévias, que essa sensação dura só até os primeiros minutos no palco. Nesse momento eu entro em flow com o conteúdo e consigo superar o mal estar.

    Quando a apresentação acaba eu só peço para anotarem a placa do caminhão. Estou exausto e, algumas vezes, até com dores físicas.

    Muitas vezes eu cogitei “tomar algumas” (“fumar” poderia funcionar também) para ver se quebrava um pouco a ansiedade mas desistia da ideia por respeito à audiência. Eu não sei exatamente o que aconteceria mas não me perdoaria se a apresentação ficasse ruim porque eu estava alterado.

    Apesar disso tudo e, diferentemente do Martin Fowler, eu pretendo continuar fazendo apresentações. Sinto que devo isso à comunidade que me trouxe muitas coisas boas na vida e na profissão. Entretanto, tentarei restringir os convites que aceito e, provavelmente, enviarei propostas para poucos eventos.

    Para iniciantes

    Se tem algo que eu gostaria de trazer para quem vai começar a se apresentar em eventos, é que eles entendam que esse nervosismo é normal e bem comum. Até mesmo aquela pessoa no palco, que você admira muito, pode estar passando por essa provação.

    Se você quer encarar essas experiências entenda que pode acontecer esses contratempos ao longo do caminho. E se você não quiser, ou não puder, encarar essas dificuldades tá tudo bem também.

  • Código Deletado

    Código Deletado

    Hoje eu vi uma pesquisa na internet onde perguntavam como eu me sentia quando via meu código sendo removido por outros desenvolvedores do meu time.

    A pesquisa também pedia informações de perfil profissional para tentar entender se profissionais com experiências diferentes reagiriam da mesma forma ao verem seu código removido por outro desenvolvedor do time.

    A primeira coisa que pensei foi sobre o assunto foi “depende”. O software continuou funcionando direito depois do “facão”? O código perdeu alguma característica importante?

    Sempre que vou revisar um código e vejo um patch que remove muitas linhas a minha primeira reação é de empolgação. Então, por padrão, eu costumo gostar muito de alterações que removem código. Nesse momento eu não sei se o código removido é meu ou não então eu também posso dizer que a autoria do código é indiferente pra mim. Sou devoto da igreja do Collective Code Ownership.

    A partir daí eu sigo com a revisão usando outros critérios para validar o que está sendo feito. E é aí que o “depende” entra em ação e eventualmente tenho dúvidas sobre ser favorável ou não à remoção deste ou daquele código.

    Código desnecessário

    Se o código removido não está mais sendo usado obviamente tem que ser removido. Todo mundo ganha com isso. Aquela API antiga que não tem mais suporte e ninguém usa mais? Apaga. Foi tarde.

    Outro tipo de código desnecessário são aqueles trechos que estão comentados dentro dos arquivos. Se você usa um sistema de controle de versão (e deveria) jogue fora isso. Não comente código “pra usar depois”. Se você precisar usar depois busque no controle de versão e use.

    Código grande

    Algumas vezes a gente vê algum método muito grande e decide melhorar a implementação dele. Como conseqüência o código termina menor do que o anterior e os testes ainda continuam passando. Ou seja, foi uma boa refatoração onde todos ganham.

    Mas… tem uma exceção para isso aqui. A legibilidade. Imagine que você tem um código tipo:

    for i in range(50):
        for j in range(50):
           double[i][j] = array[i][j] * 2

    Aí a refatoração faz isso:

    double = [[array[i][j] * 2 for j in range(50)] for i in range(50)]

    Claramente é um código mais curto e roda mais rápido. Mas e a legibilidade? Para julgar se essa redução no código é boa ou não precisamos avaliar mais aspectos.

    Pra mim, por padrão, esse tipo de remoção de código é um “não”. Mas o desenvolvedor pode me convencer do contrário se dizer algo como “cara, esse método é crítico e essa mudança melhora em 30% a performance dela”.

    Código complexo

    Alguns programadores (eu aqui!) tem uma tendência de adicionar complexidades desnecessárias no código para tornar ele mais extensível, mais eficiente, etc. Não é muito incomum que um programador precise resolver um problema muito específico com um código bem básico saia criando sistemas de plugins ou configurações em busca de mais flexibilidade.

    Por sofrer desse problema não é incomum que eu receba modificações que passam facão geral nessas partes do código que eu tinha escrito.

    Sendo bem franco? Eu fico chateado. Mas depois que passa a tristeza e a razão assume o controle é possível entender que a mudança é potencialmente positiva.

    Um “causo” (sem desfecho)

    Certo momento da minha vida eu pegava muito freela pra fazer. Uma empresa me contratou para desenvolver um software de simulação de empresa para um cliente deles.

    O cliente deles tinha um curso de administração e empreendedorismo e criou um simulador de empresa usando Excel. É. Recebi uma planilha com cerca de 30 abas (não é uma hipérbole) onde você controlava estoque, verba de marketing, salários, de uma empresa hipotética e a planilha ia “reagindo” a essas mudanças e mostrando a evolução do seu negócio.

    Eu ia levar 1 mês só com a engenharia reversa daquela planilha para então começar a criar uma aplicação Django pro cliente do meu contratante (Django era requisito do meu cliente).

    Então pensei: e se eu implementar um motor de planilha no Django? Criaria o motor, faria “copy & paste” das fórmulas da planilha para o banco de dados da aplicação e profit!.

    Era uma ideia meio ousada e, por isso, fiz uma prova de conceito para mandar pro meu contratante avaliar. Ele apagou tudo e substituiu as fórmulas da planilha por código Python tradicional. Ele refez o que eu tinha feito só que hardcoded.

    Obviamente, como era só uma prova de conceito com um subconjunto bem pequeno da planilha, o meu “motor” era bem maior do que um conjunto hardcoded de condicionais. Na minha solução o cliente (treinado) poderia ajustar os parâmetros e fórmulas da simulação. Na versão nova só um desenvolvedor poderia fazer isso.

    A alteração feita reduziu muito o código em troca de flexibilidade e de fato ficou bem mais simples e fácil de compreender. Mas foi um bom negócio? Não sei. O cliente deles desistiu do projeto por questões financeiras e nunca soubemos qual abordagem seria melhor.

    Esse caso mostra bem como eu tenho uma forte tendência ao over-engineer. Sempre bom ter alguém ponderado por perto pra segurar minha onda.

    Código ingênuo

    Quando estamos atacando um problema pela primeira vez é bem comum criar soluções muito muito ingênuas para esses problemas. Essas soluções até servem por um certo período de tempo mas logo se mostram insuficientes.

    Olhando deste modo isso parece algo ruim mas é melhor optar por uma solução ingênua do que uma alternativa flexível que inevitavelmente traria complexidade desnecessária pra solução.

    É importante entender que, com o tempo, vamos entendendo melhor o problema e adquirindo mais sabedoria sobre como resolver ele de uma maneira mais adequada. Esse é o momento de melhorar o código e jogar fora o código antigo (se não for possível melhorar ele).

    Quando sabemos que esse momento chegou? Não sabemos. Provavelmente jogaremos fora esse código novo também. E assim a vida segue. Por isso chamamos de software ?

    Um exemplo…

    Já tive que implementar determinados tipos de código mais de uma vez ao longo da minha carreira. Alguns desses reincidentes são os sistemas de autenticação/autorização e os sistemas de assinatura/pagamentos.

    É impressionante. Eu fiz errado na primeira vez, na segunda vez, na terceira vez, … e na última vez.

    Em cada ocasião eu fiz o sistema mais flexível que o anterior e pensava: “dessa vez vai”. Não ia. Acho que nos cursos de Marketing e Administração eles ensinam uma matéria “Como encurralar Devs”. Eles sempre conseguem criar um modelo de assinatura, pagamento, pacotes de permissões, etc que você nunca imaginou. Sempre. Não tente lutar contra isso.

    Por isso o melhor caso aqui é faça um código que só resolva o problema na mesa. Quando outro problema surgir, escreva um código que resolva os problemas que você precisa e jogue o anterior fora. Não tente prever os eventuais futuros problemas porque é perda de tempo.

    Hoje eu terceirizo alguns desses sistemas sempre que dá. Desisti de tentar. Acho que é Senior que chama, né? ?

    Remover código é bom

    Como podem ver, tirando algumas exceções, apagar código é uma coisa boa. Vamos apagar código até termos “low code” ou “no code“… brincadeirinha ?

  • Aprendendo a Programar

    Aprendendo a Programar

    Dentre vários assuntos que tenho interesse na computação um deles é sobre o aprendizado de programação. Principalmente para crianças e jovens. Já li muita coisa e ouvi opiniões muito distintas sobre as melhores formas de se ensinar e aprender a programar um computador.

    Existe muita discussão sobre se ensinar crianças a programar seria algo bom ou não, mas não pretendo descer muito nesse aspecto do debate. Para fins práticos vou partir da premissa de que ensinar crianças e jovens a programar não faria mal para eles e acrescentaria algumas habilidades úteis aos seus repertórios.

    Lembrando sempre que ensinar programação para crianças não tem nada a ver com encaminhar crianças para a profissão de programador.

    Como ensinar programação?

    Nas minhas conversas sobre esse assunto, com diversas pessoas, eu já vi abordagem bem variadas para ensinar alguém a programar. O nível de convicção desses interlocutores sobre sua abordagem favorita variava muito. Alguns “achavam” que sua abordagem era boa e outros tinham “certeza” de que a sua abordagem era a melhor.

    Um padrão que eu detectei foi: quando mais fácil foi para o interlocutor aprender a programar, mais certo ele estava de que o método usado com ele é o mais adequado.

    Isso complica muito a discussão porque faz parecer que reproduzir um desses métodos vai funcionar pra todo mundo. E isso não é assim.

    O que esses bons resultados, com abordagens diferentes revelam é justamente o oposto. Revelam que o que dá certo é usar abordagens diferentes com pessoas diferentes.

    Abordagens

    Eu me deparei com sugestões para os mais diversos tipos de abordagens para ensinar programação para iniciantes.

    Existe uma abordagem que busca ensinar teoria e “lógica de programação”. Com computadores de verdade ou com computadores de papel. Alguns sugerem escrever código em “Portugol” em um pedaço de papel para fazer os famigerados “teste de mesa” e só depois ir para o computador. Outros sugerem usar Portugol direto no computador (ou Pascal).

    Outras pessoas já me disseram que programador tem logo que começar a aprender a programar em C pra já ficar mais próximo da máquina. Eles sugerem C porque seria uma espécie de “assembly multiplataforma”.

    Estou lendo um livro muito bom que sugere ensinar computação (e não só programação) partindo de portas lógicas NAND até implementar um jogo de Tetris.

    Por outro lado outros amigos imaginam que o melhor mesmo seria usar alguma linguagem de nível mais alto mas que ainda são linguagens de uso geral como Python, Javascript, Processing, Arduino/C++, etc.

    Alguns outros adoram ver seus filhos se divertindo com plataformas especificamente criadas para crianças como Scratch.

    O que eu acho dessas abordagens? Na verdade não importa o que eu acho porque não estamos falando do meu aprendizado. Eu já aprendi a programar (eu acho?) e cada uma dessas abordagens funcionou para algumas pessoas e também falhou com outras.

    Qual abordagem é melhor?

    Ok. Então significa que não existe uma abordagem que funcione para ensinar programação? Não exatamente. Não existe uma abordagem que funcione. Existem várias.

    Pessoas diferentes aprendem de modo diferente e isso precisa ser respeitado. Então o certo seria iniciar o ensino com uma das abordagens apresentadas e ir iterando sobre ela para ir ajustando o curso. E focar muito nas práticas e atividades que funcionam melhor para aquele aluno ou para a média daquela turma (caso não seja possível individualizar o ensino).

    Dentre várias práticas observadas por cientistas que já se debruçaram sobre o assunto as que mais se mostram positivas para facilitar o aprendizado são aquelas que apresentam o feedback mais amplo e rápido para o aluno.

    Quando um aluno experimenta algo no computador e vê o resultado daquilo surgindo instantaneamente o cérebro dele dispara recompensas que ajudam muito a fixação do aprendizado. Por outro lado se ele observa o feedback com a visão, com o olfato, com o tato, com a interação com pessoas, etc o efeito dessa recompensa é potencializada ainda mais.

    Essa potencialização do feedback é que fez com que o Seymour Papert, criador do ambiente LOGO para ensino de programação para crianças, disponibilizasse uma tartaruga robô no ambiente que ele desenvolveu. O robô existia para reforçar o feedback das crianças quando ela digitava um comando “PARAFRENTE 10” (ou “FRENTE 10” na variante Microsol LOGO) e via aquele robozão andando sozinho obedecendo à instrução fornecida pela criança. Isso tudo está descrito em seus dois livros.

    A ideia de feedback rápido também é explorada nesse artigo incrível do Brett Victor chamado Learnable Programming que serviu de referência para a Apple criar o ambiente Swift Playgrounds.

    Então, se voltarmos para as abordagens propostas que descrevi acima, podemos trabalhar com várias delas desde que seja possível obter feedback amplo e rápido nas atividades desenvolvidas.

    Tanto o Seymour Papert quanto o Brett Victor apresentam outras práticas úteis no ensino de programação (e, acredito, de qualquer outro tipo de conteúdo). Sugiro a leitura de ambos para se preparar para a tarefa de ensinar programação.

    Qual abordagem funcionou pra mim?

    Eu sou um privilegiado sortudo. Tive pais que tinham uma boa condição de vida (aka classe média) e nunca pouparam grana e esforço em me apoiar.

    Eu já contei um pouco essa história aqui mas resumidamente eu era uma criança de 9 anos que brincava com Eletrônica junto com um amigo e esse amigo ganhou um computador de natal. Eu fiquei completamente entusiasmado com aquilo e pedi um computador pro meu pai.

    Demorou um pouco pro meu pai conseguir comprar o meu primeiro computador (MSX Expert) usado de um tio mas ele chegou lá e eu comecei a estudar com os livros que acompanhavam a máquina. Mas aí eu travei em um ponto do aprendizado e passei a usar a máquina só pra jogar.

    Meu pai viu aquilo e me cobrou: poxa filho… investimos uma grana alta nesse computador pra você aprender a usar ele e você fica só jogando? Você já tinha um videogame pra jogar (um Atari), não precisava de um computador caro pra isso.

    Expliquei pra ele que eu já tinha lido todos os livros e feito todos os experimentos que vinham nele e “não tinha mais pra onde ir”.

    Ele entendeu o problema e perguntou se eu queria fazer um curso de computação? “- Claro!”.

    Ele encontrou uma escola de computação no bairro onde eu morava através da lista telefônica (é… anos 80/90…) e me matriculou lá. Meu pai não entendia nada de tecnologia e me matriculou nessa escola só porque eu poderia ir sozinho até ela (bairro Boa Vista em São José do Rio Preto – SP).

    E até aqui mostra como fui/sou uma pessoa privilegiada. Mas agora vem a parte onde eu fui sortudo…

    Essa escola perto de casa, no interior de SP, era de um casal que tinha ganhado uma grana alta em um desses de plano de demissões voluntárias e foram para os Estados Unidos, no MIT, estudar no grupo LOGO do próprio Seymour Papert, pra trazer o método pro Brasil. Eles montaram essa escola usando essa abordagem.

    E é aqui que eu ganhei na loteria.

    No curso eu aprendi LOGO (variante Microsol LOGO) e BASIC em máquinas Apple II (TK3000 e Exato Pro). Eu saia da aula todo dia e tentava refazer tudo o que aprendi no meu MSX Expert (que não tinha LOGO e tinha um dialeto diferente de BASIC).

    Depois eu ia para a casa daquele meu amigo que tinha um Apple II (um raríssimo Spectrum ED) onde ele já estava ralando pra aprender Assembly de 6502 (e eu ali do lado me aventurando junto).

    Em dezembro de 1989 eu concluí o curso na “Escola Inteligente” (é… era o nome da escola) e me formei em programação LOGO e BASIC aos 12 anos de idade. Alguns meses depois eu comecei a trabalhar como programador em uma imobiliária da cidade, mas isso é outra história.

    Conclusão

    Depois desse tempo todo eu acho que não importa se você vai ensinar programação com Scratch, Python, C/C++, Arduino ou pela eletrônica. O importante é que você consiga produzir feedback rápido e amplo por todo o caminho do aprendizado.

  • NULL

    NULL

    Quase todo desenvolvedor profissional vai ter que lidar com um banco de dados relacional ao longo de sua carreira. Os bancos de dados relacionais são uma daquelas ideias boas que a computação trouxe para o mundo.

    Obviamente esses sistemas possuem limitações e essas limitações se dão tanto no nível conceitual como nas várias implementações de SGBD exitentes.

    A limitação do modelo relacional existe porque não dá pra modelar o mundo que nos cerca usando conceitos tão “bidimensionais” como tabelas.

    Ok, eu sei que dá pra modelar 3D, séries temporais, hierarquia, graphos, etc em bancos de dados relacionais, mas você vão concordar que as coisas começam a ter que ser ligeiramente “enjambradas” nas tabelas pra isso funcionar. E o funcionar ainda pode trazer algumas limitações.

    Também tem as limitações de implementações do modelo. Os SGBDs ainda precisam saber se aquela coluna vai armazenar um texto ou um número e qual o tamanho esse dado vai ter.

    Mas tem um negócio que é praticamente onipresente nos bancos de dados relacionais. O NULL.

    O NULL serve para dizer que aquele dado, daquela coluna, naquela linha “não existe”. Não importa se essa célula de informação é um texto, uma data ou uma chave primária/estrangeira.

    Ele também é um tipo de dado “complementar”, ou seja, você não diz que uma coluna da tabela é do tipo NULL. Você diz que aquela coluna é do tipo X e também pode guardar um NULL. Ou seja, o valor NULL não é um tipo mas também serve a todos os tipos.

    O NULL também é usado para modelar as relações entre os objetos de duas tabelas. É ele que vem como resposta ou influencia o resultado dos famigerados LEFT|RIGHT|INNER|OUTER|... JOINs que tanto demoram pra entrar na cabeça dos desenvolvedores.

    O NULL é tão esquisito que força os programadores, tão acostumados com a lógica binária, a pensar em uma lógica com três estados.

    Esses problemas mencionados até aqui podem ser extendidos aos nil, None de várias linguagens de programação, portanto, a dica que eu vou dar pode se aplicar em outros contextos: se você puder evitar usar NULL, faça isso.

    Um exemplo do tipo de discussão sobre NULL causa aconteceu na nossa equipe. A gente está trabalhando em um sistema que cadastra perfis de cavalos. Então teremos nesse cadastro o nome do cavalo, a cor dele, a árvore genealógica, gênero, etc. Algumas dessas informações podem mudar ao longo do tempo (ex. um cavalo pode nascer de uma cor e mudar de cor na vida adulta). Outro problema que temos que lidar é com a fragmentação e qualidade dos dados das nossas fontes (ex. algumas base de dados que temos não informam a cor do animal).

    Considerando esses requisitos e limitações é bastante comum que programadores, por reflexo, saiam colocando várias dessas colunas como NULLABLE no banco de dados. Mas isso trás alguns problemas que eu pretendo demonstrar (provavelmente de forma incompleta) abaixo.

    Perda de Otimizações

    Alguns SGBD podem perder otimizações em cenários onde temos colunas NULLABLE. Esse artigo aqui (inglês) tem uma explicação mais detalhada de um desses problemas.

    O tipo de problema de otimização causado por colunas NULLABLE variam de SGBD pra SGBD, então recomendo que você faça uma busca por “nullable optimization [seu banco de dados]” no seu buscador favorito para entender o impacto do NULL no seu SGBD.

    Pobreza Semântica

    Quando usamos NULL no lugar de um valor real sabemos apenas que não temos aquele valor. Mas o que isso significa de fato? Não dá pra saber.

    Vou dar um exemplo bem simplificado para ilustrar melhor… Imagine que temos um site de e-commerce e na nossa tabela de produtos (ex. Product) a gente tenha uma coluna para guardar o diâmetro do produto (ex. diameter). Na sua loja virtual você tem produtos com essa característica (ex. parafusos, canos, etc) e produtos que não tem essa característica (ex. caixa decorativa, piso porcelanato, furadeira).

    A gente pensaria: esse campo é NULLABLE porque ele não precisa ser preenchido para todos os produtos.

    Mas o que o não-valor NULL significa de verdade nesse contexto? significa que eu “não sei o valor” porque ainda não medi o objeto que está cadastrado no meu banco de dados? Significa que o valor diâmetro não se aplica àquele produto porque ele é uma caixa? Significa que ele ainda está aguardando a informação porque ela é preenchida de forma assíncrona por outro serviço ou equipe?

    Não existe uma solução específica para adicionar mais semântica para esses dados. Existe um conjunto de técnicas e práticas que podem ser usadas pra resolver esse problema.

    No caso da cor do cavalo que comentei acima, temos uma Foreign Key (FK) para uma tabela de cores oficiais de cavalo (sim, isso existe), o ideal seria criar uma cor NOT_AVAILABLE na tabela de cores e referenciar ela quando não conseguirmos determinar a cor do animal. Mas a mesma solução não serviria para a data de nascimento dele.

    Como temos diferentes tipos de informação que podem ou não estar disponíveis precisamos criar uma modelagem específica para lidar com isso.

    Coalescing

    Quando dizemos que uma coluna é de um tipo específico podemos fazer nossas queries e nosso código sempre assumindo que o dado retornado é daquele tipo.

    Saber disso diminui a complexidade do nosso código porque não precisamos ficar lidando com um cenário excepcional onde o tipo do dado muda nem ficar convertendo esse dado de um formato para outro.

    NULL é inevitável

    Infelizmente nem sempre é possível evitar o uso de NULL. Eventualmente precisamos recorrer à ele ou preferir ele à outras opções.

    Se eu tenho uma coluna birthdate e nem sempre eu terei essa informação para preencher no meu banco de dados é preferível usar NULL do que armazenar uma data inválida tipo 00/00/0000. Usar uma data inválida só vai servir pra mudar a complexidade de lugar (quando precisar calcular a idade da pessoa preciso excluir datas zeradas pra não ter alguém com 2020 anos).

    No caso do diâmetro que eu mencionei acima, podemos usar um 0 pra sinalizar que o objeto não tem diâmetro. Mas fazer isso pode trazer problemas e complexidades para o sistema de shipping fazer o cálculo da volumetria do objeto pra calcular o frete. Nesse caso usar NULL pode fazer mais sentido (e usar uma segunda coluna pra adicionar semântica à esse NULL).

    Conclusão

    NULL não é inerentemente ruim e não estou desaconselhando ele. O objetivo desse artigo é só “desligar o automático” na cabeça dos desenvolvedores na hora de tornar uma coluna NULLABLE.

    E quando estiver usando NULL é importante redobrar a atenção com seu código e com seus dados.

    PS. NULL significa Zero em Alemão. Então eu abro exceção e tomo Coca-Cola Null Zucker (zero açucar) por aqui. 😉

  • Ensinando Testes

    Ensinando Testes

    Depois de algum tempo escrevendo código com testes automatizados eu comecei a considerar que cursos e livros sobre esse assunto fossem sempre um tipo de “falcatrua”. Achava que ensinar a fazer testes não fazia muito sentido.

    Mas quando abri minha empresa de consultoria e treinamento eu recebia vários pedidos de clientes para ministrar um “Curso de TDD” para suas equipes. Então resolvi desenvolver esse curso.

    Só uma observação: eu uso teste automatizado e não ao longo desse texto porque é importante saber que TDD é uma técnica de desenho e modelagem de código que usa testes automatizados mas tem muito software com testes automatizados que não foram criados com TDD.

    Voltando para o curso…

    O curso ficou bem legal e os slides estão disponíveis gratuitamente hoje em dia, já que não vendo mais ele e nem tenho mais a minha empresa.

    Ter desenvolvido esse curso mudou a minha visão sobre ensinar testes com cursos e livros? Não mudou.

    Prática vs. Perfeição

    Eu continuo achando que só é possível aprender a escrever testes na prática. E durante o curso, como vocês podem ver nesse slide, eu menciono isso para não alimentar falsas expectativas de que cada aluno ali seria um “mestre dos testes” após concluir o meu treinamento.

    Eu estabeleci um paralelo entre aprender escrever testes com aprender uma arte marcial. E usei a figura do Sr. Miyagi ensinando caratê pro Daniel San (ok, eu sei que sou velho mas me recuso a usar a figura do tira-casaco/coloca-casaco que ensinava Kung-Fu).

    E, tal como nas artes marciais, você não aprende a escrever testes em livros e cursos.

    Resolvi estabelecer uma proposta “ousada” para o curso: não ensinar a escrever testes.

    No lugar disso o curso daria uma fundamentação sobre o que é teste, pra que servem, a importância deles, e desmistificaria algumas bobagens que dizem sobre eles (ex. cobertura de 100% é essencial, código com testes não tem bugs, etc). Depois a gente teria algumas atividades práticas controladas (as tão temidas “dinâmicas”).

    Em uma dessas dinâmicas eu criava uma atividade parecida com a de um Coding Dojo com os alunos. O problema em todas as turmas era sempre o mesmo: converter números para algarismos romanos.

    Essa dinâmica baseada em Coding Dojo servia muito bem no processo seletivo de uma outra empresa onde trabalhei mas isso é assunto para outro artigo.

    Eu observava a dinâmica mas não trabalhava no problema. Eu tomava nota de algumas coisas da atividade e, no final, a gente discutia o que havia acontecido de errado, o que tinha dado certo e eu ia encaixando os tópicos de TDD para serem ilustrados pelo que eles experimentaram.

    Depois disso a gente passava por mais alguns fundamentos e retornávamos para a prática.

    A segunda atividade era escrever um encurtador de URLs completo na linguagem/framework que a empresa usava ou com o qual a maior parte da equipe estava mais familiarizada.

    Nesse momento a gente aprendia como organizar melhor os testes, como usar as ferramentas de teste e até como fazer TDD. Essa atividades levava de 1 a 2 dias e eram feitas em duplas (pair programming) que eram trocadas a cada 2 horas (o critério de troca era misturar abordagens das diferentes duplas com programadores(as) diferentes).

    Por fim eu indicava alguma literatura complementar (majoritariamente como referência) porque obviamente eles aumentam a sua compreensão sobre testes automatizados mesmo não sendo a fonte principal de aprendizado.

    Uma curiosidade sobre a dinâmica do Coding Dojo com o problema dos algarísmos romanos: eu ministrei esse treinamento para 5 turmas diferentes. Das cinco turmas que trabalharam no problema, cada uma delas entregou solução completamente diferente umas das outras. Todas funcionavam e atenderiam tranquilamente requisitos de performance, uso de memória, etc. Engraçado notar como pessoas e times possuem perspectivas tão distintas sobre os problemas apresentados.

    Não é fácil mas é possível

    Infelizmente é impossível aprender a escrever testes sem praticar. Mas eu garanto que vale a pena tentar.

    Vai ser frustrante e lento no início mas depois as coisas aceleram.

    E entenda que o seu “caratê” vai ser bem ruim no começo e, talvez, no futuro, ele fique ótimo. Você pode até chegar à faixa preta mas atingir a perfeição é impossível.

    Por conta dos seus testes serem ruins no começo eles vão gerar um grande esforço de manutenção. Aquele refactoring ou bugfix “trivial” vai te garantir horas de reescrita de testes. Desistir vai parecer uma ótima ideia nessas horas. E é aí que você vai precisar perseverar. Entenda que isso acontece porque seus testes ainda não estão muito bons (ou ainda que o seu código sendo testado precise de algumas melhorias).

    E quando você não conseguir mais programar sem testes você vai ver que valeu a pena.

  • Mercado saturado: isso importa?

    Mercado saturado: isso importa?

    Como me envolvi em vários eventos voltados para empreendedores nos últimos anos recebo e-mails de várias pessoas que pretendem desenvolver seus próprios empreendimentos. O perfil dessas pessoas geralmente é formado por programadores ou freelancers que tiveram uma idéia e querem desenvolve-la até que ela se torne um negócio.

    Recebo vários tipos de perguntas mas tem um tipo que me chama a atenção: “Você não acha que esse mercado está saturado?”.

    Essa pergunta me chama a atenção porque, por trás dessa aparência inocente, ela tem várias subquestões importantes como: mercado “oceano azul” vs “oceano vermelho”, mercado global vs local, ineditismo vs copycat, etc.

    Ineditismo

    Dia desses um amigo chegou com uma ideia interessante e disse que ia começar a desenvolve-la. Algum tempo depois eu fui perguntar pra ele como estava o andamento do projeto e ele me respondeu: “Ih! Desisti da ideia. O Google implementou um produto ‘igualzinho’.”.

    Eu achei a resposta interessante porque parece que as pessoas se esquecem que já existiam buscadores antes do Google 🙂 O que o Google fez para alcançar o domínio nas buscas foi criar um produto que funcionava melhor que os concorrentes.

    Mesmo com esse ótimo produto eles tem os seus concorrentes em buscas específicas como busca de ofertas (ex. Buscapé no Brasil), busca de estabelecimentos locais, etc. Eles tem concorrência até mesmo para o produto principal: DuckDuckGo (a participação de mercado é menor mas mesmo assim a empresa já é lucrativa).

    Quando uma grande empresa grande e poderosa resolve atacar no mesmo mercado e com um produto parecido com o seu significa que você, provavelmente, está com um bom projeto nas mãos! Essa concorrência deve ser encarada como uma validação positiva da sua idéia e não uma coisa para se lamentar. Eu sempre desconfio de empreendedores com idéias “que ninguém mais teve”.

    Outro exemplo: nós, programadores, conhecemos os serviços de hosting de código Github e Bitbucket, certo? Eles são os mais famosos e o Github é o maior player nesse mercado. Quando o Github nasceu o Google já tinha o Google Code Hosting.

    Mesmo assim colega resolveu criar um serviço desses e cobrar $9/mês para as pessoas usarem. Nasceu o Codeplane. O Codeplane nasceu porque ele tinha uma necessidade que não era atendida pelo Bitbucket/Github de forma satisfatória: ter dezenas de projetos pequenos para hospedar em repositórios privados.

    O Github cobra por cada repositório privado, logo, o custo seria enorme. O Bitbucket, na época, limitava o número de repositórios privados em apenas 5 por usuário. No Codeplane não. Você poderia ter quantos repositórios privados precisasse. O único limite era o espaço de armazenamento total.

    Ele criou um serviço útil para ele e para várias pessoas e ganhou dinheiro com isso. Independentemente dos “cachorros grandes” desse mercado.

    Diferenciais

    Uma coisa que é importante ter num mercado onde existe concorrência é o diferencial. O Google tinha como diferenciais a qualidade nos resultados das buscas e a velocidade com que elas eram feitas. O Codeplane tinha uma forma de cobrar diferente dos concorrentes. O DuckDuckGo também tem seus diferenciais.

    O simples fato de ter um serviço adaptado para a realidade brasileira, por exemplo, pode criar um diferencial. Mas tenha em mente que esse diferencial pode ser pequeno demais para impedir seus concorrentes de atacarem seu mercado.

    Copycats

    Criar um produto similar à outro pré-existente e colocar alguns diferenciais nele é bacana. O “copycat” puro e simples não é.

    O problema do copycat é que os seus clientes usarão o seu serviço até descobrirem o “original”. Se a empresa que fez o original for mais “poderosa”, provavelmente, terá condições de melhorar o produto deles num ritmo muito mais acelerado que o seu. Isso te deixaria para trás muito rápido na corrida pelo mercado.

    Oceano Azul vs Oceano Vermelho

    Existe um livro chamado “A Estratégia do Oceano Azul” (W. Chan Kim, Renee Mauborgne) que descreve o mercado como oceanos. Existe um oceano cheio de tubarões (concorrência) onde a briga entre eles é tão grande que tinge as águas de vermelho. E existem outros oceanos bem menos concorridos onde as águas ainda são azuis.

    O objetivo de todos os empreendedores que estão começando deveria ser o de navegar por oceanos azuis. Com pouca concorrência. Para fazer isso o livro sugere que segmente o mercado de maneiras diferentes e ofereça valores também diferentes para esse mercado.

    Analise os atributos de valor que os seus concorrentes oferecem para os clientes e tente realçar/eliminar alguns deles de modo a ter um produto único e diferente que sirva para pessoas que estão em mercados ainda inexplorados.

    Global vs Local

    Em vários artigos que falam sobre como começar um negócio você vai ler sobre “a necessidade de adaptar o produto para a realidade brasileira”. Não tem nada de errado com essa estratégia e ela pode até ser boa porque, inicialmente,  diminui os riscos do negócio.

    Mas eu acho que devemos nos arriscar mais e parar com esse pensamento pequeno. Com a Internet e os negócios voltados para tecnologia o custo de iniciar certos serviços em escala nacional ou global é muito parecido. E, me perdoe pela obviedade, o mercado global é muito maior que o brasileiro.

    Se a gente falar de um negócio que só adapta um que já existe em outro país a coisa fica ainda pior. Pode ser questão de (pouco) tempo para que a empresa global adapte o seu produto para a realidade brasileira e venha competir com você aqui no Brasil.

    E aí será uma briga de uma empresa local contra uma empresa global. É bem mais difícil ganhar essa briga, não acham?

  • Programador Freelancer

    Programador Freelancer

    Durante muito tempo da minha vida eu trabalhei como programador freelancer. Eu até tive empresa, sócio, etc. mas o fato é que eu era um freelancer como qualquer outro. Afinal eu vendia o serviço, elaborava proposta, negociava, executava o projeto, cobrava, emitia nota fiscal, e dava suporte. Durante esse tempo eu aprendi algumas coisas que gostaria de compartilhar.

    Freelancing não escala

    Trabalhar como freelancer é divertido e dificilmente enfrentamos problemas com a rotina quando trabalhamos desta forma. Não temos que lidar com a rotina porque cada projeto é único.

    Essa variedade de projetos é legal mas tem algumas desvantagens. Como eles são razoavelmente diferentes fica difícil reaproveitar o conhecimento adquirido durante a execução de um deles.

    Como o freelancer precisa aprender coisas novas em quase todos projeto perde-se boa parte do “ganho de escala” do negócio. E é o ganho de escala que permite reduzir custos que geram margens de ganho maiores ou preços menores para o cliente. Isso não é bom nem ruim. É uma característica inerente do trabalho do freelancer.

    Se o freelancer opta por “crescer” o negócio e montar uma empresa com vários funcionários (ou freelancers) precisa observar que ele pode até ganhar escala mas esse ganho será praticamente linear: para fazer 1 projeto precisa de 1 pessoa e para fazer 2 projetos provavelmente precisará de 2 pessoas.

    Você pode até mudar a inclinação do gráfico projetos x pessoas mas ele dificilmente se curvará.

    Você vende horas? Cobre por horas

    Uma armadilha bastante comum para freelancers iniciantes é a de negociar um contrato com um escopo fechado. A coisa piora se o escopo não estiver muito detalhado.

    Essa armadilha é mortal porque na imensa maioria dos casos o contrato vincula o pagamento do serviço à entrega do escopo. E, acredite, os clientes vão expandir esse escopo ao ponto de tornar o projeto prejudicial para o freelancer.

    Eu sei que é difícil negociar um contrato baseado em horas de trabalho mas você tem que negociar nesses termos. É melhor não pegar o projeto do que negociá-lo por escopo e/ou vincular o pagamento ao escopo.

    Sei que isso é bem complicado porque as contas para pagar chegam todos os meses sem piedade e aquele contrato com escopo fechado oferece uma oportunidade de ter dinheiro para pagar essas contas. Mas no médio prazo você pode acabar se tornando um escravo do projeto e ficar trabalhando de graça nele (ou até pagando para trabalhar).

    O melhor para você e para seu cliente é trabalhar com entregas parciais em intervalos curtos e rápidos. Isso nos leva ao próximo ponto…

    Atualização: logo depois que enviei O Melhor da Internet o meu amigo Elvis enviou um link para um artigo que ele escreveu onde ele ressalta o fato de que um freelancer raramente consegue vender 100% das suas horas disponíveis.

    Atualização 2: Depois que o artigo foi publicado me lembrei de uma outra dica importante relacionada à esse tópico. Quando você está elaborando a proposta e negociando o projeto é importante incluir o tempo usado nesse processo no valor final do projeto. Se você não fizer isso essas horas sairão “de graça” para seu cliente. Para isso funcionar direito as propostas também precisam ter um prazo de validade que permita uma revisão de valores nos casos onde a negociação demora muito.

    Não cobre “50% no início e 50% na entrega”

    É uma prática bem comum trabalhar dessa forma: o freelancer recebe 50% quando inicia o projeto e o restante quando entrega ele pronto.

    Existem duas pegadinhas nesse modelo: uma é o conceito de pronto (veja o tópico anterior) e a outra tem relação com um negócio chamado fluxo de caixa.

    Uma das coisas que certamente mata uma empresa é a má gestão do seu fluxo de caixa. E um freelancer é uma empresa de uma pessoa só. Precisa gerenciar seu fluxo de caixa com muita atenção.

    Quando você fecha um negócio e recebe por ele 50%+50% fica mais difícil de gerenciar o fluxo de caixa da empresa porque a segunda metade do pagamento vira um alvo móvel. Quando você vai entregar o projeto? Quando ele estará “pronto”?

    No lugar de negociar 50%+50% prefira receber parcelas em intervalos regulares (mensalmente? quinzenalmente?). Pode-se até vincular os pagamento às entregas parciais do projeto.

    Receber pelo trabalho em intervalos regulares e vincular isso às entregas parciais é o cenário perfeito porque facilita a gestão do fluxo de caixa do freelancer e aumenta a segurança do cliente que pagará por algo que já recebeu.

    “Produtize” seus serviços

    No primeiro tópico eu falei sobre o problema de escala associado ao freelancing e aqui eu vou apresentar uma forma de amenizar esse problema.

    É raro mas acontece: quando um freelancer está trabalhando no seu milésimo projeto ele percebe que certos padrões surgem em todos eles. Exemplo: quase todos os projetos tem um formulário de contato, ou uma página com um mapa mostrando a localização da loja do cliente, ou tem algum sistema de monitoramento, backup, etc.

    Quando o freelancer detecta um padrão desses ele pode ter certeza que existe uma oportunidade de transformar essa parte do projeto em um produto que pode ser vendido para vários clientes. Se você fizer isso vai ter um ganho de escala ou até mesmo alguma receita recorrente.

    Certos projetos também são genéricos ao ponto de poderem ser transformados em produtos (com a devida anuência do cliente contratante). Um exemplo? Um dos meus clientes solicitaram o desenvolvimento de um sistema de avaliação de funcionários para o RH da empresa.

    O sistema usava uma metodologia conhecida como “Avaliação 360°” e gerava relatórios para o RH da empresa avaliar os seus funcionários. O sistema foi desenvolvido para um cliente específico mas, certamente, poderia ser útil para outras empresas. Não foi o caso mas esse projeto poderia ter se transformado em um produto.

    Outros tipos de produtos que você pode criar estão na forma de conteúdo. Em meu caso, por exemplo, escrevi um livro e criei um video-curso de programação Python e Django para vender na Internet (que, por não manter mais, acabei disponibilizando gratuitamente).

    Crie receitas recorrentes

    Todo negócio tem seu risco e com o freelancing não poderia ser diferente. Quando o freelancer está trabalhando e vendendo suas horas de trabalho para alguém as coisas ficam bem. Mas quando, por algum problema, isso não acontece as coisas podem ficar bem complicadas.

    Um freelancer pode adoecer, o mercado pode dar uma esfriada, pode acontecer uma entresafra de projetos (ex. o período de novembro a março costuma ser difícil para novos projetos).

    Uma maneira de lidar com essas dificuldades é cuidar para poupar nos períodos fartos para ter algo nos períodos difíceis como na fábula da Cigarra e das Formigas. Outro modo de lidar com essa questão é criando formas de se obter receitas recorrentes.

    Ofereça serviços de manutenção, suporte, apoio, etc para os clientes que desenvolveram projetos com você. Crie mecanismos (honestos) para continuar recebendo dinheiro deles mesmo depois que o projeto tenha terminado. Ou crie algum produto (tópico anterior) que seja vendido na modalidade de assinatura.

    Recuse clientes ruins

    Essa é uma das coisas mais difíceis de colocar em prática porque, a menos que alguém nos avise, é quase impossível saber se um cliente novo é bom ou ruim. Mas alguns indícios podem ser observados:

    • Cliente que questiona demais os preços – pode ser uma preocupação legítima mas geralmente não é. Mostra que é um cliente mais preocupado com preços do que com qualidade. Ele vai apertar os seus ganhos e vai te trocar por outro mais barato na primeira oportunidade.
    • Cliente que não sabe o que quer e não te ouve – existem muitos clientes que não sabem exatamente o que querem e isso isoladamente não é um problema. Mas se você tentar ajudá-lo a descobrir e ele recusar a sua ajuda isso pode virar um problema.
    • Cliente que descumpre o combinado – você estabelece com o cliente que ele te pagará mensalmente e no dia do pagamento você tem que ficar lembrando e cobrando. Ou cliente que simplesmente te dá um calote. Eu costumava fazer um teste: eu “esquecia” de cobrar os meus clientes algumas vezes. É engraçado mas os meus melhores clientes sempre me enviavam e-mail avisando sobre meu “esquecimento”.
    • Cliente que oferece uma “oportunidade única” de trabalhar para ele – tem muito cliente que pede um precinho camarada em um primeiro projeto com a promessa de valores maiores em projetos futuros. Não caia nessa armadilha porque esse cliente não é fiel à você. Ele é fiel ao teu preço baixo. E não se engane… tem muita empresa grande e famosa que usa o próprio nome para obter essas vantagens. Se usarem o discurso do “você vai colocar a nossa empresa no teu portifólio!” respondam de forma sarcástica: “eu já gastei a minha verba de marketing para esse ano”.

    Para clientes pré-existentes é sempre importante gastar algumas horas do mês para reavaliar a sua carteira de clientes e projetos. Cliente bom é aquele que cumpre com suas obrigações, gera bons projetos, indica você para novos clientes e te dá um bom lucro.

    Automatize as tarefas chatas

    Coisas chatas que freelancers precisam fazer e precisam ser automatizadas o mais rápido possível:

    Responder e-mails de sondagem

    Eu recebia muitos e-mails assim: “Oi, Meu nome é Fulano e gostaria de saber quanto você cobraria por um projeto assim e assado”. Você tem que responder à esses e-mails mas 80% deles são de aventureiros. Pessoas que não tem dinheiro para te contratar, não sabem o que querem e não vão fechar negócio contigo.

    O problema é que não dá pra você diferenciar as boas oportunidades daquelas que vão fazer você perder tempo.

    Um das coisas que funcionou razoavelmente bem comigo foi colocar informações detalhadas sobre o tipo de projeto que eu desenvolvia e um valor aproximado para minha hora de trabalho no site da empresa. Colocava destaque na informação: “Esses valores são negociáveis”.

    Com essas informações a pessoa já consegue ter uma idéia se ele consegue contratar o seu serviço. A outra informação (valores negociáveis) filtrava os aventureiros daqueles que realmente queriam realizar o projeto.

    O cara pode até não ter o dinheiro para te contratar mas se ele quiser muito realizar o projeto ele vai entrar em contato contigo para tentar negociar o prazo de pagamento, os valores, o escopo, etc. E isso, por si só, mostra que ele pode ser um bom cliente e gerar negócios.

    Algumas pessoas (por medo ou desconhecimento) acreditam que essas informações no site afugentam clientes. Pode ser que sim. Mas pergunte-se: “Que tipo de cliente eu estou afastando?”.

    Produzir e enviar propostas

    Depois que você entende melhor o projeto é o momento de enviar uma proposta para seu cliente.

    Se você ainda estiver negociando projetos com escopo fechado fica impossível automatizar essa etapa porque cada proposta será única e precisará ser bem detalhada, mas se você negociar em termos de horas a proposta fica bem mais simples. Você precisa apenas preencher os milestones do projeto (entrego X na data Y, …) e fazer uma multiplicação de horas pelo teu valor/hora.

    Eu tinha um template no meu editor de textos onde eu só alterava os dados, gerava um PDF, e enviava para o cliente. Se o cliente já era antigo, muitas vezes, eu só mandava um e-mail: “imagino que dê pra gente trabalhar nisso em uma semana por R$X”. E o cliente respondia: “Ok, pode fazer”. Esse é o tipo de relação de confiança que você precisa construir com seus clientes.

    Cobrança e NFe.

    Cobrar o cliente e ver se ele pagou é uma daquelas coisas que nunca consegui automatizar 100% mas cheguei à um ponto onde isso não atrapalhava o resto das atividades.

    Eu criei uma conta de cobrança sem registro na conta da empresa no banco (dica: não misture sua conta pessoal com a conta usada para seu trabalho) e emitia boletos para meus clientes pagarem. Cerca de 5 dias depois da emissão dos boletos eu puxava um extrato e conciliava os pagamentos na mão. No site da prefeitura eu emitia as NFe daqueles que haviam pagado o boleto.

    Comecei com um software que só emitia os boletos e depois migrei para outro que emitia os boletos e a NFe.

    Seja parceiro dos bons clientes

    É provável que você não consiga resolver todos os problemas de seus clientes e, nestes casos, você deve ajudá-lo a encontrar as soluções para esses problemas. Mesmo que para isso você tenha que encaminhá-lo para um outro prestador de serviços (freelancer, empresa, etc).

    Se você fizer isso o cliente criará um modelo mental muito positivo sobre você: “quando eu tenho um problema é só eu entrar em contato com esse cara que ele resolve ou me ajuda a resolver”. Esse modelo mental é poderosíssimo para gerar novos negócios.

    Cumpra combinados e faça com qualidade

    Deveria ser o primeiro item mas resolvi deixá-lo para o final para que fique mais fresco na sua memória.

    É da mais absoluta importância para um profissional que ele cumpra aquilo que foi combinado com o cliente. E mais do que isso… é importante que tudo seja feito com a maior qualidade.

    Cumprir com o combinado manterá o seu cliente fiel à você. Fazer isso com qualidade transformará ele num canal de vendas.