quarta-feira, 30 de julho de 2014

Como integrar o Windows 7 SP1 no pacote de instalação

Introdução

Este artigo apresenta um pequeno tutorial sobre como integrar o Windows 7 Service Pack 1 (e outros updates), no pacote de instalação do Windows 7.

A integração (slipstream) de updates no pacote de instalação do Windows permite que estes sejam instalados automaticamente, juntamente com a instalação inicial.

Existem várias formas de realizar esta operação. Este artigo descreve a forma manual de o fazer, sem necessidade de utilizar qualquer software de terceiros, somente com os pacotes oficiais da Microsoft.

No tutorial do presente artigo vamos ver como integrar o SP1 no pacote de instalação do Windows 7, mas os métodos são em tudo semelhantes para a integração de outros updates do Windows.

O método descrito neste artigo é totalmente legal e pressupõem que o utilizador seja possuidor de uma licença válida para instalar o Windows 7. Todos os links indicados para downloads remetem para o site oficial da Microsoft.

Requisitos

Para executar o presente tutorial, são necessários os seguintes requisitos:

  • Executar num PC já com o Windows 7 SP1 instalado;
    • Pode-se obter o WAIK a partir desta página;
    • E o Suplemento do WAIK a partir desta página;
  • DVD ou imagem ISO de instalação do Windows 7;
  • Pacote de instalação do Windows 7 Service Pack 1 (KB976932) de 32 bits ou 64 bits, conforme a versão que se pretende integrar.
    • Pode-se obter o SP1 a partir desta página

Deve ainda criar as seguintes pastas (no presente tutorial assumimos o disco C:, mas pode ser em qualquer outra localização):


Método

  1. Copie o conteúdo do DVD de Instalação do Windows 7 para a pasta C:\Win7sp1\InstallDVD. Se em vez de um DVD, possuir uma imagem ISO, use o 7-Zip, WinRAR ou WinZip para extrair o conteúdo do ISO para esta pasta.
     
  2. Copie o ficheiro com o pacote de instalação do SP1 (windows6.1-KB976932-…exe) para a pasta C:\Win7sp1 (neste tutorial vamos exemplificar com a versão x64).
     
  3. De seguida, abra a janela de Linha de comandos, com privilégios elevados (executar como Administrador).

     
  4. Na Linha de Comandos, execute o seguinte:
     
    C:\Win7sp1\windows6.1-KB976932-X64.exe /X:C:\Win7sp1\SP1content
     
    Isto vai extrair o conteúdo do pacote de instalação do SP1 para a pasta C:\Win7sp1\SP1content.
     
  5. Dentro da pasta C:\Win7sp1\SP1content existe um ficheiro chamado windows6.1-KB976932-X64.cab, ou similar (existem dois ficheiros com nomes parecidos, escolha o maior). Extraia o conteúdo deste ficheiro para o mesmo local.
     
  6. Após a extracção, vai existir um ficheiro chamado NestedMPPContent.cab. Extraia este ficheiro para o mesmo local também.
     
  7. De seguida, localize 7 ficheiros com os nomes KB976933-LangsCab0-6.cab. Extraia estes ficheiros também. Durante a extracção, é natural aparecer a mensagem de ficheiros repetidos. Confirme a substituição de todos.
     
  8. Agora é necessário editar os seguintes ficheiros (pode usar o Bloco de Notas):
    • Windows7SP1-KB976933~31bf385~amd64~~6.1.1.17514.mum

      Localize e substitua o texto allowedOffline="false" por allowedOffline="true".


    • update.mum
      Efectue alteração semelhante à do ficheiro anterior.
    • updates.ses

      Localize as duas últimas linhas com o texto targetState=”Absent” e altere-as para targetState=”Installed.
  9. A partir desta fase, é necessário usar uma ferramenta chamada Dism. Embora possa existir uma versão desta ferramenta na pasta do sistema, a ferramenta correta está localizado nas pastas do WAIK, que deverá estar instalado, conforme os pré-requisitos.

    É então necessário mudar o directório de trabalho para a pasta das ferramentas do WAIK (a pasta correcta x86, ia64 ou amd64 depende da arquitectura do SO em que está a trabalhar).
     
    cd C:\Program Files\Windows AIK\Tools\amd64\Servicing
     
  10. Para integrar o SP1, é necessário saber o número de índice de versão do Windows que quer integrar. Execute o seguinte comando para obter os índices das versões contidas na ficheiro install.wim do seu pacote de instalação:

    dism /get-wiminfo /wimfile:C:\Win7sp1\InstallDVD\sources\install.wim
     


    Imaginemos que queremos integrar o SP1 no Windows 7 PROFESSIONAL x64, que, no nosso exemplo, tem o índice 8. Vamos necessitar deste número nos próximos passos.
     
  11. Temos agora que fazer o mount da imagem do SO contida no pacote de instalação. Execute o seguinte comando:
     
    dism /mount-wim /wimfile:C:\Win7sp1\InstallDVD\sources\install.wim
    /index:8 /mountdir:C:\Win7sp1\Mount

    Substitua o índice pelo correcto, da sua instalação.
     
  12. Agora vamos adicionar os ficheiros do SP1 à nossa imagem (esta operação pode demorar algum tempo):
     
    dism /image:C:\Win7sp1\Mount /add-package /packagepath:C:\Win7sp1\SP1content

    Nota: para instalar outros updates, que não apenas o SP1, basta colocar os respectivos ficheiros numa pasta e executar o comando anterior. Se foram ficheiros do tipo MSU, não é necessário fazer qualquer tipo de extracção.
     
  13. Após a conclusão da integração dos pacotes de actualização, é necessário fazer o unmount da imagem, gravando as alterações (também demora algum tempo):
     
    dism /unmount-wim /mountdir:C:\Win7sp1\Mount /commit

    Nota: se estiver a criar a imagem num computador com o Windows 7 64 bits, tem que fechar todas as janelas do Explorador do Windows, antes de executar este último comando, senão dá um erro e, embora crie a imagem sem problemas, não faz o unmount da mesma.
     
  14. Após a conclusão desta tarefa, pode verificar que o ficheiro install.wim, na pasta C:\Win7sp1\InstallDVD, foi alterado (timestamp actualizado e tamanho maior). Basta agora gravar o conteúdo desta pasta para um novo DVD ou criar uma imagem ISO, por exemplo. Atenção que em ambos os casos é necessário criar um DVD ou imagem de arranque (bootable).

segunda-feira, 28 de julho de 2014

Como integrar o Office 2013 SP1 no pacote de instalação

Introdução

Este artigo apresenta um pequeno tutorial com dois métodos para integrar o Office 2013 Service Pack 1 (e outros updates), no pacote de instalação do Office 2013.

