Mês: agosto 2013

Enfim, Ágil

Introdução

Lembro a primeira vez que tive contato com alguma metodologia ágil, em 2004. Naquele momento, a primeira prática que mais me trouxe resultado foi a integração contínua, mas o XP também falava de uma série de outras coisas. No meu post sobre TDD, relatei as tentativas de incorporar esta prática e o tempo que levou até entender o real benefício dela (no meu caso, fui bem cabeça-dura).

Das práticas mais confusas, a parte de estimativas do XP talvez seja a mais revolucionária. Mudar a idéia que eu já tinha na na época de cronograma, planejamento, levantamento detalhado de requisitos era muito pra mim. Quando eu percebi que a metodologia não mais daria aquela “certeza” de que a coisa aconteceria no prazo, logo conclui que o mercado nunca iria aderir àquilo, pois o modelo de comercialização seria muito complexo de implementar. Mas sempre achei que a XP descreve o que melhor funciona no mundo de software.

7 anos depois

Um bom tempo depois, numa das empresas que trabalhei, houve uma tentativa de implementação de SCRUM. Eu tinha lido muito pouco sobre o assunto, dada a conclusão precipitada que tive sobre a dificuldade de comercialização do SCRUM. Como trabalhava numa empresa que tinha um viés de desenvolvimento de produto (apesar das customizações por muitas vezes fazerem a empresa funcionar como uma consultoria que vendesse projeto a preço fechado), havia uma preocupação com a qualidade e com o acompanhamento dos projetos.

Foi engraçado ver tanta parede com post-it pregado e diversas reuniões, mas não consegui ver o entusiasmo nas pessoas e uma mudança cultural profunda. Depois entendi o que aconteceu. Foi mais uma daquelas situações que um processo é totalmente personalizado pra encaixar na empresa, o processo não funciona e posteriormente a coloca-se a culpa no processo. No Scrum inventaram até um nome pra isso: Scrum, but…

E o cascata, funcionava?

Eu sempre fui um defensor de trabalhar com projetos em fases menores no cascata (entregas menores e mais frequentes) e de levantamento de requisitos exaustivos (meu post, levantamento de requisitos mostra isso) e de fato consegui alguns resultados interessantes, mas minha experiência me mostrava que algumas coisas não iam tão bem assim.

O custo para montar um cronograma completo no início do projeto era enorme. Era de semanas a meses pensando atividade a atividade, quem iria fazer. Não foram poucas as vezes que “desenvolvedores virtuais” aparecerem no cronograma, contando que em algum momento eles seriam contratados, treinados e entrariam no projeto funcionando e jogando.

Sempre que alguma mudança ocorria no meio do projeto (o que acontecia com frequência, porque em desenvolvimento de software, requisitos mudam!) era um esforço enorme pra replanejar.

Numa empresa que trabalhei, percebi uma das maiores falhas do levantamento de requisitos exaustivo no início do projeto. Eu trabalhava para capturar os requisitos, escrevia casos de usos detalhados e os usuários validavam. Quando apresentávamos o software, ficava uma discussão quase contratual, pois o cliente alegava que não era o que ele precisava e o desenvolvedor alegava que era o que estava escrito. O cliente desejava melhorias no que foi entregue, porém, não existia o “espaço” no cronograma para tais melhorias, e voltava a discussão ao cronograma. Os dois estavam certos. Nova mudança, novo replanejamento, o que significava outro ciclo infinito de reuniões para discutir o cronograma, alinhar expectativas.

De fato, foram semanas discutindo cronograma e o que fazer. O tempo de alinhamento versus construção era desproporcional. Perdia-se mais tempo discutindo o que fazer do que de fato fazendo. O resultado final foi uma equipe frustrada, a consequente debandada e a paralisação de uma série de projetos.

Enfim, ágil

Recentemente, após uma mudança de área, passei a trabalhar com a abordagem ágil. Começamos com mais um Scrum But, ou seja, aplicando o Scrum somente na fase de desenvolvimento do projeto, e aos poucos fomos mudando para um modelo de inserir o usuário nas reuniões, nas discussões e estimulá-lo a exercer um papel de product owner.

Confesso que eu comecei meio cético no projeto, remetia ao passado, à brincadeira de mexer post-its e não conseguia entender como isso ia me ajudar a fazer software melhor. Eu recebi um release planning praticamente pronto, e fomos para nosso primeiro sprint planning.

