desen de 03092012 a 09092012




commands

JSF

agendam

navegacao




Dia: 03092012

link

Longing For Code Correctness By Andrew Binstock, August 26, 2012

12 Comments

The longer I write code, the more I yearn for code correctness. Despite the work this extra step presents, commercial ventures, especially Wall Street, would do well to embrace it. When I was young and first got into programming seriously, I reveled in working at the lowest levels of code. I loved (loved!) assembly language and could think of no greater happiness than doing clever things with registers and writing tight, fast code that squeezed into the minimum amount of RAM and delivered great performance.

As time passed, the lack of portability and the burden of learning the ins and outs of every new architecture got me interested C. In C, I thought I'd finally found the gateway to paradise: portable assembly language. What could possibly be better?

But after nearly 10 years of working in C on my personal projects, I tired of never being able to bring anything to a close, unless the project was a minor utility. Anything bigger never bore the full elements of my original ambitions. Feature lopping was a common practice. And even then more modestly resized projects, under unsparing hours in the debugger, would eventually be consigned to the groaning shelf of unfinished projects.

I had to move on. I went to Java, which drew me with its siren song of portability, performance, excellent tools, and enormous libraries. Not having to code one more linked list had remarkable appeal. So did the superior testing tools that would allow me to write code and test it quickly. This enabled me to avoid spending lots of time in the debugger. Ever since, Java has been my base language for personal projects, both large and small. (I am not implying that it will be my final destination. I continue to be troubled by the inconvenience of delivering software to non-developer users, who are not at all comfortable downloading or updating Java. A garbage-collected, portable, binary language with good libraries that is not as complex as C++ has great appeal to me. Which is certainly why I feel so interested in Go at the moment.)

As time has passed, though, I've found myself constantly frustrated by the feeling that no matter how much I test my code, I can't be sure with certainty that it's right. The best I can say is that the code is probably right. But when I write code for others to use, I want it to be completely reliable. This concern has led me to embrace tools that enforce the correctness of the code.

Long ago, for example, I adopted Bertrand Meyer's concept of design-by-contract (DBC), which suggests that every function should test for pre-conditions, post-conditions, and invariants. In Java, I do this with the excellent Guava library. So my methods tend to have tests, especially at the beginning where each parameter is carefully checked. I test invariants and post-conditions primarily in unit tests, which is probably not ideal, but it moves some of the validation clutter out of the code.

I'd like to go beyond this. First, I wish the languages provided better support for correctness. For example, I think floats should default to an uninitialized value of NaN (not a number). I wish integers had a NaN equivalent and that all primitive data types and strings had an invalid value to which they would be initialized by the language. A whole class of errors would go away. (In the absence of this, the Java compiler's ability to identify uninitialized values is undeniably helpful.)

But moving beyond these simple levels is where things become a lot more difficult. I have essentially two major options. The first would be to code in some kind of modeling language. Then use a tool, such as Conformiq's products or others, to generate thousands of tests. Then, automatically generate the code from the models and run all the tests. This is a highly effective way of writing solid code, and it is favored widely in Europe. However, I'm a coder at heart, and I'm not sure coding at a diagrammatic level is really my cup of tea.

The second alternative is to use languages that strongly support correctness. There are not many. Ada goes farther than Java in this regard. And Eiffel perhaps farther yet. But probably the one that does the most is Spark, an Ada subset. Developed in the U.K., Spark uses a system of annotations that are embedded in comments at the start of each method. The code can then be verified by assorted tools that check it against the annotations. Free and commercial versions of SPARK tools exist today.

Specifying code functionality in this way is undoubtedly an extra step with lots of additional typing involved. But it has advantages outside of proving correctness: To start with, it more fully documents the code. And, as Edmond Schonberg (formerly a professor of computer science at NYU and now an executive at AdaCore) mentioned to me in a pick-up conversation, by writing out the specifications before the code, most of the same benefits that tests deliver to TDD aficionados accrue to coders \u2014 the tests or specifications force you to spell out what you're doing before you begin to code. "Lots of defects get caught by this simple step," according to Schonberg. I believe it.