A integração (slipstream) de updates no pacote de instalação do Office permite que estes sejam instalados automaticamente, juntamente com a instalação inicial.

No tutorial do presente artigo vamos ver como integrar o SP1 no pacote de instalação do Office 2013 Professional Plus 64 bits, mas os métodos são em tudo semelhantes para a integração de outros updates ou para outras versões ou produtos do Office (como 32 bits, Office 2010, Office 2007, Project, Visio).

Os métodos descritos neste artigo são totalmente legais e pressupõem que o utilizador seja possuidor de uma licença válida para instalar o Office. Todos os links indicados para downloads remetem para o site oficial da Microsoft.

Método 1

Este método só extrai o Service Pack 1 para a pasta de instalação do Office 2013, mas não o integra na configuração, o que significa que o SP1 será instalado após a conclusão da instalação do Office 2013. Por outras palavras, este procedimento não vai atualizar os ficheiros originais da instalação do Office 2013, com ficheiros actualizados.

Se possuir o Microsoft Toolkit, recomendamos que siga as instruções do Método 2 para integrar o SP1 directamente na instalação do Office.

  1. Fazer o download do pacote de instalação do  Office 2013 Professional Plus SP1 x64 (KB2817430) a partir desta página.
  2. Crie uma nova pasta no Ambiente de Trabalho ou em qualquer outro local e altere o nome para: Office 2013 com SP1.
  3. Insira o DVD de instalação do Office 2013 no leitor e copie todos os ficheiros para a pasta criada no passo anterior. Se em vez de um DVD, possuir uma imagem ISO, use 7-Zip, WinRAR ou WinZip para extrair o conteúdo do ISO para esta pasta.



  4. De seguida, deve extrair o conteúdo do executável de instalação do SP1 para a pasta Updates, que está dentro da pasta Office 2013 com SP1 (neste caso recomendamos o 7Zip).


  5. Após concluir esta acção, pode iniciar a instalação do Office 2013 clicando duas vezes no ficheiro Setup.exe, localizado na pasta Office 2013 com SP1.


  6. Pode ainda gravar o conteúdo da pasta Office 2013 com SP1 para um DVD ou para uma imagem ISO, para posterior instalação.

Método 2

Este método permite a integração do SP1 directamente nos ficheiros de instalação do Office, mas só pode ser usado se possuir o Microsoft Toolkit. A integração directa dos updates nos ficheiros de instalação do Office permitem uma instalação mais rápida.

  1. Fazer o download do pacote de instalação do  Office 2013 Professional Plus SP1 x64 (KB2817430) a partir desta página.
  2. Crie uma nova pasta no Ambiente de Trabalho ou em qualquer outro local e altere o nome para: Office 2013 com SP1.
     
  3. Executar o Microsoft Toolkit. Quando aparecer o ecran inicial, clicar no botão com o ícone do Office Botão Office


  4. Assim que o Office Toolkit 2.5 for lançado, selecione o separador “Customize Setup”.


  5. Clique no botão “Extract Setup” para procurar e selecionar o ficheiro SFX ou ISO do Office, para extrair e clique em “Abrir”. De seguida, selecione a pasta Office 2013 com SP1, criada no passo 2, para salvar o conteúdo que será extraído com a ajuda do Office Toolkit.


  6. Se em vez duma imagem ISO, possuir o DVD de instalação do Office 2013, então deve copiar o conteúdo do DVD para a pasta criada no passo 2 e de seguida clique no botão “Set Installer Path”, do Office Toolkit, para procurar e selecionar o ficheiro Setup.exe, dentro da pasta Office 2013 com SP1.
  7. Após ter terminado a operação do passo 5 ou passo 6, clique no botão “Add Updates” e procure o ficheiro executável do SP1, que obteve a partir do site da Microsoft, no passo 1. Ao clicar no botão “Abrir”, o Office Toolkit vai iniciar a integração do update com o pacote de instalação do Office 2013. Quando completar a tarefa, o Office Toolkit vai apresentar a mensagem "Successfully integrated".
  8. Após concluir esta acção, pode iniciar a instalação do Office 2013 clicando duas vezes no ficheiro Setup.exe, localizado na pasta Office 2013 com SP1.


  9. Se pretender criar um ficheiro de imagem ISO, clique no botão “Make ISO” do Office Toolkit e selecione o ficheiro Setup.exe, localizado na pasta Office 2013 com SP1. Clique no botão “Abrir” e de seguida escolha uma pasta para guardar o ficheiro ISO com o Office 2013 SP1. Finalmente, clique no botão “Salvar”, para começar a criar o ficheiro de imagem. Ao fim de algum tempo, verá a mensagem “Successfully made ISO” e o trabalho está concluído.


segunda-feira, 21 de julho de 2014

Convenções de Nomenclatura

Introdução

A programação consiste em grande parte em dar nomes a coisas: classes, métodos e variáveis. Mas, conseguir criar bons nomes é bem mais difícil do que parece. Para além de respeitarem as regras da linguagem ou tecnologia em que estão a ser usados, os nomes devem ser claros para o programador que os criou, mas também para outros programadores que tenham que ler o código. É aqui que entram as Convenções de Nomenclatura (Naming Conventions).

O conceito de convenção de nomenclatura é bastante mais geral, mas, na programação, podemos dizer que consiste num conjunto de regras para a escolha da sequência de caracteres a ser usada para criar os identificadores (nomes) de classes, métodos, tipos, variáveis, ou outras entidade do código fonte e documentação. As convenções aplicam-se, normalmente, quer ao formato, quer à atribuição de significado aos nomes escolhidos.

De realçar que este é um tema controverso, pois existem variadíssimas convenções, cada uma com os seus partidários e é comum as grandes empresas criarem o seu próprio conjunto de regras, para melhor servir os seus interesses. Neste artigo vamos tentar abordar os conceitos mais importantes e analisar algumas das convenções mais populares os dias de hoje.

Conteúdo

Benefícios da utilização de Convenções de Nomenclatura

À primeira vista, as convenções de nomenclatura podem não parecer assim tão importantes. Na realidade, podemos criar código sem usar qualquer tipo de convenção e ele continuar a ser funcionalmente correcto. Então, porque devemos usar convenções de nomenclatura e porque são tão recomendadas e mesmo obrigatórias na maioria dos grandes projectos?

A utilização de convenções de nomenclatura, em oposição a deixar os programadores criar livremente os nomes e formatos dos nomes, permite que seja significativamente mais fácil a outros analistas e programadores entender entender como o sistema funciona e o que está a fazer e como corrigir ou estender o código fonte para novas necessidades de negócio.