Foi um pouco assustador, um time, pela primeira vez junto, num projeto que poucos tinham contexto discutindo como as coisas seriam feitas. Não conhecíamos o método, não conhecíamos o projeto e fomos com a cara e a coragem. Discutimos as atividades, estimamos (de forma errada, pois não tínhamos as estórias estimadas e sim as atividades). Erramos nas estimativas das primeiras sprints, mas já começávamos a observar as dificuldades. Na retrospectiva, apontamos as dificuldades, melhoramos o processo e assim seguimos.

Oito sprints depois (sprints e 2 semanas), já trabalhamos como um time muito mais integrado, estamos acertando nas estimativas (usamos os dados históricos), estimamos as estórias e o time está bastante satisfeito com o design da aplicação. Estamos fazendo TDD, Integração contínua, pair programming pois conseguimos nos organizar para tal, e apesar de um “Scrum but”, a coisa vem caminhando muito bem. O que de fato mudou?

Aprendizados

Pessoas

Trabalhar em equipe não é uma coisa fácil. As cerimônias de sprint planning, daily meetings e retrospectivas promovem isso. É praticamente impossível chegar ao fim dessas cerimônias sem interagir. Os medos, dificuldades aparecem e a sujeira sai debaixo do tapete.

Inspeção

O Burndown Chart e o Kanban, são ferramentas fantásticas. Elas vão constantemente mostrando ao time o seu progresso. Como foi o time quem deu as estimativas e se comprometeu com a sprint, o incômodo é generalizado. Enfim, o processo promove uma forma de você visualizar o que realmente está acontecendo, ou seja, se o time irá conseguir atingir a meta ou não.

O Kanban, recomendo que seja físico. Ele exerce uma pressão psicológica violenta quando mostra o real andamento do projeto, além do fato de ajudar a definir o foco, ou seja, estar constantemente mostrando o que é prioritário e o que precisa ser feito.

Após essas sprints, adotei o Kanban como ferramenta de planejamento para outras atividades (não relacionadas a desenvolvimento de software). É muito mais fácil visualizar e ajustar prioridades movendo post-its do que num Excel, além do fato que o Kanban é compartilhado e evita aquele tipo de reunião em que a equipe fica batendo papo enquanto uma das pessoas fica digitando no Excel.

Empowerment

O processo do Scrum ajuda a equipe a obter compromissos que pode cumprir e a dar poder para o time trabalhar. Isso automaticamente faz com que o time busque os recursos para ser mais performático.

Daily Meetings

Os daily meetings são muito importantes. Primeira regra é realizá-los dentro do tempo (15 minutos). Os grandes benefícios do daily meeting pra mim estão no alinhamento e no “pega-lazy”. Quando existe um membro do time que não está jogando para o time, o daily meeting rapidamente mostra isso. A pessoa fica enroscada na atividade e não apresenta o impedimento no daily meeting durante, 3, 4, 5 dias. Geralmente no último dia vem com alguma desculpa do porque não conseguiu realizar a atividade.

Peer pressure

No Scrum, não existem adividades com “donos”. O time é dono das atividades, logo, o time atinge o objetivo ou não. Nesse cenário, começa a ocorrer a pressão entre os pares. No cenário que eu citei acima, do daily meeting, o próprio time começa a se mobilizar para expelir o descomprometido do time. Assim como na existência de um problema, o time começa a buscar os mecanismos para resolvê-lo, pois ninguém quer perder a meta.

Líder facilitador

Observamos que num ambiente ágil não cabe a figura tradicional do chefe. Com o time se auto organizando e entendendo seu papel, o líder passa a ser um facilitador. Ele precisa desenvolver grande habilidade para mediar conflitos, buscar recursos e criar condições para o time trabalhar.

Datas?

É interessante ver como a metodologia tradicional de gestão de projetos criou uma cultura de cravar datas na pedra e exercer cobranças até que a atividade saia no prazo (usando a qualidade para pagar o preço). O Scrum, quando transparece as atividades que precisam ser realizadas, o esforço estimado e a velocidade do time, começa a trazer mais ferramentas que ajudam a visualizar se o objetivo será ou não atingido.

Aquelas situações que visualizamos do gerente perguntar o percentual de conclusão da tarefa, e este percentual ser reportado na progressão: 50%, 75%, 90%, 91%, 92%, 93%, 93.5% perdem o sentido. Como disse anteriormente, o Scrum tira a sujeira debaixo do tapete.

O que começa a ficar evidente é que o responsável pelo projeto precisará de fato aprender a negociar prioridade, escopo ou recursos para a realização do projeto, invés de somente exercer cobranças.