And I rue that in the U.S., only a few industries (mostly embedded, automotive, and avionics) are interested in high levels of code correctness. It's a topic that is dismissed as a luxury by mainstream programmers because it appears to interfere with the ability to deliver software quickly.

I have some sympathy for this point of view. If I were to indulge my desire for correctness more deeply, I would certainly want to have a scripting language as a secondary tool for testing out ideas and banging out code that doesn't need to be perfect. I don't want correctness to push me back to the days of coding in C when nothing was ever completed. However, as the recent Knight Capital disaster on Wall Street demonstrates, the general resistance to correctness felt by business programmers is a conceit that cannot always be accommodated without considering its occasionally dire consequences.

\u2014 Andrew Binstock
Editor in Chief
alb@drdobbs.com
Twitter: platypusguy


link

Andrew koening

More Thoughts on Undefined Behavior August 31, 2012
1 Comment

I first started thinking about undefined behavior as an important issue in the 1970s, when I read Edsger Dijkstra's then recently published book A Discipline of Programming. Among other ideas, this book advanced a notion of what a program should be that was quite radical at the time, and has become much more mainstream \u2014 though far from universal \u2014 today.

Dijkstra argued that instead of thinking of a program as a set of instructions for a computer, we should instead think of a computer as a device that is intended to execute our programs. This distinction may seem like splitting hairs, but it becomes an important part of deciding how we think about software errors. If a program's purpose is to instruct a computer, then it is the programmer's responsibility to issue only valid instructions. If a computer's purpose is to execute our programs, then it is the computer's responsibility to detect and refuse to follow invalid instructions.

In the early days of computing, the first of these viewpoints was overwhelmingly the most common. Even trivial coding errors would often result in the entire machine stopping instantly, with no easy way to determine where or why it had done so. A few programming languages, such as BASIC and APL, tried to report all runtime errors in their programs; but as a result of this checking, many people considered them too slow for serious applications. As computers became faster, programmers became more willing to accept the idea that some of that speed should go into checking that programs contained only well-defined operations. Some languages, such as PL/I, offered a choice of implementations, so that programmers could choose how aggressive the implementation would be about runtime checking.

One language whose designers made a particularly interesting choice in this regard was Modula-3. As its name suggests, a Modula-3 program consists of modules. Each module is either safe or unsafe. Programmers choose modules' designations, with safe being the default. The language also divides errors into checked and unchecked. All compile-time errors are checked; an unchecked runtime error is what a C or C++ programmer would call undefined behavior. A program that encounters a checked runtime error will always report that error \u2014 at least if the language is implemented correctly.

What interests me particularly about Modula-3 is that it allows unchecked errors to occur only in unsafe modules. Therefore, unless you designate a module as unsafe, the implementation is required to generate code that checks for all possible runtime errors. This requirement becomes tricky in the case of pointers \u2014 which Modula3 has \u2014 for the same reason as in C++, namely that deleting the object to which a pointer points invalidates all pointers to that object. Modula-3 solves that problem in a radical way: It says that its equivalent of the C++ delete expression is permitted only in unsafe modules. Of course this policy would lead to memory leaks were it not that Modula-3 requires its implementations to include a garbage collector.

In other words, the Modula-3 designers concluded that garbage collection is necessary for runtime safety as follows:

However, garbage collection has some disadvantages of its own:

C++ smart pointers offer the possibility of a similar level of dynamic-memory safety as garbage collection, but with a different set of performance tradeoffs. Their very existence tells me that despite the more than 35 years since Dijkstra published his book, programmers are still trying to resolve the tension between safety and performance.


LIMINE OS BACKUPS ANTIGOS DO IPAD E IPHONE PARA LIBERAR ESPA\307O EM SEU COMPUTADOR!