Existem outras razões e vantagens, é claro, mas a questão da manutenção é fundamental. Quando temos que olhar para o código de outra pessoa, ou mesmo para o nosso próprio código, quando já não lhe mexemos há algum tempo, ajuda-nos ter certas expectativas sobre o que um dado identificador é e o que faz, logo à primeira vista. Se pensarmos que a maior parte do tempo de vida de uma aplicação é passado na fase de manutenção, tudo o que tornar a manutenção mais fácil, ajuda. Especialmente quando é algo tão fácil como seguir algumas convenções de nomenclatura.

Podemos enumerar mais alguns dos potenciais benefícios da utilização de convenções de nomenclatura:

  • Fornecer informação adicional (metadados) sobre a utilização de um dado identificador;
  • Promover a consistência dentro de uma equipa de desenvolvimento;
  • Permitir o uso de ferramentas automáticas de refactoring ou find-and-replace com um potencial mínimo de erro;
  • Aumentar a clareza, em casos de ambiguidade;
  • Melhorar a aparência estética e profissional do produto (p.ex., por não permitir nomes excessivamente longos, cómicos, ou abreviações obscuras);
  • Evitar "colisões de nomenclatura" que podem ocorrer quando o resultado do trabalho de diferentes organizações é combinado;

Vejamos um pequeno exemplo prático:

a = b * c;