Mudanças de escopo

Mudanças de escopo são bem-vindas. No Scrum, a priorização do backlog simplifica a inclusão de novas estórias e repriorização das mesmas, assim como simplifica a medição dos impactos causados pela mudança. Se você ainda tem uma data alvo, e as mudanças não param de acontecer, o Scrum sem dúvida irá ajudá-lo a mostrar as mudanças e repriorizações e também quando estas impedirão a data alvo de serem atingidas.

Exercício constante de valor agregado

O processo, quando começa a sensibilizar os envolvidos do que está acontecendo (transparência) e mostrar o real custo para se entre

Conclusão

Se você tentou implementar o Scrum em seu time e fracassou, certifique-se se você não entortou o processo. Minha experiência com TDD e com Scrum me mostram isso.

Apesar de ainda estar trabalhando com uma variação de Scrum, é muito interessante observar como o jeitão de trabalhar é muito mais alinhado com trabalho em time, o que nos mostra que a soma dos membros do time é muito maior do que a contribuição individual. Transparência também é um valor fortemente promovido pelo processo.

O processo é feito de uma forma que promove a melhoria contínua, o que me faz acreditar que ainda há muito o que aprender e aprimorar, mas os resultados imediatos são evidentes.

O processo obviamente não ensina as pessoas a desenvolver software. É importante se apoiar em outras disciplinas e processos de engenharia de software (como as práticas de XP) para obter bons resultados. Também não é a bala de prata e vai resolver todos os problemas, mas de uma coisa eu não tenho dúvida: o Scrum cria um ambiente muito mais favorável à resolução de problemas, ao trabalho em equipe e ao desenvolvimento de software de qualidade.

Outra coisa muito importante é que cada vez mais processos ágeis como o Scrum e o Lean estão sendo adotados para desenvolvimento de produtos e não só por empresas de software.

Parece que realmente o Scrum veio para ficar. A discussão ainda de qual processo é melhor, waterfall ou Scrum para gestão de projetos (não somente projeto de software) ainda será muito promovida, e até aqui minha opinião é muitos simples: Projetos com alto grau de certeza terão melhores resultados com waterfall. Projetos com alto grau de incerteza terão melhores resultados com ágil.

Fazendo as pazes com TDD (Test-Driven Development)

Introdução

A primeira vez que eu ouvi falar de TDD foi em 2004. Na época, trabalhava com Delphi ainda. Um colega da minha equipe trouxe o livro do Kent Beck, traduzido em português (acho que era esse: Programação extrema aplicada), sobre XP e estávamos querendo revolucionar como as coisas eram feitas.

Na época, principalmente em Delphi, pouco falava-se de design de software. Orientação a objetos, SOLID era uma coisa muito falada e pouco entendida. Foi um dos meus primeiros projetos que tentei fazer uma separação real de UI da lógica de negócio, criando objetos de domínio.

Foi um tempo muito divertido, e motivado pelas idéias do Beck fiz minha primeira implementação de integração contínua: um arquivo .bat, rodando um script no “want” (uma versão de ant para Windows, bem aderente ao Delphi. Não acho um link sobre isso mais!) no agendador da máquina (Windows) e no cron da máquina (Linux), pois o projeto era multi plataforma.

Outra coisa que aplicamos foram os testes associados ao build usando o DUnit.

A primeira experiência com testes

Neste projeto, conseguíamos testar os objetos de domínio, pois a UI estava totalmente desacoplada dele, porém, por um erro de design, a persistência não era desacoplada da lógica de negócios, o que automaticamente forçava os testes a dependerem de banco.

Usávamos então um setup que criava registros no banco e forçávamos os testes a executarem em ordem para que tudo passasse. Os testes foram muito úteis porque o projeto também era multi-banco e dessa forma, conseguíamos testar se nossa persistência funcionava em todos eles.

Não demorou muito para os testes começarem a ser abandonados, pois era trabalhoso demais criar os testes, eles eram muito lentos pra executar e praticamente todos orientados ao banco de dados (como era o pensamento que imperava na época).

Tive uma experiência negativa do processo.

As experiências posteriores

Dali pra frente (já em .NET), sempre adotei os testes como uma prática opcional. Quando tinha alguma regra de negócio mais complexa ou componentes de infraestrutura sempre criava os testes após o desenvolvimento. Como já tinha alguma experiência, tinha facilidade em visualizar o design up front.

Óbvio que depois os testes sofriam um viés muito forte daquilo que já estava desenvolvido. Ajudava bastante, mas sem saber estava praticando “design done by tests“.