Ol\341 amigos, hoje vou passar uma dica de rotina para recuperar espa\347o em disco de seu computador, seja ele Mac ou PC, como sabemos os backups dos dispositivos iPad, iPhone ou iPod ocupam bastante espa\347o em seu computador, mem\363ria esta que um dia poder\341 \u201cficar curta\u201d e se tornar uma terr\355vel dor de cabe\347a.

A maioria dos computadores atuais possuem HDs com bastante espa\347o, geralmente com 500 GB ou mais, por\351m, imagine seu dispositivo de 16 GB sendo backupeado mais de 10 vezes? J\341 ocuparia grande parte de seu espa\347o dispon\355vel, portanto, hoje ser\341 o dia de aprender a limpar os backups antigos.

Essa dica \351 v\341lida para quem faz os backups no computador, j\341 quem faz o backup no iCloud n\343o ter\341 o que eliminar. Mas, j\341 que entrei nesse assunto eu prefiro faz os backups no computador pois o iCloud somente nos oferece 5 GB gratuitos, se voc\352 possui mais de um dispositivo dificilmente conseguir\341 se virar sem comprar espa\347o extra.

Pronto para aprender com um f\341cil t passo-a-passo?

Limpando backups antigos para liberar espa\347o

O processo \351 muito simples, basta:

Se voc\352 tem mais de um dispositivo certifique-se de deixar o \372ltimo backup de cada um, normalmente esse procedimento \351 recomend\341vel a cada 2 ou 3 meses, principalmente se voc\352 ao inv\351s de HDD possui um SSD onde cada megabyte \351 precioso.

Pensou que seria mais dif\355cil? Se engana quem pensa que para ser uma dica excelente precisa ser complicada! Voc\352 j\341 conhecia esse procedimento? Conte-nos.

Fonte: Actualidad iPad


Nokia Purity HD ganha NFC e cancelamento de ru\355do

A parceria entre Monster e Nokia j\341 rende novos produtos. Apresentados na IFA 2012, os novos fones de ouvido Purity HD Pro adicionam pareamento NFC, cancelamento de ru\355do e Bluetooth ao acess\363rio. Com o mesmo layout do modelo anterior, os novos fones ser\343o vendidos nas cores preto, amarelo, branco e vermelho. O pre\347o estimado \351 de 376 d\363lares. Assim como o Zik, da Parrot, o Purity HD Pro possui um sensor para ativar o cancelamento de ru\355do quando colocado na cabe\347a e interromper sua execu\347\343o quando removido. Segundo a Monster, a bateria oferece autonomia de 24 horas de m\372sica ou liga\347\365es.


BMW estreia mouse para gamers

\u201cComparar este mouse com um mouse comum \351 como comparar um carro esportivo com um popular\u201d. \311 o que diz a BMW, que desenvolveu um mouse chamado \u201cLevel 10 M\u201d com visual futurista e que pretende marcar uma mudan\347a no cen\341rio de games.

A parte de cima do mouse, onde se posiciona a m\343o do jogador, pode ter ajustada sua inclina\347\343o lateral ou de altura. Perfura\347\365es tamb\351m na parte superior faz a ventila\347\343o para refrescar as m\343os do jogador.

O mouse \351 feito com uma liga de metais que tamb\351m \351 utilizada na aeron\341utica e na arquitetura. Al\351m disso, possui tamb\351m um software capaz de identificar as taxas de DPi dos games.

O Level 10 M \351 fabricado pela Thermaltake\u2019s e pode ser encontrado em lojas online e f\355sicas nos Estados Unidos, Europa e \301sia por US$ 99.



link

Testing OO Systems, Part 1

By Allen Holub, May 15, 2012

1 Comment

OO tests stimulate an object and observe that object's behavior. The tests do not look at the object's state to judge whether or not the test succeeds, they just look at the object's behavior. When I call dog.expressHappiness(), my test succeeds when I observe that wagTail() is called. I would never look inside the dog at the isHappy field.