embora o código acima esteja sintaticamente correcto (em Java ou C#), não é claro qual o seu objectivo ou funcionalidade.

juros = capital * taxa;

Agora tornou-se muito mais claro qual o objectivo desta linha de código.

Conceitos e elementos mais comuns

Comprimento dos identificadores
Este é um elemento sujeito a muita discussão e controvérsia, na prática, mas é fundamental em qualquer convenção de nomenclatura. Algumas regras impõem um número limite fixo de caracteres individuais permitidos para cada identificador enquanto outras especificam apenas orientações.

Algumas considerações:

  • os identificadores mais curtos, podem ser tidos como mais convenientes, porque são mais fáceis de digitar;
  • identificadores extremamente curtos (como o 'i' ou 'j') são muito difíceis de distinguir, ao usar ferramentas de find-and-replace;
  • identificadores mais longos podem ser preferidos porque os curtos podem não codificar informação suficiente ou parecer demasiado críptica.

A preferência por identificadores mais curtos ou mais longos é uma questão ainda aberta à pesquisa. A utilização de brevidade na programação pode ser atribuída, em parte, ao seguinte:

  • Os primeiros compiladores e linkers só permitiam nomes de variáveis com 6 caracteres. Mais tarde foram permitidos nomes mais longos, para permitir uma melhor compreensão humana, mas apenas os primeiros caracteres eram significativos;
  • Os primeiros editores de código não possuíam autocomplete;
  • Os primeiros monitores eram de baixa resolução e tinham um número limitado de caracteres por linha (p.ex. apenas 80 caracteres);
  • Grande parte da ciência da computação teve origem na matemática, onde, tradicionalmente, os nomes das variáveis ​​têm apenas uma única letra.

Caixa Alta, Caixa Baixa e Números
Algumas convenções de nomenclatura definem se as letras podem aparecer em maiúsculas ou minúsculas. Outras não restringem a caixa das letras (letter casing), mas anexam uma interpretação bem definida com base em casa caso. Outras convenções especificam ainda se podem ser usados identificadores alfabéticos, numéricos ou alfanuméricos, e em caso afirmativo, em que sequência.

Identificadores multi-palavra
Uma recomendação comum, na programação, é "usar identificadores significativos". Uma única palavra pode não ser tão significativa, ou específica, como várias palavras. Consequentemente, algumas convenções de nomenclatura especificam regras para a criação de identificadores que contenham mais que uma palavra.

Como a maioria das linguagens de programação não permite a utilização de espaços em branco nos identificadores, é necessário um método de delimitação de cada palavra, que torne mais fácil de interpretar que caracteres pertencem a cada uma.

  • Palavras separadas por delimitadores
    Uma abordagem possível é delimitar as palavras através de um carácter não alfanumérico. Os dois caracteres mais utilizados nesta técnica são o hífen “-“ e o sublinhado “_”. Por exemplo, o identificador “duas palavras” seria representado como "duas-palavras" ou "duas_palavras". O hífen é usado por quase todos os programadores de Cobol, Forth e Lisp e também é comum como seletor em Cascading Style Sheets. Na maioria das outras linguagens (p.ex., famílias C e Pascal) usa-se o hífen como operador de subtração, não estando, por isso, disponível para uso em identificadores, usando-se o sublinhado no seu lugar. Esta prática chama-se Snake Case.
  • Palavras separadas por caixa de letras
    Outra abordagem é delimitar as palavras através do uso de letras maiúsculas. Neste caso o identificador “duas palavras” seria representado como "duasPalavras" ou "DuasPalavras". Esta técnica é chamada de Camel Case. Esta técnica tem duas variantes principais, uma que diz que a primeira palavra deve ter letra minúscula (“duasPalavras”) e outra que deve ter letra maiúscula (“DuasPalavras”). Existe alguma discussão sobre a correcta utilização destas variantes, mas hoje é mais comum aceitar-se que Camel Case designa a primeira variante (minúsculas) e que Pascal Case designa a segunda variante.

Metadados
Algumas convenções ultrapassam as meras regras de formato e grafia para a criação de nomes. Impõem também algumas regras para o seu significado. Alguma das técnicas usadas nessas convenções (especialmente nas mais antigas), são:

  • Notação Húngara
    A Notação Húngara é talvez a mais conhecida destas convenções, que codifica o tipo de uma variável no seu nome, através de um prefixo. Por exemplo sNome indica que a variável é uma string ou nIdade, indica que a variável é um número inteiro.
  • Notação posicional
    Uma técnica muito usada em notações curtas. P.ex. FTMARM01, onde FT é a aplicação – Facturação, M significa Menu, ARM é o módulo de Armazéns e 01 um número de sequência. Este tipo de convenção ainda é usada em mainframes dependentes de JCL e é vista também no formato MS-DOS 8.3 (máximo 8 caracteres, ponto separador e três caracteres para o tipo de ficheiro).
  • Esquema de palavras compostas
    Um dos primeiros sistemas de convenções foi desenvolvido pela IBM e consiste no esquema de palavras PRIME-MODIFIER-CLASS. Um exemplo será IT_SEQ_NO, para significar “Item Sequence Number” ou “Número de Sequência do Item”. As palavras PRIME designavam as principais entidades do sistema, enquanto as palavras MODIFIER eram utilizadas como refinamento adicional, qualificação e legibilidade. Finalmente as palavras CLASSE deveriam ser apenas uma pequena lista de tipos de dados relevantes para uma determinada aplicação. As palavras CLASSE, colocadas como sufixo teve muitas vezes a mesma finalidade que os prefixos da Notação Húngara.

Namespces
O conceito de namespace (espaço de nomes) é bastante abrangente na ciência da computação. Genericamente, pode-se definir como um container que fornece um contexto para os elementos que armazena. P.ex., a nível do sistema operativo, um directório é um namespace. Muitas linguagens de programação disponibilizam namespaces como contextos para guardar identificadores. Algumas regras para estes espaços de nomes são as seguintes:

  • Não podem existir dois identificadores iguais dentro do mesmo namespace;
  • Podem existir namespaces dentro de outro namespace, formando uma árvore de espaços de nomes;
  • Na mesma aplicação, podem existir classes ou funções com o mesmo nome, desde que estejam definidas em namespaces diferentes.

Os namespaces também necessitam de um identificador e, como tal, existem convenções de nomenclatura para a sua criação. Uma das convenções mais comuns, quer no Java, quer no .NET consiste em identificar os namespaces através de grupos de palavras em Camel Case ou Pascal Case, separadas por “.”. Cada um destes grupos tem um significado, conforme passamos a indicar:

  • Nome da empresa ou organização
  • Nome do produto ou tecnologia
  • Nome do módulo
  • Nome do sub-módulo e assim sucessivamente

Vejamos alguns exemplos:

Microsoft.Excel.Math.Random
java.util.stream
pt.governo.ministerio.financas

Convenções de Nomenclatura específicas

Java
Na linguagem Java, as convenções de nomenclatura para identificadores foram sugeridas e estabelecidas ao longo do tempo por várias comunidades, como a Sun Microsystems, ou a Netscape. Seguem-se alguns exemplos de convenções de nomenclatura da Sun:

  • Classes
    Os nomes das classes devem ser substantivos, em Pascal Case. Devemos tentar manter os nomes das classes simples e descritivos. Usamos palavras inteiras, evitando siglas e abreviaturas, a não ser quando a sigla é muito mais usada do que a forma longa, como em URL ou HTML. Alguns exemplos:
    class ImageSprite
    class TextFileParser
  • Métodos
    Os nomes de métodos devem ser verbos, em Camel Case. Alguns exemplos:
    run();
    runFast();
  • Variáveis
    Os nomes das variáveis devem ser formatados em Pascal Case. Apesar de permitido em termos de sintaxe da linguagem, os nomes de variáveis não devem começar por “_” ou “$”. Os nomes das variáveis devem ser curtos, mas significativos. Não se devem usar nomes de apenas um carácter, excepto para variáveis ​​temporárias "descartáveis". Os nomes comuns para variáveis ​​temporárias são i, j, k, m, e n para inteiros; c, d, e e para caracteres ou strings. Alguns exemplos:
    int    i;
    char   c;
    float  myWidth;
  • Constantes
    Os nomes de variáveis declaradas como constantes, devem ter todas as palavras em maiúsculas, separadas pelo carácter “_”. Alguns exemplos:
    static final int MIN_WIDTH = 4;
    static final int MAX_WIDTH = 999;

Microsoft .NET
As convenções de nomenclatura da Framework Microsoft .NET são muito semelhantes às da linguagem Java, em que a diferença mais evidente é a utilização do Pascal Case para o nome de métodos, em vez de Camel Case. Também existem pequenas diferenças entre as várias linguagens .NET, mas não muito significativas.

Recomendações

Finalizo com algumas recomendações baseadas na minha experiência pessoal:

  • A primeira recomendação é que usem convenções de nomenclatura. Para além das convenções das linguagens e das que são usadas nos locais onde trabalham, criem as vossas próprias convenções e tenham a disciplina de as usar sempre que possível;
  • Reforço a recomendação anterior para todos aqueles que estejam a liderar uma equipa de desenvolvimento, um projecto ou mesmo um departamento;
  • Criem convenções para os componentes de framework, serviços, componentes de front-end, áreas de negócio, etc. Não são só os nomes das variáveis que são importantes;
  • Utilizem a convenção dos namespaces (organização.aplicação.módulo) para evitar ambiguidades e colisões de nomes.

terça-feira, 15 de julho de 2014

O que há de novo no Java 8?

No passado mês de Março de 2014 foi lançada o Java SE 8. Trata-se de uma forte actualização de características e funcionalidades da plataforma Java SE, implementada pela Oracle.

Neste artigo, vamos resumir algumas das novas características e funcionalidades do Java SE 8 e do JDK 8.

Os componentes mais actualizados da plataforma Java SE, podem ser obtidos a partir de download do site da Oracle, aqui.

Linguagem Java

  • Lambda Expressions. Um novo recurso da linguagem que foi introduzido nesta versão. Elas permitem tratar uma funcionalidade como um parâmetro de um método ou código como dados. As expressões lambda permitem expressar instâncias de interfaces de método único (referidos como interfaces funcionais) de forma mais compacta.

  • Method References. Fornecem expressões lambda fáceis de ler para os métodos que já têm nome.

  • Default Methods. Permitem que novas funcionalidades sejam adicionadas a interfaces de bibliotecas e asseguram a compatibilidade binária com o código escrito para versões mais antigas desses interfaces.

  • Repeating Annotations. Fornecem a possibilidade de aplicar o mesmo tipo de anotação mais de uma vez para a mesma declaração ou tipo em uso.

  • Type Annotations. Fornecem a possibilidade de aplicar uma anotação em qualquer lugar onde um tipo é usado e não apenas numa declaração. Usado com um sistema plugin de tipos, esta característica permite uma melhor verificação de tipos, no código.

  • Melhoria da inferência de tipos.

  • Reflexão de parâmetros de métodos.

Colecções

  • As classes no novo package java.util.stream fornecer uma Stream API para suportar as operações de estilo funcional em streams de elementos. A Stream API é integrada na Collections API, o que permite operações em bulk em colecções, como transformações sequenciais ou paralelas com mapeamento reduzido.

  • Melhoria de Desempenho para HashMap com Key Collisions.

Plataforma Java SE

  • Compact Profiles. Contêm subconjuntos predefinidos da plataforma Java SE e permitem que aplicações que não necessitam de toda a plataforma sejam instaladas e executado em dispositivos pequenos.

Segurança

  • TLS 1.2 ativado por por defeito, no lado do cliente.
  • Nova variante do AccessController.doPrivileged que permite ao código validar um subconjunto de seus privilégios, sem impedir a pesquisa completa da stack, para verificar se há outras permissões.
  • Algoritmos mais fortes para criptografia baseada em password.
  • Suporte para extensão SSL/TLS Server Name Indication (SNI) em servidores JSSE.
  • Suporte para algoritmos AEAD: O provider SunJCE foi melhorado, para suportar implementação de cifras AES / GCM / NoPadding, bem como parâmetros do algoritmo GCM. E o provider  SunJSSE foi melhorado para suportar conjuntos de codificação modo AEAD base.
  • Melhorias no KeyStore, incluindo o novo tipo de Domain KeyStore java.security.DomainLoadStoreParameter e a nova opção de comando -importpassword para o utilitário keytool.
  • Resumos de mensagens SHA-224.
  • Melhoria do suporte para NSA Suite B Cryptography.
  • Melhoria do suporte para High Entropy Random Number Generation.
  • Nova classe java.security.cert.PKIXRevocationChecker para configurar a verificação de revogação de certificados X.509.
  • PKCS11 de 64 bits para Windows.
  • Novos tipos rcache em Kerberos 5 Replay Caching.
  • Suporte para Kerberos 5 Protocol Transition e Constrained Delegation.
  • Tipos Kerberos 5 weak encryption desabilitados por defeito.
  • Unbound SASL para o mecanismo GSS-API/Kerberos 5.
  • Serviço SASL para nomes de host múltiplos.
  • Bridge de JNI para JGSS nativo no Mac OS X.
  • Suporte para chaves DH Efémeras mais fortes no provider SunJSSE.
  • Suporte para personalização de preferência de conjuntos de codificação server-side em JSSE.

JavaFX

  • O novo tema Modena foi implementado nesta versão. Para mais informações, consultar o blog fxexperience.com.
  • A nova classe SwingNode permite aos programadores incorporar conteúdos Swing em aplicações JavaFX. Ver a documentação da classe SwingNode e Embedding Swing Content in JavaFX Applications.
  • Os novos controlos de UI incluem o DatePicker e o TreeTableView.
  • O package javafx.print fornece as classes públicas para a JavaFX Printing API. Ver a documentação para mais informações.
  • As funcionalidades de Gráficos 3D incluem agora formas 3D, câmara, luzes, sub-cenas, materiais, pesquisa e suavização. As novas classes de API: Shape3D (subclasses Box, Cylinder, MeshView e Sphere), SubScene, Material, PickResult, LightBase (subclasses AmbientLight e PointLight) e SceneAntialiasing, foram adicionados à biblioteca de gráficos 3D do JavaFX. A classe API Camera também foi atualizada nesta versão. Ver a documentação de cada uma das classes anteriores e Getting Started with JavaFX 3D Graphics.
  • A classe WebView oferece novas funcionalidades e melhorias. Rever Supported Features of HTML5, para obter mais informações sobre recursos adicionais de HTML5, incluindo Web Sockets, Web Workers e Web Fonts
  • Suporte de texto melhorado, incluindo texto bi-direcional e scripts de texto complexos, tais como Tailandês ou Hindu, nos controlos, e nós de texto multi-linha, texto multi-estilo.
  • Suporte para monitores Hi-DPI.
  • As classes CSS Styleable tornaram-se uma API pública. Ver a documentação javafx.css para mais informações.
  • A nova classe ScheduledService permite reiniciar automaticamente o serviço.
  • O JavaFX está agora disponível para plataformas ARM. O JDK para ARM inclui a base, gráficos e controlos que compõem o JavaFX.

Ferramentas

  • É fornecido o comando jjs para chamar o motor Nashorn.
  • O comando java lança aplicações JavaFX.
  • A página java man foi reformulada.
  • A ferramenta de linha de comandos jdeps é fornecida para analisar ficheiros de classes.
  • O Java Management Extensions (JMX) fornece acesso remoto a comandos de diagnóstico.
  • A ferramenta jarsigner tem uma opção para solicitar um signed time stamp a uma autoridade de tempo (TSA).
  • Ferramenta javac
    • A opção –parameters do comando javac pode ser usada para armazenar nomes formais de parâmetros e ativar a Reflection API para disponibilizar os nomes formais de parâmetros.
    • As regras de tipo para operadores de igualdade na Java Language Specification (JLS) Seção 15.21 agora são correctamente aplicadas pelo comando javac.
    • A ferramenta javac tem agora suporte para verificar o conteúdo de comentários javadoc que poderiam levar a vários problemas, como HTML inválido, ou questões de acessibilidade, nos ficheiros que são gerados quando o javadoc é executado. A funcionalidade é ativada pela nova opção -Xdoclint. Para mais detalhes, ver o output da execução do comando javac -X. Esta funcionalidade também está disponível na ferramenta javadoc e está activa por defeito.
    • A ferramenta javac agora proporciona a capacidade de gerar cabeçalhos nativos, conforme o necessário. Isto elimina a necessidade de executar a ferramenta javah como um passo separado no pipeline de build. A funcionalidade é ativada no javac usando a nova opção -h, que é usada para especificar o diretório onde os ficheiros de cabeçalho devem ser escritos. Serão gerados ficheiros de cabeçalho para qualquer classe que tenha ou métodos nativos, ou campos constantes anotados com uma nova anotação do tipo java.lang.annotation.Native.
  • Ferramenta javadoc
    • A ferramenta javadoc suporta a nova DocTree API, que permite tratar comentários Javadoc como árvores de sintaxe abstractas.
    • A ferramenta javadoc suporta a nova Javadoc Access API, que permite invocar a ferramenta javadoc diretamente de uma aplicação Java, sem executar um novo processo. Ver a página javadoc what's new, mais informações.
    • A ferramenta javadoc tem agora suporte para verificar o conteúdo de comentários javadoc que poderiam levar a vários problemas, como HTML inválido, ou questões de acessibilidade, nos ficheiros que são gerados quando o javadoc é executado. Esta funcionalidade está activa por defeito e também pode ser controlado pela nova opção -Xdoclint. Para mais detalhes, ver o output da execução do comando javadoc -X. Esta funcionalidade também está disponível na ferramenta javac, embora não esteja activa por defeito.

Internacionalização

  • Melhorias no Unicode, incluindo suporte para Unicode 6.2.0.
  • Adoção de Unicode CLDR Data e propriedades de sistema do tipo java.locale.providers.
  • Novo Calendário e APIs Localizadas.
  • Possibilidade de instalar um Custom Resource Bundle como uma extensão.

Implementação

  • Para applets sandbox e aplicações Java Web Start, o URLPermission é agora usado para permitir ligações de volta ao servidor a partir do qual foram iniciadas. SocketPermission já não é permitido.
  • O atributo Permissions é exigido no manifesto dos ficheiros JAR ou no ficheiro JAR principal, em todos os níveis de segurança.

Package Date-Time

  • Um novo conjunto de packages, que fornecem um modelo abrangente de data e hora.

Scripting

Pack200

  • Suporte Pack200 para Constant Pool Entries e New Bytecodes Introduzidas pela JSR 292.
  • Suporte JDK8 para alterações de ficheiros de classes, especificadas pela JSR-292, JSR-308 e JSR-335.

IO e NIO

  • Nova implementação de SelectorProvider para Solaris com base no mecanismo Solaris Event Port. Para utilizar, executar com a propriedade de sistema java.nio.channels.spi.Selector definida com o valor sun.nio.ch.EventPortSelectorProvider.
  • Diminuição do tamanho do ficheiro <JDK_HOME>/jre/lib/charsets.jar.
  • Melhoria da performance para o construtor java.lang.String(byte[],*) e para o método java.lang.String.getBytes().

Packages java.lang e java.util

  • Ordenação paralela de arrays.
  • Encoding e Decoding Base64 syandard.
  • Suporte para aritmética Unsigned.

JDBC

Java DB

  • O JDK8 inclui o Java DB 10.10.

Redes

  • Foi adicionada a classe java.net.URLPermission.
  • Na classe java.net.HttpURLConnection, se estiver instalado um gestor de segurança, chamadas que peçam para abrir uma conexão requerem permissão.

Concorrência

  • No package java.util.concurrent foram adicionadas novas classes e interfaces.
  • Na classe java.util.concurrent.ConcurrentHashMap, foram adicionados métodos para suportar operações de agregação baseadas na nova funcionalidade de streams e expressões lambda.
  • No package java.util.concurrent.atomic foram adicionadas novas classes para variáveis ​​actualizáveis ​​escaláveis.
  • Na classe java.util.concurrent.ForkJoinPool, foram adicionados métodos para suportar uma pool comum.
  • Foi adicionada a classe java.util.concurrent.locks.StampedLock, para proporcionar um bloqueio à base de capacidade com três modos para controlar o acesso de leitura/escrita.

HotSpot

  • Controladores intrínsecos de hardware foram adicionados para usar Advanced Encryption Standard (AES). As flags UseAES e UseAESIntrinsics estão disponíveis para o uso de intrínsecos AES, baseados em hardware para Intel. O hardware deve ser 2010 ou Westmere mais recente. Por exemplo, para habilitar AES por hardware, usar as seguintes flags:
    -XX:+UseAES -XX:+UseAESIntrinsics
    E para desabilitar:
    -XX:-UseAES -XX:-UseAESIntrinsics
  • Remoção do PermGem.
  • Os Default Methods na Linguagem de Programação Java são suportados pelas instruções de bytecode para invocação de método.

Outros

Tradução livre das Release Notes “What's New in JDK 8”, da Oracle.

quinta-feira, 10 de julho de 2014

Como ser um bom programador?

Como ser um bom programador? É uma pergunta interessante para fazermos a nós próprios. Isto obriga-nos a refletir sobre a arte do desenvolvimento de software. Também é uma boa pergunta para fazer aos nossos colegas. Ela pode desencadear algumas discussões interessantes sobre como podemos trabalhar em conjunto. Aqui estão cinco características que podem ser fundamentais, para ser um bom programador.

1. Decomposição do problema 

A programação trata da resolução de problemas. Mas antes de escrever qualquer código, é necessário ser claro sobre a forma de resolver o problema. Uma característica que os bons programadores têm é a capacidade de dividir o problema em partes cada vez mais pequenas, até que cada parte possa ser facilmente resolvida. Mas não basta simplesmente encontrar uma maneira de resolver o problema. Um bom programador encontra uma maneira de modelar o problema, de tal forma que o programa resultante é fácil de entender, fácil de implementar e fácil de testar.

Alguns dos programas mais complicados com que trabalhamos, só são complicados, em parte, porque a implementação não resolve bem o problema. Isso leva a um código que é difícil de entender. Quando o problema é bem modelado, temos que concordar com Bernie Cosell (excelente entrevista em Coders at Work):

“…há muito poucos programas inerentemente difíceis. Se estiver a olhar para um pedaço de código e parecer muito difícil - se não conseguir entender o que estas coisa é suposto fazer – isso é quase sempre um indício de que foi mal pensado. Nesta altura, não arregaça as mangas e tenta corrigir o código; vai dar um passo atrás e pensar sobre o problema, novamente. Quando pensar o bastante, vai descobrir que é fácil.”

2. Análise de Cenários

Os bons programadores têm a capacidade de considerar vários cenários diferentes para o programa. Isso se aplica tanto à lógica do programa, como aos eventos internos e externos que podem ocorrer. Para considerar os diferentes caminhos na lógica, eles fazem perguntas como: O que acontece se este parâmetro é null? E se nenhuma destas condições for verdadeira? Este método é thread-safe? Para descobrir quais os tipos de eventos com que o software necessita de lidar, eles vão fazer perguntas como: E se essa fila ficar cheia? E se não houver nenhuma resposta a este pedido? E se o outro servidor reinicia enquanto este servidor está a reiniciar?

Os bons programadores perguntam a si próprios: Como pode ocorrer um “break” no programa? Por outras palavras, eles têm a capacidade de pensar como testers. Em contraste, os programadores inexperientes, normalmente, consideram apenas o "caminho fácil" - o fluxo normal de controlo, quando tudo correr como esperado (o que acontece a maior parte do tempo). Mas, inevitavelmente, o inesperado acontece e o programa tem que ser capaz de lidar com isso.

3. Nomenclatura

A programação consiste em grande parte em dar nomes a coisas: classes, métodos e variáveis. Quando bem feito, o programa torna-se, em grande parte auto-documentado, o que significa que a função do programa é bastante clara apenas a partir da leitura do código fonte. Um dos efeitos do código auto-documentado é que, naturalmente, leva a existirem muitos métodos de pequena dimensão, em vez de poucos métodos grandes, simplesmente porque vão existir mais lugares para colocar nomes significativos (há outras razões pelas quais é benéfica a existência de muitos métodos pequenos).

Conseguir criar bons nomes é muito mais difícil do que parece. Uma boa citação (de Phil Karlton): "Há apenas duas coisas difíceis em Ciência da Computação: Invalidação de cache e dar nomes a coisas". Dar nomes é difícil, em parte, porque é necessário ser claro o que cada nome representa, na nossa mente. Às vezes isso não é imediatamente claro, mas só se torna evidente quando o desenvolvimento avança. Portanto, a renomeação é tão importante quanto a nomeação.

Dar nomes às coisas correctamente também inclui encontrar conceitos a serem utilizados e como esses conceitos devem ser chamados. Criar nomes distintos e bem pensados, para conceitos, que são vão ser usados ​​de forma consistente (no programa e quando se discute o domínio com programadores e não programadores), torna a escrita do programa muito mais fácil.

4. Consistência

Talvez o maior desafio na programação esteja em gerir a complexidade. A consistência é uma forma de combater a complexidade. Ela diminui alguma da complexidade, por nos permitir ver os padrões e inferir como as coisas são chamadas, usadas ​​e tratadas. Com consistência, não precisamos usar o poder do cérebro para nos lembrarmos de excepções e variações aleatórias. Em vez disso, podemo-nos concentrar na complexidade essencial, não na complexidade acidental.

A consistência é importante em toda a linha. Aplica-se a nomes de variáveis ​​e métodos, a divisão em módulos, a estrutura de directórios, o GUI, tratamento de erros, logging, a documentação, etc. Por exemplo, se algumas variáveis ​​estão relacionados e aparecem juntas (em declarações, chamadas a métodos ou como colunas numa BD), então devemos usá-las sempre na mesma ordem. Assim, torna-se mais fácil ver se alguma está a faltar, ou se foram misturadas ou confundidas. Para uma operação, se for chamada “Apagar” num dado lugar, não a chamar “Remover” noutro lugar – usar sempre o mesmo nome. Steve McConnell também tem alguns bons conselhos sobre o uso de opostos (precisamente em Code Complete). Por exemplo, begin/end são opostos, assim como são start/stop. Não misturar nomes de pares diferentes (p.ex., begin/stop) quando se trata de opostos.

Ao modificar um programa, podem ser introduzidas inconsistências. Programadores desleixados não verificam se o que acrescentam é consistente com o código existente ou não. Os bons programadores são incansáveis ​​no sentido de garantir que, mesmo os pequenos detalhes estão correctos. Eles sabem o quão importante é a consistência na luta global contra a complexidade.

5. Formação/Aprendizagem

Como programadores de software, estamos constantemente a aprender. Antes de adicionar um novo recurso, temos que entender o que ele é suposto fazer. Antes de adicionar código a um programa já existente, normalmente, temos que saber o que o código existente faz, a fim de ajustar a nova funcionalidade corretamente. Também temos que aprender sobre os sistemas circundantes, a fim de interagir com eles corretamente. Portanto, a capacidade de aprender rápido, faz de cada um de nós um programador muito mais eficaz.

Além disso, como o ritmo de desenvolvimento e evolução no campo da Engenharia de Software é tão alto, há um fluxo constante de novas linguagens, ferramentas, técnicas e frameworks para aprender. Podemos ver isso como bom ou como mau. Fred Brooks marca a aprendizagem como uma das alegrias do ofício. Aprender coisas novas é bom em si mesmo. Significa, também, que a vida como programador nunca é chata.

Conclusão

Todas as características e competências acima são genéricos - nenhuma delas é específica a qualquer linguagem, framework ou tecnologia. Quem as possuir, pode rapidamente aprender uma nova linguagem ou ferramenta, e escrever um bom software nesse ambiente. Além disso, porque elas são de natureza geral, não se tornam obsoletas num par de anos.

 

Tradução livre do artigo “What Makes a Good Programmer”, de Henrik Warne.

segunda-feira, 7 de julho de 2014

Utilização da Memória em .NET - Conceitos importantes

Introdução

Este artigo irá debater alguns conceitos importantes no .NET:

Vamos começar por descrever o que acontece internamente na memória do computador, quando uma variável é declarada, introduzindo de imediato aos conceitos de stack e heap. De seguida vamos analisar os tipos de valor e os tipos de referência e alguns dos seus fundamentos e funcionamento. Finalmente vamos analisar as operações de boxing e unboxing e como estas afectam a performance das aplicações.

Conteúdo

Memória Stack e Heap 

Quando o computador está em operação normal a memória RAM contém o código e os dados dos componentes do sistema operativo (SO) e aplicações que estão em execução.

A memória da aplicação é a porção da memória alocada pelo SO para executar cada aplicação. Esta memória é dividida em duas “zonas”: stack e heap.

RAM do computador

stackA memória stack, segue uma sequência de alocação estática, do tipo pilha, i.e., os dados são adicionados ou removidos numa lógica LIFO (Last In First Out) – o último a entrar é o primeiro a sair.

A stack é responsável por manter o controlo da memória necessária à execução da aplicação.

A heap é uma memória de alocação dinâmica. Os dados não são alocados sequencialmente nem em nenhuma ordem específica, como no caso da stack.

O que acontece quando declaramos uma variável?

Quando declaramos uma variável numa aplicação, a Framework .NET começa por alocar um bloco de memória RAM. Este bloco de memória é identificado internamente por um endereço, mas tem mais três características definidas: o nome da variável, o tipo de dados e o valor. Declaração Variável

Isso foi apenas uma explicação muito simples do que acontece na memória. O tamanho do bloco de memória alocado, bem como o tipo de memória a utilizar (stack ou heap), dependem do tipo de dados da variável.

No exemplo acima, vamos guardar um valor do tipo int, como tal, necessitamos de um bloco de 32 bits = 4 bytes, e a variável vai ser guardada na memória stack (nas próximas secções veremos porquê).

De forma a percebermos melhor o que são a stack e a heap, vamos analisar o que acontece internamente, durante a execução deste pequeno bloco de código:

public void MethodX()
{
    int x = 5;
    int y = 10;
    Class1 obj;

    obj = new Class1();
}

Vamos analisar linha a linha, para percebermos o que acontece internamente:

Linha 1
Quando esta linha é executada, o compilador aloca uma pequena quantidade de memória na stack e guarda lá a variável x.

Linha 2
Na próxima linha de código, o compilador aloca outro bloco de memória, na stack, empilhado por cima do bloco anterior e guarda a variável y. Na stack, for causa da lógica LIFO, os blocos são alocados e desalocados sempre na mesma ponta da memória - no topo da pilha.

Linha 3
Nesta linha, o compilador aloca mais um bloco de memória na stack, onde vai guardar um ponteiro para um objecto da classe Class1. Um ponteiro não é mais que um endereço de memória.  Como a classe ainda não foi instanciada, o ponteiro tem um valor especial que é null.

stackLinha 4
O operador new dá ordem ao compilador para criar uma instância da classe, para criar um novo objecto. Isto consiste no seguinte conjunto de operações :

  • É alocado um bloco de memória na heap, que permita guardar um objecto da classe Class1 (o compilador sabe determinar quantos bytes são necessários).
  • O endereço de memória do objecto é guardado na stack, no bloco identificado pela variável obj. Para o programador, o valor concreto deste endereço não interessa, é da responsabilidade do SO. O ponteiro é simplesmente representado pela variável.

stack & heap

Final do método
Quando o compilador termina a execução do método, limpa todas as variáveis de memória que lhe estão a atribuídas na stack, ou seja, a memória é desalocada, seguindo uma lógica LIFO. Todavia, a memória heap continua alocada. A limpeza desta memória ocorre mais tarde e é da responsabilidade do Garbage Collector.

Limpar memória

Os pontos importantes a reter é que os ponteiros são guardados na stack e as instruções do tipo “Class1 obj;” não alocam memória para uma instância da classe, simplesmente alocam espaço na stack para o ponteiro e colocam o seu valor a null. Só quando é executado o operador new é que é alocada a heap, é criado o objecto e atribuído o valor ao ponteiro.

Em resumo, podemos dizer que uma instrução de declaração de uma variável provoca que a memória stack seja alocada. A memória heap só é alocada através de uma instrução com o operador new.

Agora, muitos programadores podem estar a perguntar-se do porquê de dois tipos de memória. “Não podemos simplesmente alocar tudo em apenas um tipo de memória e pronto?”

Se analisarmos com atenção, os tipos de dados primitivos não são complexos. Possuem valores únicos como "int i = 0". Os tipos de dados de objectos são complexos. Referenciam outros objetos ou outros tipos de dados primitivos. Por outras palavras, possuem referências a outros valores múltiplos e cada um destes deve ser armazenado na memória também. Tipos de objecto necessitam de memória dinâmica, enquanto os tipos primitivos necessitam de memória estática. Se a exigência for memória dinâmica ficam alocados na heap, senão, vão para a stack.

Tipos de Valor e Tipos de Referência

Depois de termos compreendido os conceitos de stack e heap e de termos analisado o que se passa na memória do computador quando se declara uma variável ou se instancia um objecto, vamos analisar os conceitos de Tipo de Valor e Tipo de Referência.

Os Tipos de Valor são aqueles que guardam os dados na mesma localização da memória referenciada pela variável. São os tipos primitivos que discutimos anteriormente, que são alocados na stack.

Os Tipos de Referência guardam um ponteiro para a localização dos dados, que estão numa zona de memória diferente. Estes são os tipos complexos, que exigem memória dinâmica. Ficam alocados na heap, mas é criado um ponteiro na stack que referencia essa localização na heap.

Vejamos então o que acontece na memória quando usamos Tipos de Valor:

public void MethodY()
{
    int i = 5;
    int k = i;
    i = 10;
}

Linha 1
O compilador aloca memória na stack e guarda a variável i.

Linha 2
O compilador aloca memória na stack, para guardar a variável k e copia para lá o valor da variável i. As variáveis têm cópias cópias diferentes.

Linha 3
O compilador actualiza, na memória, o valor da variável i. A variável k não é afectada.

Tipos de ValorE agora vejamos o que acontece com os Tipos de Referência:

public void MethodZ()
{
    Class1 ob1 = new Class1();
    Class1 ob2 = ob1;
    ob1 = null;
}

Linha 1
O compilador aloca memória na stack para o ponteiro ob1. Depois aloca memória na heap para o ojecto e insere o endereço no valor do ponteiro.

Linha 2
O compilador simplesmente aloca memória na stack, para o novo ponteiro ob2 e copia para lá o valor da variável ob1. Neste caso, somente o valor do ponteiro é copiado, i.e. o endereço de memória. O objecto em si não é copiado.

Tipos de ReferênciaLinha 3
O valor do ponteiro ob1, na stack é colocado a null. Nada acontece ao objecto, na heap. Como os ponteiros estão em blocos distintos na stack, o ponteiro ob2 também não é afectado.

ponteirosQuais são os Tipos de Valor e os de Referência?

Depois de termos compreendido o que são os Tipos de Valor e os Tipos de Referência e como funcionam em termos da memória do computador, é legítimo colocar-se uma questão: dos tipos pré-definidos na Framework .NET, quais são de valor e quais são de referência?

Tipos de Valor (C#), por categoria:

Enumerations

Strucs

Tipos de Referência (C#)

Boxing e UnBoxing

Após termos adquirido algum conhecimento sobre tipos de dados e o seu respectivo tratamento no .NET, vamos tentar perceber o impacto, em termos de performance, da transferência de dados entre a stack e a heap e vice-versa.

Quando movemos de um tipo de valor para um tipo de referência, os dados são transferidos da stack para a heap. Quando movemos de um tipo de referência para um tipo de valor, os dados são transferidos da heap para a stack. Estas operações chama-se, respectivamente, Boxing e UnBoxing.

Vamos vero que acontece na memória quando realizamos estas duas operações.

public void MethodK()
{
    int i = 5;
    object ob1 = i;
    int k = (int)ob1;
}

Linha 1
Como já sabemos, a variável i é guardada na stack.

Linha 2
O compilador guarda o ponteiro ob1 na stack e aloca memória na heap para o ojecto, para onde copia o valor que está na variável iBoxing

Linha 3
O compilador aloca memória na stack, para a variável k e copia da heap o valor que está guardado no objecto – UnBoxing

Boxing & UnBoxing

As operações de Boxing e UnBoxing têm impacto na performance da execução da operação. Por exemplo, fez-se uma experiência de executar 1000 vezes os dois métodos abaixo indicados, registando-se o tempo de execução de cada uma destas operações.

private void BoxUnbox()
{
    int i = 1234;
    object ob1 = i;
}

private void SimpleAssign()
{
    int i = 1234;
    int k = i;
}

A operação de executar 1000 vezes o primeiro método demorou cerca de 3.5 segundos enquanto o segundo método demorou apenas 2.5 segundos. Registámos assim uma degradação de performance de 40%.

Por outras palavras, há que evitar a utilização de operações de Boxing e UnBoxing. Elas têm um impacto significativo na execução das aplicações. E em projectos em que seja mesmo obrigatório fazer boxing e unboxing, usar apenas nas situações em que for absolutamente necessário.

Bibliografia recomendada

  • Farrel, Chris e Harrison, Nick, “Under the Hood of .NET Memory Management”, USA, Simple Talk Publishing, 2011, ISBN 978-1-906434-74-8

 

Nota:

- Os exemplos de código apresentados foram desenvolvidos em linguagem C#. Poderiam estar em qualquer outra linguagem do .NET. A opção pelo C# deveu-se simplesmente a uma maior facilidade pessoal e abrangência em termos de documentação disponível para consulta.