Fazendo as pazes com TDD

TDD-280_largeRecentemente, resolvi prestigiar o trabalho do Maurício Aniche. Ele escreveu o livro Test-Driven Development: Teste e Design no Mundo Real. Confesso que eu comprei o livro porque eu conhecia o Aniche pessoalmente e queria prestigiar o trabalho de um brasileiro. Só não esperava que eu iria me deparar com um livro extremamente bem escrito e com um ponto de vista para mim novo sobre TDD: Os testes influenciam o design.

O livro me ajudou a entender que quando escrevemos os testes antes do código, o teste vai nos forçando a criar um bom design, vai forçando o SOLID a ser aplicado no nosso código.

Isso acontece porque se você está com dificuldade de pensar ou de criar o teste, é porque provavemente suas reponsabilidades não estão bem separadas, ou você não está invertendo as dependências corretamente.

O teste é quem vai te contando isso na prática. O grande problema é aprendermos a dar ouvidos ao que a prática nos diz.

Como funciona isso na prática?

Se eu de fato tivesse aprendido a aplicar o TDD corretamente na minha primeira experiência, teria percebido que se eu estou dependendo do banco de dados pra fazer um teste de regra de negócios, algo está errado. Esse é o tipo do sintoma que tendemos a ignorar por causa do apego que acabamos desenvolvendo ao nosso design.

O mesmo acontece com qualquer dependência externa. Um arquivo, um web service, qualquer coisa desse tipo pode ter suas dependências invertidas para ser corretamente testada. No código do MSBuildCodeMetrics, tive uma situação similar para testar as tasks sem depender do MSBuild.

Testes de integração não são ruins, mas se você não tem unidades, não consegue fazer testes de unidade. Esse é um dos grandes benefícios.

Se eu também tivesse lido um pouco mais e procurado na comunidade informações sobre como aplicar melhor o princípio, descobriria coisas importantes como a atomicidade dos testes. Os testes não podem depender de outros testes, o que tornou a manutenção dos mesmos muito difícil.

Documentação do Design

O TDD também nos ajuda a documentar a nossa “intenção” quando criamos um design. Esse é outro grande benefício. Um exemplo que eu gosto de dar é:


public Cliente localizarClienteComMaiorVolumeDeVendas(IList<Pedido> pedidos){
}

No método acima, qual o comportamento você espera quando nenhum cliente é encontrado (Ex.: lista de pedidos vazia)? Você espera que o método retorne null ou dê um throw numa Exception? Os testes conteriam essa resposta. E melhor ainda, se alguém mudar este comportamento no método, o teste quebrará, o que garantirá a evolução deste design no decorrer do tempo e evitar bugs indesejados.

Produtividade

Produtividade é um critério que sempre gera muita discussão na comunidade de desenvolvimento. Ela aparece em diversas discussões: arrastar componentes invés de criar código manualmente, utilizar ferramentas de migração de código e não podia ser diferente, nos testes. A grande pergunta é se o tempo que os desenvolvedores perdem escrevendo teste paga os benefícios ou não. É bastante intangível isto, apesar de existiram muitas pesquisas discutindo os benefícios, essa discussão aparece.

Após ler o Clean Code e o The Clean Coder, do Uncle Bob, eu me convenci facilmente que qualquer desenvolvedor profissional deveria praticar TDD, assim como me convenci que a grande dificuldade de falar sobre produtividade em software é que confundimos o custo do primeiro release com o custo do software.

Deixa eu tentar explicar melhor: sempre pensamos em produtividade no tempo que o produto demora pra ficar “pronto”, ir para o ar, subir e começar a trazer dinheiro ou resultado. Mas quanto custa evoluir este produto depois?

Sempre que o código apodrece (termo usado pelo Uncle Bob), o custo para mexer em qualquer coisa é exponencial. Começam a surgir bugs nos lugares mais improváveis e cada vez mais tendemos a querer jogar tudo fora e reescrever o software todo. Qual o custo disso?

A forma mais simples de entender essa questão da produtividade vem do gráfico abaixo. É um gráfico de produtividade em relação ao tempo:

Clipboard02

A idéia é que no começo, quando você não carrega nenhum código podre, sua produtividade é 100 e com o decorrer do tempo ela tende a nada. Minha experiência empírica me diz que isso é verdade.

As práticas de XP (TDD, Integração Contínua, Refatoração) são aliados importantes para ajudar o gráfico acima se tornar uma reta e não ter a cara de um logarítmo. Na partida, nos sentimos mais lentos, mas com o decorrer do tempo, a produtividade se torna constante.