The subject for this and next month's columns is testing, with a focus on OO systems. This month we'll cover the basics, looking at tests for the code that I've presented over the past few months: the Configurations, Places, and ExtendedLogger classes. You may want to go back and reread those articles so that you can see what we're testing. Next month I'll focus more on mock-based testing (and mock-based design).

The Basics

The test code from this month is pretty straightforward, but serves as a vehicle for talking about core issues.

I've mentioned this before, but the one essential principle that underlies all object oriented systems is "abstraction." Your objects should be black boxes. You know what the interface to the object looks like, but the way in which the object works should be completely hidden. This hard-core abstraction has a highly desirable side effect: You should be able to completely change the implementation of an object \u2014 literally throw out all the field definitions and all the method bodies \u2014 and as long as the interface hasn't changed, the clients (the objects that use the class you just modified) should be unaware that you've made any changes.

The opacity that OO abstraction entails controls the way an object is put together in really fundamental ways. For one thing, there can be no so-called "properties" \u2014 getter or setter ("accessor" or "mutator") methods that just return or modify fields \u2014 because these methods provide too much information to the outside world about how the object works internally. You typically can't change the field that underlies the getter/setter, much less eliminate that field altogether, without severely impacting all the clients. It's a maintenance nightmare.

Not only does this approach improve maintainability, you can't do any sort of Agile development without it. All agile processes require you to easily introduce new business requirements into your code. If all of your classes are coupled to each other through getters and setters, however, it's almost impossible to do that. Very small changes ripple out to the entire program very quickly, and making even trivial modifications to one class can touch just about every class in the system by the time your done. You just can't shoehorn that much work into the short cycle time required by all Agile processes.

