quarta-feira, 24 de março de 2010
Resultados da pesquisa sobre salários de programadores - parte 2 - escolaridade
Mais interessante é o gráfico de salários médios. Como podemos ver, o salário médio cresce de acordo com a escolaridade. Parece bom, mas isso nos leva a uma pergunta: quanto vale, por exemplo, um mestrado?
Para responder a essa pergunta, vamos considerar apenas a região Sudeste para reduzirmos os efeitos regionais. A média salarial do graduado no Sudeste é de R$ 3.586,00. Já a média salarial do mestre é de R$ 5.107,00. A diferença é de R$ 1.521,00. Suponhamos que essa diferença se mantenha constante ao longo da carreira. Se o programador obtém o mestrado aos 25 anos e trabalha até os 60 anos, são 35 anos * 12 meses * R$ 1.521,00 = R$ 638.820,00. Ou seja, vale a pena fazer o mestrado, mesmo que você tenha de fazer um empréstimo no banco para pagar.
É claro que não podemos ter certeza que há uma relação causal entre escolaridade e salário - pode ser que haja algum terceiro fator que ao mesmo tempo leva a pessoa a buscar um grau maior de escolaridade e a ter um emprego melhor. Não é garantido que fazer um mestrado ou uma pós vá melhorar seu salário.
Aliás, eu sempre digo isso quando faço em universidades minha palestra sobre o que fazer depois de se formar: um diploma ou outro título te ajuda a conseguir um emprego, mas não te ajuda a ficar nele. Não leva mais do que três meses para um empregador perceber se o diploma é só um pedaço de papel ou se tem valor real.
terça-feira, 23 de março de 2010
Para que serve o teste de software?
A maioria dos programadores e principalmente estudantes norte-americanos dos programas de graduação em Engenharia de Software não acham que precisam testar seus programas com rigor - aqui rigor não significa nem formalismo matemático, nem exaustão, uma vez que é impossível, mas sim uma forma sistemática do programador testar seus programas munido de técnicas apropriadas. A maioria dos programadores dá um tiro no próprio pé fazendo alguns poucos testes aleatórios. Por mais que a universidade tente mostrar a necessidade e que o teste seja também papel do desenvolvedor/programador, os alunos só se convencem disso quando vão para o mercado.
As experiências no ensino de desenvolvimento dirigido por testes (TDD) são frustrantes. A maior parte dos alunos não utiliza a metodologia pois TDD não pode ser considerada um técnica por si só. E uma vez que é apenas uma metodologia, é dificil para os professores exigirem dos alunos a aplicação da mesma. Mesmo sabendo que serão penalizados, os alunos não aplicam o TDD e só criam os casos de teste após terem escrito o código. Estou falando de TDD quando o assunto é teste, mas sabemos que as grandes contribuições de TDD estão na evolução de um bom projeto, no entendimento maior do problema em questão antes da codificação. Desta forma, os alunos que imaginam que só precisam criar casos de teste e que tanto faz antes como depois do código perdem o melhor da metodologia. São os profissionais com essa atitude que chegam ao mercado. Se TDD fosse aplicado desde as primeiras disciplinas de programação, talvez assim os alunos percebessem a
vantagem da abordagem. Algumas universidades americanas vão investir neste caminho.
No passado, teste servia o propósito limitado de detectar erros nos programas. Através da quatidade de erros encontrados no programa era possível derivar dos testes um indicador da qualidade do programa. Esse era o tempo em que os programas eram monolíticos ou compostos de pequenos módulos. Hoje em dia cada componente utilizado é de uma complexidade grande e possui suas próprias características intrínsecas. Princípios de ocultação de informacao e interfaces bem definidas foram aplicados e a engenharia de software se orgulha destes avanços. No entanto, o comportamento de um determinado módulo ou componente precisa ser descoberto pelo programador que usa este módulo ou componente, e a maneira de descobrir este comportamento é através de testes. Muitas vezes a documentação é escassa ou descreve bem o que se espera que o componente faça, mas na verdade o comportamento dele é um pouco diferente. Este propósito do teste de descobrir ou certificar o comportamento dos componentes é completamente diferente do propósito de detectar defeitos. Quais técnicas de teste devem ser usadas neste caso?
Produzir casos de teste relevantes continua sendo o problema mais difícil de se resolver em testes, principalmente no teste considerando o código. Como o Torsten disse anteriormente, se o foco de teste passa a ser a cobertura no sentido que passei por aqui, é melhor projetar os casos de teste antes de escrever o código e com base na sua especificação. Mas será que usaríamos os mesmos casos de teste para testar as três versões de código abaixo da função fatorial? (exemplos de código fornecidos por Nawwar Kabbani - participante do workshop.)
Com certeza, vendo os três códigos conseguimos pensar em casos de testes que gostaríamos de fazer. Alguns com base na definição do fatorial, outros com base no código que foi apresentado. No último caso a cobertura não vai ajudar em nada.
Para terminar, eu recomendo fortemente o mini curso do Doug Hoffman que participará do Encontro Brasileiro de Testes de Software (IV EBTS) , ele na minha opiniao é um grande praticante com muitas estórias de sucesso sobre testes de software para contar. Seu objetivo é coletar várias estórias para compor um livro que possa ajudar a comprovar os diversos propósitos de testes e sua necessidade para a sobrevivência dos programadores.
sexta-feira, 19 de março de 2010
Resultados da pesquisa sobre salários de programadores - parte 1 - dados agregados por estado
Hoje vamos ver os dados agregados por estado. Para criar a visualização, usei a fantástica, sensacional ferramenta gratuita Tableau Public. Não tenho palavras pra dizer o quanto essa ferramenta é legal. Ela permite criar visualizações interativas que você pode incluir no seu site.
O mais importante ao investigar os resultados da pesquisa é saber que não se trata de uma amostragem aleatória e, portanto, não se pode tirar conclusões generalizáveis. Como se pode ver pelo gráfico abaixo, predominaram as respostas vindas de Minas Gerais, o lar do Micos, e da Paraíba, graças ao Guilherme Germoglio que espalhou a notícia. Naturalmente, não podemos dizer que esses dois estados concentram a maioria dos programadores do Brasil.
Dentre os que declararam o local onde trabalham, excluí para esse gráfico todos os que trabalham fora do Brasil e os residentes do Piauí e do Pará, pois cada estado contribuiu com uma única resposta.
O gráfico nos mostra alguns dados interessantes: tanto a média salarial quanto o nível de experiência dos programadores do Nordeste está bem abaixo da média dos de outras regiões. Por outro lado, o nível de satisfação médio é bastante uniforme em todos os estados. Nota-se uma discrepância na média salarial do Distrito Federal, muito acima da média nacional.
Experimentem brincar com o gráfico abaixo selecionando, por exemplo, apenas os programadores que tem graduação, ou apenas aqueles com 3 anos ou menos de experiência.
Semana que vem tem mais.
segunda-feira, 8 de março de 2010
Feliz Dia Internacional da Mulher
A Guta achou o link para a apresentação no meio de uma discussão que está acontecendo na lista da Sociedade Brasileira de Computação (sbc-l) sobre a nova boneca Barbie que foi lançada, cuja profissão é Engenheira de Computação. Tem gente que achou bom, tem gente que achou ruim. Eu, pessoalmente, achei a boneca de muito bom gosto e vou comprar duas, uma pra cada uma das minhas filhas.
terça-feira, 2 de março de 2010
Pesquisa sobre remuneração de programadores
A equipe do Micos de Realejo está escrevendo um grande post sobre o estado atual da remuneração na indústria de software. No entanto, estamos sentindo falta de dados concretos e contamos assim com a colaboração dos leitores.
Elaboramos uma pesquisa curta que deve levar cerca de 3 minutos para responder. A pesquisa é destinada apenas àqueles que de alguma forma trabalham com programação.
A pesquisa é totalmente anônima, todas as questões são opcionais e dados individuais não serão divulgados. Divulgaremos apenas resultados agregados.
Por favor divulguem para seus colegas para que possamos obter uma quantidade significativa de dados para análise.
O link para a pesquisa é: http://bit.ly/9FpAPV
Obrigado,
Torsten
quarta-feira, 24 de fevereiro de 2010
Complexidade
Relendo o excelente artigo Anatomy of a Crash, fiquei impressionado de novo não só com a rapidez com que uma batida é tratada, mas também com a complexidade do sistema todo. O texto narra a reconstrução de uma batida simulada como parte de um estudo em segurança de veículos:
0 milliseconds - An external object touches the driver's door.
1 ms - The car's door pressure sensor detects a pressure wave.
2 ms - An acceleration sensor in the C-pillar behind the rear door also detects a crash event.
2.5 ms - A sensor in the car's centre detects crash vibrations.
5 ms - Car's crash computer checks for insignificant crash events, such as a shopping trolley impact or incidental contact. It is still working out the severity of the crash. Door intrusion structure begins to absorb energy.
6.5 ms - Door pressure sensor registers peak pressures.
7 ms - Crash computer confirms a serious crash and calculates its actions.
8 ms - Computer sends a "fire" signal to side airbag. Meanwhile, B-pillar begins to crumple inwards and energy begins to transfer into cross-car load path beneath the occupant.
8.5 ms - Side airbag system fires.
15 ms - Roof begins to absorb part of the impact. Airbag bursts through seat foam and begins to fill.All over in the blink of an eye
17 ms - Cross-car load path and structure under rear seat reach maximum load.
Airbag covers occupant's chest and begins to push the shoulder away from impact zone.
20 ms - Door and B-pillar begin to push on front seat. Airbag begins to push occupant's chest away from the impact.
27 ms - Impact velocity has halved from 50 km/h to 23.5 km/h. A "pusher block" in the seat moves occupant's pelvis away from impact zone. Airbag starts controlled deflation.
30 ms - The Falcon has absorbed all crash energy. Airbag remains in place. For a brief moment, occupant experiences maximum force equal to 12 times the force of gravity.
45 ms - Occupant and airbag move together with deforming side structure.
50 ms - Crash computer unlocks car's doors. Passenger safety cell begins to rebound, pushing doors away from occupant.
70 ms - Airbag continues to deflate. Occupant moves back towards middle of car.
Engineers classify crash as "complete".
150-300 ms - Occupant becomes aware of collision.
Imagine um site moderno, que tem código rodando no browser e código no servidor (números inventados de cabeça mas não totalmente irreais):
0 ms - usuário digita o endereço de uma página do seu site
1 ms - o código do cliente determina o que fazer com a URL e dispara uma chamada ao servidor solicitando dados
16 ms - front-end do site recebe o pedido, determina que parte do site deve ser executada a partir da URL e dos dados da requisição HTTP
17 ms - serviço responsável por tratar a parte do site que o usuário quer recebe o pedido, decodifica parâmetros e dispara chamadas remotas a dezenas de back-ends
20 ms - cada back-end envolvido no serviço recebe uma requisição e acessa alguma forma de banco de dados para buscar as informações necessárias
25 ms - serviço recebe os dados de volta e calcula resposta a ser enviada de volta para o cliente, empacota tudo em algum objeto e retorna
40 ms - browser recebe resposta HTTP, chama callback do cliente para tratar os dados
42 ms - cliente preenche interface com os dados recebidos, montando a árvore DOM para a próxima interação
45-150ms - enquanto imagens carregam, usuário começa a ler o texto que já está disponível, possivelmente tomando a próxima ação (se o usuário está no IE6, a primeira requisição provavelmente só foi disparada pro servidor agora...)
Essa descrição é propositadamente superficial. Alguns dos detalhes omitidos são autenticação, serialização e desserialização de pedidos e respostas, caching em vários níveis do sistema, sharding e balanceamento de carga, logging, validação de entrada no cliente e no servidor, o modelo ou esquema de armazenamento de dados para acesso eficiente, bordinhas redondas e degradês em todos os browsers, monitoramento, XSS, XSRF, cookies, injeção de dependências, internacionalização, e as pilhas do sistema operacional e de rede de todas as máquinas envolvidas no processo. Além disso, cada front-end e back-end envolvido tem suas próprias camadas de complexidade, ou abstração. Ah, e tem um bug aqui e outro ali.
A grande vantagem pra quem trabalha na engenharia de software sobre outros tipos de engenharia em termos de confiança no sistema é que se tem a oportunidade de testar exatamente o código que vai rodar em produção durante o desenvolvimento. Nós podemos inflar o airbag que vai ser instalado no próximo carro da linha de produção, acender cada fósforo que vai entrar na próxima caixinha. O perigo de confiar totalmente nisso é que a soma da compreensão das partes não é a compreensão do todo.
E quando tudo falhar em produção, teremos aquela grande imagem cheia de detalhes para depurar; analisando várias partes descobriremos que aquele airbag que nós sabíamos que funcionava não foi inflado. Onde no meio de tantas interações ficou faltando o disparo do airbag praquele usuário que teve uma batida a um ângulo de 23ᵒ, trafegando a 45km/h com 2 passageiros numa tarde de sábado de um ano bissexto?
Só não se sente intimidado por um site moderno, ou pelos bugs que podem aparecer nele, quem não sabe como ele funciona.
terça-feira, 2 de fevereiro de 2010
20 lições importantes
Segue abaixo então minha tradução livre do artigo. Aliás, livre até demais: eu mantive as 20 lições intactas, mas os comentários são meus.
- Decida quanto tempo você quer gastar com um problema antes de começar. Ao invés de ficar pelejando por uma semana com um problema que deveria levar um dia pra resolver, como eu fiz na semana passada, decida antecipadamente quanto tempo você vai dedicar a ele. Pode ser uma semana, um dia, uma hora, 30 minutos, não importa. Se você não conseguir resolver o problema no tempo em que você se permitiu trabalhar nele, procure ajuda ou repense suas prioridades ao invés de tentar ser o super-programador.
- Uma linguagem é uma linguagem é uma linguagem. Um sábio professor uma vez me disse que o problema que o seu programador mais júnior está tendo com a namorada tem mais impacto no sucesso do seu projeto do que a linguagem de programação que você escolher. Ele tinha razão. Escolha uma linguagem que te dê conforto, e pronto.
- Não exagere nos design patterns. Pense duas vezes antes de usá-las - se houver uma solução mais simples, use-a.
- Faça backups do seu trabalho diariamente.
- Você não é o melhor programador. Conforme-se com isso. Sempre tem alguém melhor que você. Aprenda com eles ao invés de tentar ser melhor.
- Aprenda a aprender mais. Se você não está gastando pelo menos 50% do seu tempo aprendendo, sua produtividade está piorando. Sim, parece um paradoxo, mas não é.
- Mudanças são constantes. O que você sabe hoje não vai ser tão importante amanhã. Diversifique seus conhecimentos.
- Apoie os menos experientes. Ajudar os programadores da sua equipe a se tornarem melhores é o melhor investimento a longo prazo que você pode fazer.
- Simplifique seu algoritmo. Quando terminar, volte atrás e veja o que você pode fazer para tornar seu código mais simples e fácil de ler. O futuro agradece.
- Documente seu código. De novo, o futuro agradece. Aliás, quem provavelmente mais agradecerá será você mesmo.
- Teste, teste, teste.
- Celebre cada sucesso. Não espere uma data longínqua para se dar os parabéns. Programar é cansativo. Comemore cada passo a frente e cada bug removido, da maneira que preferir. Só não comemore comendo chocolate, como eu faço.
- Faça revisões de código. No Google cada linha de código que é escrita é revisada por pelo menos um outro programador. Nenhuma outra atividade é tão importante para se garantir a qualidade dos sistemas. Mesmo que você não chegue a esse extremo, peça a seus colegas que revisem as partes importantes e ofereça-se para fazer o mesmo.
- Estude seu código antigo. Leia código que você escreveu quando ainda não era tudo isso e maravilhe-se com o quanto você aprendeu desde então.
- Tenha senso de humor. Ha ha.
- Evite trabalhar com programadores possessivos ou prepotentes. O possessivo é aquele que não permite que ninguém altere ou critique seu código; ele pode arruinar seu projeto. O prepotente é aquele que tem sempre a última palavra; ele vai prejudicar sua auto-estima.
- Nenhum projeto é simples. Nenhum. Não existe nada de qualidade em computação que possa ser feito "rapidinho, em dois dias".
- Cuidado com o excesso de confiança. Enquanto não estiver funcionando e aprovado, nunca está 90% completo. Os 10% que faltam em geral levam o mesmo tempo que você gastou com os 90%.
- Software nunca está pronto. Leia o post Persistir ou jogar tudo fora?
- Paciência é uma virtude. Saiba esperar a hora certa de implementar; antes tente entender seu problema. Quando as coisas derem errado, procure entender por que ao invés de sair tentando qualquer coisa.