Era isso!

Ensaio sobre carreira

Introdução

Sempre tive uma certa resistência em tentar escrever algo aqui sobre carreira. Acho que minha dificuldade vem da minha concepção de liderança por exemplo. Acho que seria muito ruim escrever sobre, sei lá, sucesso ou tentar dar conselhos sobre por qual caminho seguir sem estar necessariamente seguro do próprio sucesso ou de qual caminho seguir.

Mesmo assim, resolvi compartilhar aqui um pouco da minha experiência com o objetivo de ajudar companheiros de profissão a encontrarem também seu caminho ou talvez evitar algumas frustrações e escapar de algumas armadilhas.

Se vc tiver paciência pra chegar até o final do post, peço a gentileza de me mandar suas impressões, por e-mail, twitter, comentário no blog. O que achar válido, mas já aviso que o post vai ser longo…. 😉

Motivação

Apesar de longo, e até um pouco antigo, esse vídeo do Dan Pink merece ser visto até o final. Ele mostra alguns estudos que mostram como o modelo de recompensa tradicional (oferecer dinheiro ou prêmio em cumprimento de uma meta) funciona muito bem para trabalhos repetitivos (algorítmicos) e como ele é ineficiente para trabalhos criativos ou heurísticos.

Vídeo: Dan Pink e a surpreendente ciência da motivação

A primeira vez que eu vi esse negócio, caiu que nem um meteoro na minha cabeça. Agora estou lendo o livro “Drive – The Surprising Thuth About What Motivates Us”. Impressionante como esse livro vem sendo citado por muitos caras de software e em eventos de agilidade. Não é à toa.

419tQKzU2jL._SY346_PJlook-inside-v2,TopRight,1,0_SH20_

No “Drive”, o autor traz a idéia que no século XX existia uma grande demanda por trabalho repetitivo. Não existia tanto desenvolvimento, tantas ferramentas e ainda era muito necessário o trabalho humano repetitivo e braçal. E rapidamente, o homem inventou um “sistema operacional” para este modelo. O modelo de recompensa, geralmente financeira para o batimento de uma meta.

Com o progresso, cada vez mais o trabalho criativo é necessário. Para o crescimento das empresas, não mais é necessário somente trabalhar muito, mas pensar em soluções, desenvolver novas formas de fazer negócios, criar novos produtos, e como mostrado no vídeo acima e no livro, o modelo de recompensa tradicional não funciona para estes casos.

O ponto é que, como bem exemplificado, os negócios ainda não fazem o que a ciência descobriu.

As diferentes tribos de desenvolvedores

É curioso como uma mesma profissão pode acomodar perfis completamente diferentes de profissionais. De um lado temos pessoas extremamente comprometidas, preocupadas em tornar o trabalho do desenvolvedor mais profissional, estudando pilhas de livros, cruzando o país várias vezes ao ano para participar de eventos, desenvolvendo projetos open source, participando de dojos e tantas outras coisas (grupo A), e do outro profissionais que trabalham com tecnologias defasadas, cada vez mais repetindo o mesmo estilo de programação, sem se preocupar em aprender nenhuma tecnologia nova ou conceito novo (grupo B).

Minha conjectura, após conhecer a teoria do Dan Pink, é que isso é facilmente explicado pelos “sistemas operacionais” que ele descreve.

Faz muito sentido para o desenvolvedor do grupo B, motivado por recompensa funcionar da forma que ele funciona. Quanto pior a qualidade do código que ele escrever, mais problema o sistema vai dar. E obviamente mais vão precisar dele para corrigir. Quanto mais rápido ele codificar e mais rápido entregar o projeto desde que passe nos subjetivos critérios de aceitação, melhor pra ele. E em muitas empresas ele será recompensado por isso! Em resumo, ele entrega com uma qualidade ruim, no prazo, ganha bônus e ainda garante o emprego para o resto da vida.

Na outra extremidade faz muito sentido para o desenvolvedor do grupo A, motivado por propósitos se inconformar com a postura do desenvolvedor B. Ele é motivado por ver o software funcionando, ver a empresa funcionando, ver a sociedade, o companheiro de equipe tendo algum benefício com isso. Para ele, a recompensa é o próprio resultado do trabalho. Pode ser que lendo, você não entenda que alguém pense assim, mas se ainda não viu, por favor, veja o vídeo acima.