On a purely structural level, the basic principle is the Law of Demeter (LoD): "Talk only to your friends." (The phrase was coined by Ian Holland, but was popularized in many books, most notably Hunt and Thomas's The Pragmatic Programmer. For the classicists amongst us, the name has only a tenuous relationship to Greek goddess of the harvest. The Law came out of Project Demeter, whose central philosophy was "grow software in small steps," which certainly should be the law, but doesn't seem to have a pithy name.) A great example (from Freeman, Mackinnon, Pryce, and Walne's great paper Mock Roles, Not Objects):

"Programmers should avoid writing code that looks like: dog.getBody().getTail().wag(); colloquially known as a 'Train Wreck.' This is bad because this one line depends on the interfaces and implied structure of three different objects. This style laces structural dependencies between unrelated objects throughout a code base. The solution is described by the heuristic 'Tell, Don't Ask,' so we rewrite our example as: dog.expressHappiness() and let the implementation of the dog decide what this means."

That is, you may choose to implement expressHappiness() inside the dog as body.wagTail(), but you now have the option of doing something else entirely. The problem with the "train wreck" anti-pattern is that changing any of the classes in the chain breaks the entire chain, so it's very fragile. The "friends" in "talk only to your friends" are your immediate neighbors in the network of objects that comprise your program. Talk only to objects to which you have a direct reference (stored in a field or passed into a method as an argument). A train wreck is, of course, a series of getters.

Note, by the way, that there's a big difference between a getter or setter that's doing nothing but providing public access to a field and a method that implements a well-thought-out interface by returning or modifying a field. The first case breaks the abstraction. In the second case, the fact that the easiest way to implement some method is to simply sets a value in no way precludes you from completely changing that method to do something else entirely in the future.

That "Tell, Don't Ask" aphorism is, I think, more helpfully expressed as "Ask for help, not for information." I discussed the principle, in the context of making your code smaller, in Solving the Configuration Problem for Java Apps, the article that started this series, but it really fundamentally changes the way that you structure your code. You end up thinking about the responsibilities of the objects and the operations that they have to support to implement those responsibilities. You'll need fields to implement the methods, but that's just an implementation detail that doesn't even come up at design time, and is never exposed to the outside world.

Testing Abstractly
So how does all this apply to testing?

The notion that changes to the object shouldn't affect the clients applies in spades to tests. If both your test and the object that you're testing change at the same time, you have no idea whether a failure indicates a broken test or a broken object. Ideally, you want to make changes to the object, run the tests, and then move on if the tests pass. If your tests are suspect, you can't do that. To make the test immune to changes in the tested object, the object must be a black box to the test. That is the test must work entirely through an interface that provides no direct access to the inner workings of the object. The test should act like any other client, and radical changes to the implementation of the object under test shouldn't affect the tests themselves. You just can't get that level of isolation if you expose implementation with things like getters and setters.

Having solid tests also changes the way that you work. I typically get nervous if I add more than about 20 lines of code to a class without running the at least a subset of my unit tests, and I've found that I work much faster when I work that way. Bugs tend to be very easy to find, because they're probably somewhere in those 20 lines. If you test once a day, you need to look at an entire day's work to find the bug. I'm typically not doing formal "test driven development" \u2014 I'm not building the tests before I write any code \u2014 but instead add unit tests incrementally as the code evolves. I do add tests when I've added something new to the object. When I find a bug, I generally add a test that makes sure that the bug doesn't reappear. All these tests really free up your ability to experiment since you can immediately tell if an experiment fails. More to the point, you can't really refactor if you don't have the tests in place, because you have no other way of telling whether or not your refactoring has broken something.

This test-often strategy depends on the tests testing behavior without knowing how the object works under the covers. That is, if I need to introduce significant structural changes to a class without changing the tests, then the tests can't assume anything about how the object is implemented. If, for example, my test validates the success of a method call by using getters to examine the fields that represent the interior state of the object, the test will fail outright if I need to change (or eliminate) those fields, and can fail subtly if I introduce a field that the test doesn't know about. Once I've determined that a test works properly, I never want to change it again.

OO tests, then, stimulate an object and then observe that object's behavior (which is often best done with mocks; I'll discuss those next month). The tests do not look at the object's state to judge whether or not the test succeeds, they just look at the object's behavior. When I call dog.expressHappiness(), my test succeeds when I observe that wagTail() is called. I would never look inside the dog at the isHappy field, nor would I have a getIsHappy() method and call it in a test. Sometimes, the result of the stimulus might be quite distant from the stimulus itself. For example, I might verify that a notifyByEmail() method on a Customer object worked by seeing that the email actually arrives at the correct place, effectively testing the entire email chain. I couldn't do that, however, If I didn't have a fully functional email system, and I would have written many smaller tests in the process of getting that email system working (all of which would still be in place).

Boundary level testing is particularly useful when you need to modify a complicated existing system that has no unit tests (which is all too often the case \u2014 maybe I work for too many startups). Start introducing unit tests at the outer edges of the system (test that the mail arrives). The obvious problem is that, when (not if) something doesn't work, you have no idea where the problem lies, but at least you can now tell that there is a problem. Over time, as you work on the system, you can add unit tests that verify that the innards of the system are working as expected.

Note, by the way, that this same look-at-behavior-not-state argument applies to examining the state of the database as well. It's a really bad idea to validate a method call by looking at the database to see if some row has been modified in some way (because changes to the schema break all the tests). A better approach looks at the way that database-dependent objects behave. For example, let's say that a "User" object in your system is defined by a user name expressed as an email address and a password. When you create a new user, you could look at the database to see if the new user was created as expected. However, if you can log in successfully, you can infer that the database was set up correctly without having to look at the database at all (assuming that the log-in process was validated by a previous test, of course).

If you can't test an object via behavior, then you should really wonder if the work you just did has any value at all. Ultimately, it's the behavior of the system that you care about, not it's internal state. If all the work that you just did doesn't change any behavior, then what have you accomplished? This argument applies just as much to the object level as it does to the system level. If an object's behavior doesn't change, then what use was the change you just made?