De fato, já ouvi várias vezes a resposta “porque eu preciso do dinheiro” para a pergunta “qual sua motivação?”. Isso pra mim de certa forma me dá mais segurança na minha conjectura.

A pílula vermelha ou a pílula azul

É duro parafrasear o Matrix, mas você vai ter que escolher uma delas e cada escolha é exclusiva. O importante aqui é saber o preço de cada escolha. Você pode encarar a realidade, dura e pagar o preço por sua escolha ou viver pulando de empresa em empresa em busca do Nirvana.

Grupo A

Se sua cabeça funciona como o grupo A, você tem duas escolhas. Buscar empresas que trabalhem com desenvolvimento de um produto, startups com modelos de negócio fortemente apoiadas em TI ou empresas que tenham TI dentro de casa. Geralmente estas empresas, por sofrerem diretamente o prejuízo de má qualidade de software, tendem a ser mais sensíveis a este discurso. Como nem tudo são rosas, saiba que essas empresas geralmente são menores, pagarão salários menores e terão maior risco de passarem apertos em cenários de instabilidade econômica. Busque empresas que trabalhem com metodologia ágil e fuja do modelo de recompensa orientado a metas por entrega no prazo. Esse modelo gerará sempre o conflito qualidade x prazo.

Se você realmente for um cara cabeça-dura e insistir em não querer correr o risco citado no parágrafo anterior, ganhar grandes salários e trabalhar em empresas grandes, você pode procurar grandes instituições financeiras (fortemente orientadas a metas e com bônus) e prestadoras de serviço de software (que pagarão bem pela sua capacidade de recuperar projetos caóticos ao custo de sua saúde). Acostume-se a ser chamado de: perfeccionista, preciosista e profissional de baixa resiliência. Tome cuidado pois durante os vários conflitos de entrega de qualidade x entrega no prazo você poderá ser visto quem está jogando contra o time ou mesmo criando conflitos na equipe. Não ache que pular fora desta discussão o isentará das longas noites e finais de semana fazendo o sistema funcionar na força bruta ao custo de sua saúde.

Cuidado com a armadilha das pequenas empresas que promovem ambientes descontraídos, ausência de hierarquia, videogames no escritório, etc. Apesar de eu acreditar que existem empresas assim acredito também que existem muitas que possuem somente o discurso. Apesar de não concordar com a abordagem, compreendo a reação de alguns desenvolvedores dando respostas extremamente ríspidas a este discurso em listas de discussão.

Outra armadilha é a empresa de serviço escondida numa empresa de produto. Geralmente é uma empresa, que tem um produto em casa, mas que não possui nenhum tipo de gestão técnica sobre o produto. Vende uma coisa diferente para cada cliente diferente sendo que cada customização é um projeto (com recompensa por entrega no prazo).

Grupo B

Se sua cabeça se identifica mais com o grupo B, faça exatamente o inverso do grupo anterior. Procure empresas com modelo de recompensa baseado em metas por entrega no prazo e fuja de empresas inovadoras. Busque aprender linguagens extremamente defasadas que as pessoas do grupo A não tem estômago para trabalhar, geralmente linguagens procedurais como VB ou COBOL. Se você tiver paciência para aprender algo novo, motivado pelos altos salários que esse aprendizado lhe trará, busque linguagens proprietárias e raras como ABAP (do SAP) ou outros ERP’s. Paga-se muito caro por este nível de especialização e o pessoal do grupo A não vai se interessar muito por aprender essas linguagens/tecnologias pela própria característica dela. O preço da sua escolha será a falta de contato com coisas novas, viver corrigindo bugs em sistemas extremamente defasados e complexos, naquele estilo que você corrige um bug e ele reaparece em outro lugar e você fica tentando pegar o cachorro perseguindo o rabo dele.

Você poderá correr algum risco de perder o emprego quando alguns destes legados forem substituídos. E não imagine que você será poupado dos longos finais de semana e madrugadas de correções de bugs.

Gestor ou especialista?

Essa decisão é tão difícil quanto a anterior, e provavelmente o seu modelo de motivação também o ajudará na sua decisão.

Grupo A

Com o grande crescimento das metodologias ágeis, é bem possível que com o tempo Scrum Masters sejam visualizados como gestores nas empresas e esta seja uma boa opção pra quem vem de um background técnico, mas até lá, geralmente que quando se escolhe por uma carreira de gestão, sua distância do código vai aumenta. Em grandes empresas de tecnologia internacionais, é normal encontrarmos desenvolvedores com títulos de “Principal” (diretor) e que ainda atuam diretamente com mão no código, mas não é uma realidade para empresas atuando no mercado brasileiro.

Provavelmente se sua cabeça pensa como o grupo A, você vai viver um eterno conflito. Quando se aproximar da gestão, vai se distanciar do código e se frustrar, se sentir estagnado, como se não estivesse contribuindo com algo produtivo e distante do seu propósito. Pode ser que até se sinta um pouco enganador, liderando pessoas sem ser uma referência em conhecimento técnico para ela. Quando se aproximar do código, vai cada vez mais se visualizar distante da gestão e sentir que sua carreira (no sentido financeiro) está estagnada.

Caso escolha pelo caminho da gestão, seu raciocínio lógico e seu conhecimento técnico provavelmente irão lhe sabotar em situações de negociações em que fatores humanos e políticos predominem. O impulso para resolver diretamente os problemas do dia a dia pode se tornar uma dificuldade no desafio de todo grande gestor que é ajudar sua equipe a crescer. A vantagem de enfrentar tudo isso é ter uma possibilidade clara de crescimento na carreira, assim como a imediata desvantagem que é a diminuição de oportunidades. Quanto mais alto o cargo e o salário, menor a quantidade de oportunidades.

Por outro lado, se escolher a carreira de especialista estará mais próximo do código. Existem empresas que prometem uma carreira em Y, de forma que o especialista teria as mesmas oportunidades de um gestor. Recomendo procurar alguém que trabalha numa destas empresas para dar sua opinião se realmente isso funciona na prática, ou seja, se um especialista de fato tem poder de decisão (ao menos técnica) nas empresas, se a faixa salarial é a mesma, etc.

O preço dessa escolha é o risco de ser gerenciado por um gestor sem conhecimento técnico e ter que pagar o preço por decisões por vezes equivocadas no seu ponto de vista, ter um limite salarial e de crescimento de carreira que provavelmente chegará muito rápido, além de poder eventualmente sentir uma espécie de tom de deboche quando ouvir comentários do tipo “você poderia estar longe na carreira, mas preferiu ficar programando”. Por outro lado, existem vantagens como a facilidade de recolocação e a maior satisfação e alinhamento com a sua natureza, em outras palavras, fazer o que gosta.

Grupo B

Se escolheu ser um gestor, sua motivação pela recompensa direta (salário e bônus) será uma forte aliada para superar todos os desafios da gestão. Você sofrerá a mesma dificuldade de todo profissional técnico que é aprender a lidar com pessoas, aprender a desenvolver pessoas, habilidades de negociação, etc. No caso da gestão de uma equipe técnica, você poderá ter também bastante dificuldade em conseguir o respeito da equipe técnica devido ao histórico das tecnológias e métodos que praticou enquanto analista.

No caminho de especialista, pode ser difícil conseguir o skill necessário para virar um especialista pois enquanto as pessoas do Grupo A são auto-motivadas e buscam conhecimento por conta própria, você do grupo B precisará de um estímulo externo (Ex.: uma clara oportunidade de promoção do tipo “aprenda a tecnologia A e será promovido”) para conseguir a motivação necessária a adquirir um novo skill.

A mudança no cenário

Outro ponto a ser considerado na tomada de decisão é que cada vez mais inovação é um assunto na agenda das empresas. Muitas empresas estão precisando da criatividade e da inovação para melhorarem seus resultados ou mesmo para sobreviver. Se os negócios começarem a perceber que o caminho sugerido pela ciência faz sentido, cada vez mais pessoas do grupo A serão procuradas.

Será que essa mudança acontecerá? Ou seria a pergunta mais apropriada: quanto tempo levará para essa mudança acontecer?

Conclusão

Não existe almoço grátis. Toda escolha é exclusiva e quando lidamos com nossa carreira é importante conhecermos a nossa natureza e buscarmos aquilo que está mais alinhado com ela. A melhor forma de evitar as frustrações e não cair em armadilhas é desenvolvendo o auto-conhecimento e sabendo claramente qual a escolha que está sendo feita e o preço pago por ela.

Por que números de ponto flutuante (Float e Double) são imprecisos?

Objetivo

Esses dias fui questionado por um colega de trabalho sobre usar números de ponto flutuante (float ou double) ou o tipo decimal para representar números.

Confesso que nunca tinha refletido a fundo nessa questão e aproveitei a oportunidade para pesquisar melhor o tema. Já tive muitos problemas com imprecisões em floats em casas decimais menos significativas, mas nunca fui pesquisar a razão.

A idéia desse post é compartilhar o aprendizado.

Representação interna