You can also use behavior-based tests to identify (and eliminate) useless parts of the code. If, for example, changing a method argument doesn't change any behavior, then that argument (and all the code that uses the argument) is unnecessary and should be purged. Small programs are faster, easier to understand, and easier to maintain. If a method is never called, it shouldn't exist.


Hackers invadem notebook do FBI e vazam 1 milh\343o de identificadores \372nicos de iGadgets

Cada iGadget tem um UDID (Unique Device Identifier, ou Identificador \332nicos de Dispositivo). Era atrav\351s dele que empresas de publicidade conseguiam nos rastrear, a fim de oferecer an\372ncios cada vez mais personalizados \u2014 recentemente, por\351m, a Apple acabou com a festa e estaria trabalhando em uma nova ferramenta para oferecer as companhias/desenvolvedores.

J\341 deu pra ver que o UDID \351 importante, certo? Pois hackers do grupo AntiSec vazaram 1 milh\343o de UDIDs obtidos de um laptop do Federal Bureau of Investigation (FBI). Eles conseguiram a fa\347anha na segunda semana de mar\347o, invadindo um notebook da Dell utilizado pelo supervisor/agente especial Christopher K. Stangl (da Equipe Regional de Ciberativismo do FBI e do Escrit\363rio de Evid\352ncias do FBI de NY) atrav\351s da vulnerabilidade AtomicReferenceArray, no Java.

t O arquivo NCFTA_iOS_devices_intel.csv foi baixado, e nele, uma lista de 12.367.232 iGadgets, incluindo UDIDs, usernames, nomes e tipos de aparelhos, tokens de notifica\347\365es, CEPs, n\372meros de celulares, endere\347os, etc.

Segundo eles, a lista foi publicada para chamar a aten\347\343o ao fato de que o FBI supostamente usa a informa\347\343o para rastrear cidad\343os. Grande parte dos dados pessoais foi cortado, mesmo assim, est\343o l\341 uma quantidade significativa de informa\347\365es.

O AntiSec sugere que o FBI est\341 usando a informa\347\343o para monitorar cidad\343os. N\343o est\341 claro, por\351m, se todas essas alega\347\365es s\343o verdadeiras \u2014 mas se forem, o acr\364nimo NCFTA no nome do arquivo pego pelo AntiSec provavelmente vem de National Cyber-Forensics & Training Alliance, que \u201cfunciona como um elo entre a ind\372stria privada e as for\347as da lei.\u201d Se for o caso, isso pode significar que a Apple est\341 fornecendo dados de usu\341rios ao FBI atrav\351s da NCTFA, que o FBI est\341 garimpando seus dados\u2026 ou algo completamente diferente disso. Independentemente do que for, ao que tudo indica n\343o conseguiremos nenhuma atualiza\347\343o sobre o caso por enquanto; os hackers se recusaram a falar com os jornalistas at\351 que o nosso colega da Gawker, Adrian Chen, pose \u201ccom uma foto enorme dele vestindo um tutu de bal\351 e um sapato na cabe\347a, sem photoshop.\u201d Isso lhe d\341 uma ideia do tipo de gente que teve acesso aos seus dados pessoais. Para ver se o seu cadastro est\341 no milh\343o que j\341 foi divulgado, v\341 at\351 o banco de dados verificador do TNW. E lembre-se, mesmo que o seu n\343o apare\347a agora, ainda existem outros 11 milh\365es de onde esse saiu. [Pastebin via YCombinator via The Next Web]


Vers\343o 8 do Parallels Desktop para Mac est\341 agora dispon\355vel para todos

Anunciado no m\352s passado e detalhado h\341 poucos dias, o virtualizador de sistemas operacionais Parallels Desktop 8 para Mac est\341 agora dispon\355vel para todos. O upgrade de vers\365es anteriores sai por R$90, enquanto a vers\343o completa fica por R$180. Quem quiser pode baixar uma trial aqui. [Parallels Desktop 8 for Mac]