Como bem sabemos, todo tipo de dados tem uma representação interna, binária para o seu conteúdo. Essa representação é criada de uma forma a acomodar a maior quantidade de informações possíveis, no menor espaço. A mesma regra segue para os números de ponto flutuante.

Neste caso específico, optou-se por sacrificar um pouco a precisão em troca de espaço e velocidade de computação. Logo, a representação interna de um float (32 bits) é a seguinte (da esquerda para a direita):

  • 1 bit: sinal. 0 para positivo, 1 para negativo
  • 8 bits: expoente, representado em offset binary
  • 23 bits: mantissa

Esta notação segue um padrão IEEE 754.

Expoente

A notação do expoente, apesar de não ser lá tão simples, não é muito controversa. Ela segue a mesma regra de números inteiros (potências de 2), da direita pra esquerda. Ou seja, o primeiro bit da direita, representa 2^0, o segundo 2^1 até o oitavo bit 2^7.

A única diferença é que o “0” na verdade começa num offset de -127. Todos os bits zerados no expoente significa -127. Ao ligar o primeiro da direita, -126, o primeiro e o segundo, -124, de forma que quando ligamos todos os bits exceto o primeiro da esquerda (01111111), temos 2^0 = 1.

Mantissa

A mantissa é uma notação muito interessante. Quando todos os 23 bits estão desligados, não adicionamos nada ao número. Quando ligamos o primeiro bit mais significativo, ele adiciona metade do valor do expoente. O segundo bit, metade da metade do valor do expoente e assim sucessivamente.

Ex.: Se o expoente for 100000000 (decimal 2), o primeiro bit mais significativo do mantissa vale 1, o segundo vale 0,5, o terceiro 0,25 e assim sucessivamente.

Se o expoente for 011111111 (decimal 1), o primeiro bit mais significativo do mantissa vale 0,5, o segundo 0,25 e assim sucessivamente.

Se quisermos por exemplo o número 2.75, teremos expoente 100000000, mantissa (sem completar os digitos menos significativos) 011.

Outra curiosidade, se usarmos o expoente 100000000 e somente ligar o bit menos significativo do mantissa, seu valor é 0,0000002.

Tá bom, e as imprecisões?

Essa é a parte divertida. Por causa dessa característica da notação, alguns números não podem ser representados! Um bom exemplo é o número 0.1. Na verdade ele é composto por:

Sinal: 0
Expoente: 01111011 = 2^-4 = 0,0625
Mantissa: 10011001100110011001101 = 0,0375000014901161 (ver tabela abaixo)

Bit

Status

Valor
1

1

0,031250000000000000000000
2

0

0,015625000000000000000000
3

0

0,007812500000000000000000
4

1

0,003906250000000000000000
5

1

0,001953125000000000000000
6

0

0,000976562500000000000000
7

0

0,000488281250000000000000
8

1

0,000244140625000000000000
9

1

0,000122070312500000000000
10

0

0,000061035156250000000000
11

0

0,000030517578125000000000
12

1

0,000015258789062500000000
13

1

0,000007629394531250000000
14

0

0,000003814697265625000000
15

0

0,000001907348632812500000
16

1

0,000000953674316406250000
17

1

0,000000476837158203125000
18

0

0,000000238418579101562000
19

0

0,000000119209289550781000
20

1

0,000000059604644775390600
21

1

0,000000029802322387695300
22

0

0,000000014901161193847700
23

1

0,000000007450580596923830

Se fizermos a soma da tabela acima, chegamos no resultado 0,0625 + 0,0375000014901161 = 0,100000001490116.

A imprecisão 0,000000001490116 ocorre, porque na representação do número em bits não dá pra chegar exatamente nos 0.1.

Qual a implicação disso

Geralmente quando fazemos uma conta diretamente com float, não sentimos essa diferença, pois está numa casa decimal pouco significativa.

O grande porém está quando acumulamos os valores. Veja o snippet:

		static void Main(string[] args)
		{
			decimal d = 0m;

			for(int i = 0; i < 100000; i++)
				d += 0.1m;

			float f = 0F;
			for (int i = 0; i < 100000; i++)
				f += 0.1F;

			Console.WriteLine("Decimal: " + d.ToString()); //Decimal: 10000,0
			Console.WriteLine("Float: " + f.ToString()); //Float: 9998,557
		}

Era isso!

Referências

Utilizei como referência a Wikipedia e esta calculadora genial de números de ponto flutuante.

Também consultei o padrão IEEE 754 e a documentação da Microsoft.