I'm not an avid book reader, so I feel that my book suggestions should be taken seriously, since there are so few books I can really recommend. I think there are a few software-engineering-related books that every good programmer should have on their shelf. I will list these books, roughly in order of importance. I've also listed each book's latest edition (that I know of).
The C Programming Language, 2nd Edition by Brian W. Kernighan and Dennis M. Ritchie
The C bible. C is still an important language for many programmers to learn, and this is the book to use to learn it. Never before or since has a programming language had a textbook so thorough. I only wish that Java or C++ had a similar textbook that I could recommend as highly. Maybe it's because C is a small language, but this book works well whether you're learning C for the first time, or you just need a reference. The only downside is that the latest version of this book covers ANSI C, instead of either the newer revisions, C99 and C11. For that reason, if you're using a C99 or C11 compiler, this book is somewhat deprecated. C99 made a lot of important changes to the language. However, the book is still a good starting point if you don't know any C (or, again, if you're using an older compiler).
Introduction to Algorithms, 3rd Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
This book contains all the information you need to know about algorithms and data structures, including their pseudocode implementations and computational complexity. I suggest it to everyone who is applying to Google as a software engineer. The only issue is that it is too complete, and contains a lot of extraneous information. It's not a book you read cover to cover. Also, I'm not a big fan of their "pseudocode." A more Java-like or Python-like language would be easier to read. As a software engineer for any company that relies on speed for computing large amounts of data, you will need to know the most efficient way to solve your problem. This book will help you get there.
Effective Java by Joshua Block
That's great that you can write a one-line method to sort an array. Now, graduate from a programmer to a software engineer by learning why that is awful. Effective Java tells readers about readability and other important issues that come up with writing code in a work environment. Basically, it's a collection of tips for writing readable, maintainable Java code. Do you swallow InterruptedExceptions, that is, catch them and then simply throw them away? If so, Joshua Block will tell you why you're breaking his heart and the heart of everyone around you. (For those who just want the answer, read this. Or the simple answer is that you may prevent a program from being killed when it needs to die.)
Software Project Survival Guide by Steve McConnell
This book is written more for managers and team leads, but is useful to all engineers. It describes in detail the basic ideas and reasoning behind a waterfall software engineering process. A lot of you may be using agile or scrum, but you can still incorporate most of the ideas in this book in your work process. Testing, maintainability, requirements, tracking... this book has all you need to turn your cowboy coders into seasoned engineers. Process, process, process.
Team Geek by Brian W. Fitzpatrick and Ben Collins-Sussman
This book written by two Google engineers seems to be written more for team leads, but, again, is useful to any software engineer or manager of software engineers. It's all about the non-technical side of software engineering; the human element. For example, they cover dealing with "poisonous" coworkers, building a strong team, how to have efficient meetings, and how to communicate and collaborate well. This is the only book I didn't have to read for school or work that I'm recommending. I think it's important because even a group of smart, trained software engineers can have interpersonal issues or leadership issues, and this book tries to train people to alleviate those issues.
Saturday, August 2, 2014
Friday, June 27, 2014
Software Engineering: Automated Software Testing 101
My official title at Google is Software Engineer in Test Tools and Infrastructure, which means I spend most of my time writing automated test infrastructure and consulting with teams to help them test their products. For the last couple years that I've been working in this role I've learned a lot about testing. I'd like to disseminate some of this knowledge.
There are many ways to test your software--way too many to cover in one short blog post--, but some of them are more important and widely applicable than others. In this article I'll talk about the major types of automated software testing and why they are important.
Why and When to Test
Firstly, why do we need to test software? Software testing can sometimes seem less important than other tasks. For example, is there any reason to spend expensive engineer-hours writing tests, when you already have design reviews, code reviews, and manual code inspection to assure product quality? Additionally, the fact that bugs can still exist in well-tested code is disheartening.
Despite the drawbacks, testing should be done early and often. Testing your software increases product quality (and in doing so, lowers maintenance costs), aids development speed (testing takes time, but bugs are easier to fix when found earlier), proves requirements have been met, and can reveal design flaws. It's usually worth the time to write at least a few small tests.
This article focuses on automated tests because it's my area of expertise, manual tests are pretty easy to figure out, and because automated tests have several advantages over manual tests: automated tests are generally faster to run, can be run more frequently when part of a continuous build, are easier to use for unit and integration testing, and free up engineers to do other things. If you're writing a small program for yourself, relying solely on manual system tests is fine. For major projects, you'll need automated tests.
What to Test
So by now you've been persuaded by my convincing words that testing should be done early and often. But what are we testing? If we test everything, at what point do we write tests for tests?
Tests should be created for most things, especially complex and critical functionality. If you've created a function that does nothing but add a digit to the end of a string, it's not critical to write a test for that function. Most other stuff should be tested.
While tests themselves can break, tests don't usually need their own tests because of their simplicity and because a false failure will be visible to your team when the test runs. A falsely-passing test can be a disaster, but is an infrequent occurrence for well-written tests that were working to begin with. The exception is to write tests for test infrastructure. Sufficiently complex tests are usually built on some sort of testing infrastructure (JUnit, WebDriver, a fake database, etc.) that can easily contain bugs, and accordingly, they should be tested.
Who Does the Testing?
Who writes tests: software engineers or a QA/test team? The answer is that it depends. For small teams creating small projects, it is sufficient to have engineers test their own code. After all, it can be difficult to obtain a test guy or gal, and there isn't much code to test, so writing tests is quick and easy. But even for large teams creating large projects, it can be beneficial to have the programmers write tests. They can gain insight into their own code, have a better idea of what can break, and are more familiar what the issue is when a test breaks. As someone who writes tests for other teams' projects, I've often encountered teams that have no idea why a test is broken or how to fix it, even though they know the project code better than I do. That issue diminishes when the team has a hand in writing the tests.
Alternatively, a separate test team gains a different perspective of the code. Unlike the programmers that wrote the code, a test person's ego is not affected when a test finds a bug. In fact, finding bugs is ego-boosting for the test team. The drawback is that a test team may not write tests that sufficiently cover the weak points of the dev team's code.
So the answer is: either way is pretty good. Get a test team when writing tests becomes burdensome for the project programmers. This can happen when the software is extremely hard to test for whatever reason, or when it's complex enough to require special test infrastructure.
Test-Driven Development
So tests should be written early. But how early? Some programmers believe in test-driven development, where you write the test before writing the code. I think that's a bit drastic, but not always a bad idea. APIs and features may change slightly when actually writing code, so your tests will likely have to change anyway. You don't necessarily need to write a test before the code is written, but you should have a test plan. Writing tests should be done simultaneously when writing code; that's early enough to catch initial bugs and late enough to prevent overhauling tests.
Now, on to types of tests...
Unit Testing
First and foremost, if you're going to have any automated tests (i.e. you're not writing a small program for yourself), you should have unit tests. The reason is that unit tests are the easy and quick to write and run, unlike other tests. Unit tests are small tests, usually white-box style, that test a class, a few classes, or another small portion of code. Using mocks or stubs is perfectly fine for unit tests.
Because unit tests are so lightweight and quick to run, they should be run often, preferably as part of a continuous integration process. This allows the unit tests to catch newly introduced bugs quickly. Several solutions for continuous integration exist, like Jenkins. (I have not used Jenkins myself).
Integration Testing
The downside of unit testing is that important parts like databases or dependencies on other binaries* are mocked out or nonexistent. You don't get a good picture of how the software performs under real conditions. In order to verify the different subsystems of a program, you should write integration tests. Integration tests are large tests that test multiple binaries, or one binary that uses external resources. Integration tests are helpful in catching integration errors (often API or design bugs). Even if two pieces of a project are "bug-free," they may not integrate well, resulting in miscommunication that can only be caught by integration tests. Integration tests can also find speed or memory issues that can't be found by simple unit tests.
Since integration tests are large and slow, it can be difficult to find a test framework that will bring up all the resources (a.k.a the environment) needed for the test and then tear them down after the test is done. One workaround is to leave up servers or other external resources indefinitely and have the tests clean up any permanent effects in the environment after the tests finish. This is a dangerous game, as the long-running environment can get into a bad state, giving inaccurate test results. Sometimes the only way to run integration tests is to manually bring up and down the environment. In this case, it might be worth it to manually run the integration tests as well.
System Testing
To get a complete picture of how the software will actually perform, system tests are required. System tests are large tests, black-box style, that bringing up an actual environment and simulating an end-user using your product. Not only do they help reveal memory and speed issues that may only occur in a real-world environment, they also may reveal UI and usability issues.
System tests are often run manually since it's hard to find good frameworks that can both setup a large environment and give human-like input (often by manipulating a GUI). However, many GUI-manipulating tools exist. I've used AutoIt to manipulate Windows GUIs with excellent results and I've also used WebDriver to manipulate webpages with very good results. Combined with integration-test-style frameworks, you can potentially automate your system tests.
In summation:
Following these suggestions will help you get excellent code coverage and excellent feature coverage, which will result in stable, easy-to-maintain, and on-schedule software.
Update: Added What and Who testing sections.
*Binaries are individually-compiled programs. They may not do much alone, but work in conjunction with other programs to create useful output. If they do useful work by themselves, they are standalone binaries, or executables.
There are many ways to test your software--way too many to cover in one short blog post--, but some of them are more important and widely applicable than others. In this article I'll talk about the major types of automated software testing and why they are important.
Why and When to Test
Firstly, why do we need to test software? Software testing can sometimes seem less important than other tasks. For example, is there any reason to spend expensive engineer-hours writing tests, when you already have design reviews, code reviews, and manual code inspection to assure product quality? Additionally, the fact that bugs can still exist in well-tested code is disheartening.
Despite the drawbacks, testing should be done early and often. Testing your software increases product quality (and in doing so, lowers maintenance costs), aids development speed (testing takes time, but bugs are easier to fix when found earlier), proves requirements have been met, and can reveal design flaws. It's usually worth the time to write at least a few small tests.
"The problem with quick and dirty, as some people have said, is that dirty remains long after quick has been forgotten."(By the way, the Software Project Survival Guide is a pretty good book for those in the software field. I recommend it for engineers and especially for project managers).
— Steve McConnell, Software Project Survival Guide
This article focuses on automated tests because it's my area of expertise, manual tests are pretty easy to figure out, and because automated tests have several advantages over manual tests: automated tests are generally faster to run, can be run more frequently when part of a continuous build, are easier to use for unit and integration testing, and free up engineers to do other things. If you're writing a small program for yourself, relying solely on manual system tests is fine. For major projects, you'll need automated tests.
What to Test
So by now you've been persuaded by my convincing words that testing should be done early and often. But what are we testing? If we test everything, at what point do we write tests for tests?
Tests should be created for most things, especially complex and critical functionality. If you've created a function that does nothing but add a digit to the end of a string, it's not critical to write a test for that function. Most other stuff should be tested.
While tests themselves can break, tests don't usually need their own tests because of their simplicity and because a false failure will be visible to your team when the test runs. A falsely-passing test can be a disaster, but is an infrequent occurrence for well-written tests that were working to begin with. The exception is to write tests for test infrastructure. Sufficiently complex tests are usually built on some sort of testing infrastructure (JUnit, WebDriver, a fake database, etc.) that can easily contain bugs, and accordingly, they should be tested.
Who Does the Testing?
Who writes tests: software engineers or a QA/test team? The answer is that it depends. For small teams creating small projects, it is sufficient to have engineers test their own code. After all, it can be difficult to obtain a test guy or gal, and there isn't much code to test, so writing tests is quick and easy. But even for large teams creating large projects, it can be beneficial to have the programmers write tests. They can gain insight into their own code, have a better idea of what can break, and are more familiar what the issue is when a test breaks. As someone who writes tests for other teams' projects, I've often encountered teams that have no idea why a test is broken or how to fix it, even though they know the project code better than I do. That issue diminishes when the team has a hand in writing the tests.
Alternatively, a separate test team gains a different perspective of the code. Unlike the programmers that wrote the code, a test person's ego is not affected when a test finds a bug. In fact, finding bugs is ego-boosting for the test team. The drawback is that a test team may not write tests that sufficiently cover the weak points of the dev team's code.
So the answer is: either way is pretty good. Get a test team when writing tests becomes burdensome for the project programmers. This can happen when the software is extremely hard to test for whatever reason, or when it's complex enough to require special test infrastructure.
Test-Driven Development
So tests should be written early. But how early? Some programmers believe in test-driven development, where you write the test before writing the code. I think that's a bit drastic, but not always a bad idea. APIs and features may change slightly when actually writing code, so your tests will likely have to change anyway. You don't necessarily need to write a test before the code is written, but you should have a test plan. Writing tests should be done simultaneously when writing code; that's early enough to catch initial bugs and late enough to prevent overhauling tests.
Now, on to types of tests...
Unit Testing
First and foremost, if you're going to have any automated tests (i.e. you're not writing a small program for yourself), you should have unit tests. The reason is that unit tests are the easy and quick to write and run, unlike other tests. Unit tests are small tests, usually white-box style, that test a class, a few classes, or another small portion of code. Using mocks or stubs is perfectly fine for unit tests.
Because unit tests are so lightweight and quick to run, they should be run often, preferably as part of a continuous integration process. This allows the unit tests to catch newly introduced bugs quickly. Several solutions for continuous integration exist, like Jenkins. (I have not used Jenkins myself).
Integration Testing
The downside of unit testing is that important parts like databases or dependencies on other binaries* are mocked out or nonexistent. You don't get a good picture of how the software performs under real conditions. In order to verify the different subsystems of a program, you should write integration tests. Integration tests are large tests that test multiple binaries, or one binary that uses external resources. Integration tests are helpful in catching integration errors (often API or design bugs). Even if two pieces of a project are "bug-free," they may not integrate well, resulting in miscommunication that can only be caught by integration tests. Integration tests can also find speed or memory issues that can't be found by simple unit tests.
Since integration tests are large and slow, it can be difficult to find a test framework that will bring up all the resources (a.k.a the environment) needed for the test and then tear them down after the test is done. One workaround is to leave up servers or other external resources indefinitely and have the tests clean up any permanent effects in the environment after the tests finish. This is a dangerous game, as the long-running environment can get into a bad state, giving inaccurate test results. Sometimes the only way to run integration tests is to manually bring up and down the environment. In this case, it might be worth it to manually run the integration tests as well.
System Testing
To get a complete picture of how the software will actually perform, system tests are required. System tests are large tests, black-box style, that bringing up an actual environment and simulating an end-user using your product. Not only do they help reveal memory and speed issues that may only occur in a real-world environment, they also may reveal UI and usability issues.
System tests are often run manually since it's hard to find good frameworks that can both setup a large environment and give human-like input (often by manipulating a GUI). However, many GUI-manipulating tools exist. I've used AutoIt to manipulate Windows GUIs with excellent results and I've also used WebDriver to manipulate webpages with very good results. Combined with integration-test-style frameworks, you can potentially automate your system tests.
In summation:
- Write tests early and often
- Run unit, integration and system tests, automating them if you can
- Run automated tests as part of a continuous integration process if you can
Following these suggestions will help you get excellent code coverage and excellent feature coverage, which will result in stable, easy-to-maintain, and on-schedule software.
Update: Added What and Who testing sections.
*Binaries are individually-compiled programs. They may not do much alone, but work in conjunction with other programs to create useful output. If they do useful work by themselves, they are standalone binaries, or executables.
Tuesday, May 20, 2014
Policy: Open Letter to the FCC
The FCC has established an email address (openinternet@fcc.gov) for public comments on their Open Internet proposal. I sent the letter below. All comments become official FCC proceeding documents, so they are publicly available via the web.
FCC Commissioners,
My name is Omari Christian and I'm a software engineer. I have read and written a lot about net neutrality and I am very concerned about Tom Wheeler's new proposed rules for broadband. Particularly troublesome is giving Internet service providers (ISPs) leeway to charge content providers in a manner that is "commercially reasonable." There is no amount of money that is commercially reasonable. Once an ISP is allowed to charge providers for faster or better access to users, ISPs will become the arbiters of which businesses succeed on the Internet and which businesses will fail. The business that will succeed will, of course, be partners of said ISPs and also a few large corporations that can afford the new ISP tolls. This cannot happen. This will break the way the Internet has always worked. It will hinder the free market spirit of the Internet. It will diminish free speech by hindering one of the most popular methods of communication.
Net neutrality is good for free speech and good for the US economy. It helps small businesses. And allowing ISPs to charge content providers for access to Internet consumers is not net neutrality.
There are several things that the FCC can do to make sure the Internet stays open. First and foremost, the FCC must classify broadband Internet as a telecommunications service (i.e. a common carrier). This will give the FCC power to regulate ISPs like other common carriers. Secondly, the FCC should make sure wording includes mobile carriers. Mobile users are becoming a larger part of total Internet users every day and they may one day become the majority, if they haven't already. Mobile Internet is part of the Internet. And, thusly, mobile providers (AT&T, Sprint, T-Mobile, and Verizon included) are also Internet service providers.
Lastly, the most effective way to make sure broadband Internet is keep fast and open is to declare it a public utility, like water and electricity. This may be difficult to square with mobile providers, but it can certainly be done with cable and DSL ISPs. Just like electricity and water, broadband Internet is expensive to rollout to neighborhoods and costly to maintain. Most areas only have one or two providers because of this natural monopoly. Fast Internet service has become a necessity in this day and age, becoming one of the most efficient ways to do business, communicate with friends, and disseminate information.
Let's keep the Internet free and open for everyone. Thank you for listening.
Sincerely,
Omari Christian
FCC Commissioners,
My name is Omari Christian and I'm a software engineer. I have read and written a lot about net neutrality and I am very concerned about Tom Wheeler's new proposed rules for broadband. Particularly troublesome is giving Internet service providers (ISPs) leeway to charge content providers in a manner that is "commercially reasonable." There is no amount of money that is commercially reasonable. Once an ISP is allowed to charge providers for faster or better access to users, ISPs will become the arbiters of which businesses succeed on the Internet and which businesses will fail. The business that will succeed will, of course, be partners of said ISPs and also a few large corporations that can afford the new ISP tolls. This cannot happen. This will break the way the Internet has always worked. It will hinder the free market spirit of the Internet. It will diminish free speech by hindering one of the most popular methods of communication.
Net neutrality is good for free speech and good for the US economy. It helps small businesses. And allowing ISPs to charge content providers for access to Internet consumers is not net neutrality.
There are several things that the FCC can do to make sure the Internet stays open. First and foremost, the FCC must classify broadband Internet as a telecommunications service (i.e. a common carrier). This will give the FCC power to regulate ISPs like other common carriers. Secondly, the FCC should make sure wording includes mobile carriers. Mobile users are becoming a larger part of total Internet users every day and they may one day become the majority, if they haven't already. Mobile Internet is part of the Internet. And, thusly, mobile providers (AT&T, Sprint, T-Mobile, and Verizon included) are also Internet service providers.
Lastly, the most effective way to make sure broadband Internet is keep fast and open is to declare it a public utility, like water and electricity. This may be difficult to square with mobile providers, but it can certainly be done with cable and DSL ISPs. Just like electricity and water, broadband Internet is expensive to rollout to neighborhoods and costly to maintain. Most areas only have one or two providers because of this natural monopoly. Fast Internet service has become a necessity in this day and age, becoming one of the most efficient ways to do business, communicate with friends, and disseminate information.
Let's keep the Internet free and open for everyone. Thank you for listening.
Sincerely,
Omari Christian
Friday, May 9, 2014
Tech Support: Step-By-Step Procedure for Removing Viruses and Other Malware
So, you've got a virus. Or maybe you don't. All you know is you have a Windows PC and the damned thing isn't working like it should. I’ve had this issue countless times, and approximately twice I ended up having actual malware. There’s a few ways to proceed in a situation like this.
You can call tech support for help, but that costs money and takes time. Or you can download and install Trend Micro HijackThis, run it, and post the log on some computer tech support forum. That seems to work for a lot of people, but requires finding the right forum and waiting for kind computer geeks to solve your problem.
Finally, you can try to get rid of the malware yourself using a good malware removal tool. In this article, I’ll describe this option, taking you through my usual process of diagnosing and removing a computer malware from a computer.
"Malware" is any malicious software, including worms, trojans, and viruses. "Anti-virus" is used to refer to any software that can get rid of malware. For a complete dictionary of malware types, check out Viruses, Spyware, and Malware: What's the Difference?
Diagnosing How Bad It Is
First, turn on the computer. If the computer won't turn on--like nothing shows up on the monitor--then you're kinda hosed. It probably wasn't malware. Malware that can damage hardware or wreck your firmware (i.e. your motherboard BIOS) is rare. It's likely that your hardware is broken for other reasons, like being super old or you dropping your computer down a flight of stairs. Seek help elsewhere.
If the computer turns on, but won’t boot into Windows. Several things could be wrong. It could be your hardware, or perhaps malware just corrupted your Windows installation. In any case, that’s more advanced than what we’ll try to solve here.
If the computer turns on and boots into Windows, but you have weird problems there--popups asking you to buy something to “fix” your computer, your browser has been changed to a spammy homepage, your anti-virus won’t run, etc.--then you might have typical malware.
Removing the Malware Manually
When you start up your computer, even before you open your web browser, do you get popups telling you how to fix your computer or speed up your computer? Did you install the program that’s telling you this?
If you have some unknown program that’s telling you that it can fix your computer, you have malware. This is the most common malware I’ve seen in the last few years. One example I recently uninstalled from a friend’s computer was a piece of malware called PC Fix Speed.
PC Fix Speed and similar fake anti-virus programs want you to be concerned about fake issues with your computer so that you’ll pay them for the full version of their software or for customer support. This type of malware is called "scareware" because the intent is to scare you into paying for their services. God knows what happens after you pay them (is the “fix” a program that uninstalls their own malware?).
Getting the Fix
Download Malwarebytes Anti-Malware. This program’s preventive anti-virus capabilities may be mediocre, but its ability to find and remove existing malware is unparalleled. In the several years I've been using it, I've found no better product for removing existing malware on a computer.
If downloading the software using Internet Explorer doesn’t work, try a different browser. Once I had to deal with malware that had hijacked Internet Explorer, making visiting any website impossible. Firefox and Chrome are a bit more secure.
If you still can’t download Malwarebytes Anti-Malware for whatever reason, you’re going to have to use a different computer to download it. Transfer the installation file (usually named mbam-setup.exe or something similar) to a USB flash drive or external hard drive and then use that to transfer it to your malware-ridden computer.
Closing the Gates
Once I no longer need the Internet, I unplug network cables from my computer and turn off the computer’s wifi, if it has wifi, in case the malicious program is spyware. Spyware can upload files from your computer so that hackers can obtain your passwords, credit card numbers and other personal data that can be used for nefarious deeds. Turning off your Internet prevents this.
Installation
Install Malwarebytes Anti-Malware. If you’re really unlucky, the malware has hijacked your registry and taken control of executable files. Installation will not work, and instead a different program will open, or the installation file won’t open at all. This happened to me once. I couldn’t open any programs at all except for the malware.
Getting Control of Your Executable Files (If Needed)

8. Browse to and then click on the following registry key: HKEY_CLASSES_ROOT\exefile
9. With exefile selected, right-click (Default) and click Modify…
10. Change the Value data to "%1" %*
(That's quotation marks, percent sign, one, quotation marks, space, percent, asterisk.)
11. Browse to and then click on the following registry key: KEY_CLASSES_ROOT\exefile\shell\open
12. With open selected, right-click (Default) and click Modify…
13. Change the Value data to "%1" %*
14. Close the Registry Editor and restart your PC.
Directions edited from Microsoft Support.
Running Anti-Malware
Once Malwarebytes Anti-Malware is installed, run it by clicking Scan Now in the bottom-right corner. Scanning takes a while. Select and remove all malware that Anti-Malware finds.
Install an Anti-Virus
Now your malware is (hopefully) gone. If you don't have a anti-virus program already, install one to prevent this from occurring again. I use Microsoft Security Essentials, but I've used Avast and AVG in the past. If you don't mind paying some money, McAfee and Norton make anti-virus programs that are probably better than the free options I listed.
Good luck!
You can call tech support for help, but that costs money and takes time. Or you can download and install Trend Micro HijackThis, run it, and post the log on some computer tech support forum. That seems to work for a lot of people, but requires finding the right forum and waiting for kind computer geeks to solve your problem.
Finally, you can try to get rid of the malware yourself using a good malware removal tool. In this article, I’ll describe this option, taking you through my usual process of diagnosing and removing a computer malware from a computer.
"Malware" is any malicious software, including worms, trojans, and viruses. "Anti-virus" is used to refer to any software that can get rid of malware. For a complete dictionary of malware types, check out Viruses, Spyware, and Malware: What's the Difference?
Diagnosing How Bad It Is
First, turn on the computer. If the computer won't turn on--like nothing shows up on the monitor--then you're kinda hosed. It probably wasn't malware. Malware that can damage hardware or wreck your firmware (i.e. your motherboard BIOS) is rare. It's likely that your hardware is broken for other reasons, like being super old or you dropping your computer down a flight of stairs. Seek help elsewhere.
If the computer turns on, but won’t boot into Windows. Several things could be wrong. It could be your hardware, or perhaps malware just corrupted your Windows installation. In any case, that’s more advanced than what we’ll try to solve here.
If the computer turns on and boots into Windows, but you have weird problems there--popups asking you to buy something to “fix” your computer, your browser has been changed to a spammy homepage, your anti-virus won’t run, etc.--then you might have typical malware.
Removing the Malware Manually
When you start up your computer, even before you open your web browser, do you get popups telling you how to fix your computer or speed up your computer? Did you install the program that’s telling you this?
If you have some unknown program that’s telling you that it can fix your computer, you have malware. This is the most common malware I’ve seen in the last few years. One example I recently uninstalled from a friend’s computer was a piece of malware called PC Fix Speed.
| image from malwaretips.com |
PC Fix Speed and similar fake anti-virus programs want you to be concerned about fake issues with your computer so that you’ll pay them for the full version of their software or for customer support. This type of malware is called "scareware" because the intent is to scare you into paying for their services. God knows what happens after you pay them (is the “fix” a program that uninstalls their own malware?).
Getting the Fix
Download Malwarebytes Anti-Malware. This program’s preventive anti-virus capabilities may be mediocre, but its ability to find and remove existing malware is unparalleled. In the several years I've been using it, I've found no better product for removing existing malware on a computer.
If downloading the software using Internet Explorer doesn’t work, try a different browser. Once I had to deal with malware that had hijacked Internet Explorer, making visiting any website impossible. Firefox and Chrome are a bit more secure.
If you still can’t download Malwarebytes Anti-Malware for whatever reason, you’re going to have to use a different computer to download it. Transfer the installation file (usually named mbam-setup.exe or something similar) to a USB flash drive or external hard drive and then use that to transfer it to your malware-ridden computer.
Closing the Gates
Once I no longer need the Internet, I unplug network cables from my computer and turn off the computer’s wifi, if it has wifi, in case the malicious program is spyware. Spyware can upload files from your computer so that hackers can obtain your passwords, credit card numbers and other personal data that can be used for nefarious deeds. Turning off your Internet prevents this.
Installation
Install Malwarebytes Anti-Malware. If you’re really unlucky, the malware has hijacked your registry and taken control of executable files. Installation will not work, and instead a different program will open, or the installation file won’t open at all. This happened to me once. I couldn’t open any programs at all except for the malware.
Getting Control of Your Executable Files (If Needed)
1. Boot into Safe Mode (Directions) and log in to your account or the Administrator account.
2. Click the Start button and type regedit in the Search box.
3. Right-click Regedit.exe in the returned list and click Run as administrator.
4. If a popup asks you if you want the program to be able to make changes to your computer, click Yes.
5. Browse to the following registry key: HKEY_CLASSES_ROOT\.exe
6. With .exe selected, right-click (Default) and click Modify…
7. Change the Value data to exefile.
2. Click the Start button and type regedit in the Search box.
3. Right-click Regedit.exe in the returned list and click Run as administrator.
4. If a popup asks you if you want the program to be able to make changes to your computer, click Yes.
5. Browse to the following registry key: HKEY_CLASSES_ROOT\.exe
6. With .exe selected, right-click (Default) and click Modify…
7. Change the Value data to exefile.
8. Browse to and then click on the following registry key: HKEY_CLASSES_ROOT\exefile
9. With exefile selected, right-click (Default) and click Modify…
10. Change the Value data to "%1" %*
(That's quotation marks, percent sign, one, quotation marks, space, percent, asterisk.)
11. Browse to and then click on the following registry key: KEY_CLASSES_ROOT\exefile\shell\open
12. With open selected, right-click (Default) and click Modify…
13. Change the Value data to "%1" %*
14. Close the Registry Editor and restart your PC.
Directions edited from Microsoft Support.
Running Anti-Malware
![]() |
| Malwarebytes Anti-Malware |
Install an Anti-Virus
Now your malware is (hopefully) gone. If you don't have a anti-virus program already, install one to prevent this from occurring again. I use Microsoft Security Essentials, but I've used Avast and AVG in the past. If you don't mind paying some money, McAfee and Norton make anti-virus programs that are probably better than the free options I listed.
Good luck!
Saturday, April 26, 2014
Policy: How the FCC is Killing the Internet and How to Stop It
For a better understanding of net neutrality see my article Net Neutrality 102.
On April 23, the Federal Communications Commission (FCC) said "that it would propose new rules that allow companies like Disney, Google or Netflix to pay Internet service providers (ISPs) like Comcast and Verizon for special, faster lanes to send video and other content to their customers." (NY Times) Many people, including myself, see this as blatant violation of net neutrality principles. For example, former FCC commissioner Michael Copps, Sen. Al Franken, and Sen. Cory Booker are concerned about the proposed rules. Senator Bernie Sanders said, "Under this terribly misguided proposal, the Internet as we have come to know it would cease to exist and the average American would be the big loser."
FCC Chairman Tom Wheeler denies that the proposed rules would gut net neutrality. But as Sean Hollister of The Verge says:
A Quick History of Net Neutrality in the US
Since the beginning of the Internet, ISPs have been net neutral. Data was data, ISPs didn't discriminate against different types of traffic, and any small personal website could be accessed as quickly as a large corporation's website. However, more recently ISPs have occasionally blocked or throttled different websites and types of traffic for various reasons. The recent deal between Netflix and Comcast, was definitely a money grab by Comcast that was arguably non-net neutral.
The FCC, which regulates things like TV and radio, occasionally punished ISPs that violated net neutrality by fining them. However, in January a federal appeals court stated that the FCC technically didn't have the authority to regulate ISPs. The FCC classifies broadband Internet as an "information service," which limits the FCC's power to regulate broadband ISPs. Instead of reclassifying broadband Internet as a "telecommunications service"--which would give the FCC more power to regulate them--or appealing the court's decision, Wheeler has decided to rewrite its net neutrality rules.
It now appears that the new rules are not net neutral, throwing the Internet into jeopardy for all Americans.
What Could Happen
I, along with others, have always suspected that if and when ISPs try to kill net neutrality, it would be by charging users for access or for speedy access to certain types of Internet content. For example, Time Warner Cable might charge Internet subscribers an extra $3 per month to access netflix.com.
That isn't how it's happening. Instead, ISPs are charging the websites for access to subscribers. First, AT&T announces "Sponsored Data", which sounds nice but is just a way to block certain websites once a subscriber's data cap is reached. As Nilay Patel from The Verge says, "that's not fair competition, that's just pay to play." Next, Comcast throttles Netflix data unless Netflix agrees to pay up. Now, the FCC announces new rules that imply that this is just the beginning.
In the future, ISPs may charge all websites a fee for access to their users, possibly in speed tiers. Websites and services that don't pay up will be unreachable by users. This may sound like perfectly fine, net-neutral behavior to some, like FCC Chair Wheeler, because users cannot pay a fee to get access to these websites. However, the result is the same: small websites for small businesses, small organizations and non-wealthy individuals will have less of a chance of being seen than large websites run by corporations that can afford these new Internet tolls.
(This is also a reason to oppose the Comcast-Time Warner Cable merger. While the two companies do not compete for ISP customers because they are in different markets, they will compete for content provider customers. For example, if Netflix opted not to pay Comcast a fee for normal streaming speeds, they'd only be throttled for half of the country's broadband users. After the merger they'd be throttled for the whole country. Comcast will control most American's access to fast Internet and can charge content providers whatever they want.)
Why Is the FCC Trying to Kill Net Neutrality?
Why is this happening? It's hard to say for sure. Obama promised net neutrality laws. Then he strangely nominated Tom Wheeler for FCC Chair. Wheeler, who lobbied to deregulate the cable industry in the 80's, and lobbied for the wireless industry later. He supported the T-Mobile and AT&T merger that thankfully failed. But, when appointed, Wheeler said, "we're pro-open networks," giving hope to net neutrality supporters everywhere. It appears that hope was misplaced.
Obama's nomination of Wheeler doesn't make much sense, but Wheeler's support for deregulation and supporting huge, oligopolistic corporations--especially the wireless telecoms--is well-established. Wheeler is just supporting his friends and ex-coworkers.
What Can We Do?
We can still save the Internet. Contact your representative, your senators, and FCC Chair Tom Wheeler (tom.wheeler@fcc.gov) and tell them to oppose any new FCC rules that aren't net neutral. Tell them to get the FCC to reclassify broadband providers as "telecommunications services" instead of "information services" so that the FCC can continue using net neutral rules already in place. If enough people make their voice heard, we can keep the Internet free and open.
On April 23, the Federal Communications Commission (FCC) said "that it would propose new rules that allow companies like Disney, Google or Netflix to pay Internet service providers (ISPs) like Comcast and Verizon for special, faster lanes to send video and other content to their customers." (NY Times) Many people, including myself, see this as blatant violation of net neutrality principles. For example, former FCC commissioner Michael Copps, Sen. Al Franken, and Sen. Cory Booker are concerned about the proposed rules. Senator Bernie Sanders said, "Under this terribly misguided proposal, the Internet as we have come to know it would cease to exist and the average American would be the big loser."
FCC Chairman Tom Wheeler denies that the proposed rules would gut net neutrality. But as Sean Hollister of The Verge says:
The problem, which Wheeler's statement doesn't refute, is that the FCC intends to say that it's okay to discriminate against traffic if content providers don't pay the ISPs a "commercially reasonable" fee. While the FCC chairman says that "behavior that harms consumers or competition will not be permitted," any fee might risk harming both, even if it's tiny.How did we get here? Why is the FCC proposing new rules anyway? Let's take a step back to explain the situation.
A Quick History of Net Neutrality in the US
Since the beginning of the Internet, ISPs have been net neutral. Data was data, ISPs didn't discriminate against different types of traffic, and any small personal website could be accessed as quickly as a large corporation's website. However, more recently ISPs have occasionally blocked or throttled different websites and types of traffic for various reasons. The recent deal between Netflix and Comcast, was definitely a money grab by Comcast that was arguably non-net neutral.
The FCC, which regulates things like TV and radio, occasionally punished ISPs that violated net neutrality by fining them. However, in January a federal appeals court stated that the FCC technically didn't have the authority to regulate ISPs. The FCC classifies broadband Internet as an "information service," which limits the FCC's power to regulate broadband ISPs. Instead of reclassifying broadband Internet as a "telecommunications service"--which would give the FCC more power to regulate them--or appealing the court's decision, Wheeler has decided to rewrite its net neutrality rules.
It now appears that the new rules are not net neutral, throwing the Internet into jeopardy for all Americans.
What Could Happen
I, along with others, have always suspected that if and when ISPs try to kill net neutrality, it would be by charging users for access or for speedy access to certain types of Internet content. For example, Time Warner Cable might charge Internet subscribers an extra $3 per month to access netflix.com.
That isn't how it's happening. Instead, ISPs are charging the websites for access to subscribers. First, AT&T announces "Sponsored Data", which sounds nice but is just a way to block certain websites once a subscriber's data cap is reached. As Nilay Patel from The Verge says, "that's not fair competition, that's just pay to play." Next, Comcast throttles Netflix data unless Netflix agrees to pay up. Now, the FCC announces new rules that imply that this is just the beginning.
In the future, ISPs may charge all websites a fee for access to their users, possibly in speed tiers. Websites and services that don't pay up will be unreachable by users. This may sound like perfectly fine, net-neutral behavior to some, like FCC Chair Wheeler, because users cannot pay a fee to get access to these websites. However, the result is the same: small websites for small businesses, small organizations and non-wealthy individuals will have less of a chance of being seen than large websites run by corporations that can afford these new Internet tolls.
(This is also a reason to oppose the Comcast-Time Warner Cable merger. While the two companies do not compete for ISP customers because they are in different markets, they will compete for content provider customers. For example, if Netflix opted not to pay Comcast a fee for normal streaming speeds, they'd only be throttled for half of the country's broadband users. After the merger they'd be throttled for the whole country. Comcast will control most American's access to fast Internet and can charge content providers whatever they want.)
Why Is the FCC Trying to Kill Net Neutrality?
Why is this happening? It's hard to say for sure. Obama promised net neutrality laws. Then he strangely nominated Tom Wheeler for FCC Chair. Wheeler, who lobbied to deregulate the cable industry in the 80's, and lobbied for the wireless industry later. He supported the T-Mobile and AT&T merger that thankfully failed. But, when appointed, Wheeler said, "we're pro-open networks," giving hope to net neutrality supporters everywhere. It appears that hope was misplaced.
Obama's nomination of Wheeler doesn't make much sense, but Wheeler's support for deregulation and supporting huge, oligopolistic corporations--especially the wireless telecoms--is well-established. Wheeler is just supporting his friends and ex-coworkers.
What Can We Do?
We can still save the Internet. Contact your representative, your senators, and FCC Chair Tom Wheeler (tom.wheeler@fcc.gov) and tell them to oppose any new FCC rules that aren't net neutral. Tell them to get the FCC to reclassify broadband providers as "telecommunications services" instead of "information services" so that the FCC can continue using net neutral rules already in place. If enough people make their voice heard, we can keep the Internet free and open.
Saturday, March 22, 2014
Code: Why Google Guice is Evil
Google Guice (pronounced like "juice") is a dependency injection framework for Java. We use it quite often at work. It’s awful. I think the evils of Guice can best be explained by relating a true story as a second person narrative:
If that story didn’t do anything for you, let me explain it in more explicit terms. Guice is awful, not just because it turns your improper type casts from compile-time errors to runtime errors, but also because it can turn your code into spaghetti code, where searching for a simple injected variable becomes a quest to find a single needle in a silver haystack.
Disclaimer: Obviously, a code framework cannot be “evil.” And Guice may not always be necessarily bad. When used properly, I'm sure you can achieve Guice’s benefits while still writing maintainable, easy-to-read code. I’m just not quite sure what those benefits are. I've certainly never seen any code where it made things easier to read or to write.
An example of the futility of Guice can be found on the Motivation page of the Guice User’s Guide [link updated; the new Motivation page doesn't have a comments section]. The Motivation page describes a situation where Guice is used to make swapping test components and real components easier in a billing service. That page ends with the following example of Guice injection:
In the comments section, one person asks a good question:
In this case, BillingModuleInterface is an interface for a module that may contain real or mocked-out billing components. It’s easy to read because it’s using good old fashioned typical Java. It’s easy to write because any missed dependencies or casting errors will be found at compile time. It’s easy to add a new module because you can simply create a new class that extends BillingModuleInterface.
In conclusion, the Guice framework is a poor choice for most, if not all, projects. It’s especially bad for large projects in large codebases where finding an injected dependency may be a Sisyphean ordeal.
You have a huge project in a huge codebase and your team is using Guice. You notice an instance variable of some type (say, InitHelper) in some class, and the variable is injected into the constructor. You want to find out where that variable is initialized so you can tell what it's settings are. Sure, you can port the whole project into your IDE, compile it and run it with some fake arguments for the backends (or take an hour to initialize the real backends), pause the debugger and see what what the settings were for the that variable, but that would take a long time and you feel that you shouldn't have to run and debug code just to see what it is doing.
Luckily, you work for a top tier company with a searchable code repository. You look for all instances where the class constructor is called.
Nowhere. The constructor is called nowhere (except the tests) because your team is using Guice. No matter. You just need to look in the module. Your team had the foresight to place the module that binds the class in the same directory as the class. "The day is mine!" you exclaim, perhaps a bit prematurely.
Huh. It's not bound in the module. That's unfortunate, but just one of the side effects of being Guicy: sometimes your teammates inject variables from different directories. No biggie, just see who's using your module. Surely there's an @Inject or @Provides that will initialize your variable in another module that includes your module.
Everyone. There must be 100 classes using that module. Is that Fortran code from 1970s that uses the module? Okay, you're going about this the wrong way. You know where the main class of your binary is. Look at the main class and work from there. Is the variable bound there?
No, it's not. Because that would be easy. If it were easy, everyone would do it. And we can't have that. Instead, the main class must include a module that binds the variable you're looking for. Just look through the module(s) included in the main class. How many could there possibly be?
All of them. All of the modules ever written since time immemorial are included in the getModules() method of the main class. Well, adversity builds character. What a great person you're going to be by the end of this! Time to get super serious and just search the repository for "bind(InitHelper.class)".
You found it! The class is bound in a module... in some other team's code you've never seen before. And as far as you can tell, your team doesn't use it. You could grab your best hunting dog and follow the trail to see if something that uses this module is used in your code, or you save a lot of time not following what is probably a dead end. You go with the latter.
Look, you're smarter than this. And can do multiline searches in your repository. If it's not bound manually with a call to bind() then it's provided with a provider, right? Just search for "@Provides" followed by an optional "@Singleton" followed by a newline followed by a variable amount of space followed by the variable's class name. By the power of regex!
Quite a few modules. Let's narrow that search to your team's directory.
Nothing. That's fine, you didn't really want to find it anyway.
If that story didn’t do anything for you, let me explain it in more explicit terms. Guice is awful, not just because it turns your improper type casts from compile-time errors to runtime errors, but also because it can turn your code into spaghetti code, where searching for a simple injected variable becomes a quest to find a single needle in a silver haystack.
Disclaimer: Obviously, a code framework cannot be “evil.” And Guice may not always be necessarily bad. When used properly, I'm sure you can achieve Guice’s benefits while still writing maintainable, easy-to-read code. I’m just not quite sure what those benefits are. I've certainly never seen any code where it made things easier to read or to write.
An example of the futility of Guice can be found on the Motivation page of the Guice User’s Guide [link updated; the new Motivation page doesn't have a comments section]. The Motivation page describes a situation where Guice is used to make swapping test components and real components easier in a billing service. That page ends with the following example of Guice injection:
Injector injector = Guice.createInjector(new BillingModule());
BillingService billingService = injector.getInstance(BillingService.class);
BillingService billingService = injector.getInstance(BillingService.class);
In the comments section, one person asks a good question:
As a cynic of [dependency] injection frameworks, can someone tell me what the advantage is ofHe (or she) has a point. And in my opinion, his question is never answered satisfactorily. Why depend on annotations and reflection (the GOTOs of the Java language) when you can use the perfectly legitimate new operator? In his example, BillingService gets all its instance variables from the module argument. The constructor for BillingService would look something like this:
Injector injector = Guice.createInjector(new BillingModule());
BillingService billingService = injector.getInstance(BillingService.class);
over
BillingService billingService = new BillingService(new BillingModule());
please?
public RealBillingService(BillingModuleInterface realOrFakeBillingModule) {
this.processor = realOrFakeBillingModule.getProcessor();
this.transactionLog = realOrFakeBillingModule.getTransactionLog();
}
this.processor = realOrFakeBillingModule.getProcessor();
this.transactionLog = realOrFakeBillingModule.getTransactionLog();
}
In this case, BillingModuleInterface is an interface for a module that may contain real or mocked-out billing components. It’s easy to read because it’s using good old fashioned typical Java. It’s easy to write because any missed dependencies or casting errors will be found at compile time. It’s easy to add a new module because you can simply create a new class that extends BillingModuleInterface.
In conclusion, the Guice framework is a poor choice for most, if not all, projects. It’s especially bad for large projects in large codebases where finding an injected dependency may be a Sisyphean ordeal.
Friday, January 3, 2014
Code: Detecting Mobile Users
A while back, I wrote about how to make a mobile-optimized website. One tip I omitted was the best way to determine what type of user is visiting your site: desktop, mobile or tablet. The article simply checked the user agent string for "iPod" or "iPhone".
Checking for all kinds of mobile devices (Android and Windows Phone included) and checking for tablets is important. As a new tablet owner (Nexus 10) I am disappointed by the number of sites that insist on sending me to a version of their site that was meant for tiny screens. Undoubtedly, they are seeing "Android" in my user agent string and thinking I'm using a phone.
The desktop version isn't always right for tablets either. Most tablets don't have Flash, so any website with Flash animations should replace those animations with videos, moving gifs, or static images on the tablet version of the site. Additionally, there are ways to make your website optimized for a touchscreen, even if that screen is 7 inches or larger. This is why tablets may deserve their own website version. But in case you don't want or need a tablet version of your website, this article covers the two ways to split up your site.
Mobile (Phone) vs Non-Mobile (Desktop and Tablet)
After much research on the user agent strings of different devices, I discovered there's an easier way to determine whether you're using mobile or not. You're supposed to detect features, not check the user agent string to determine what device is being used.
Even though phones, iPods and other small screen devices have very high resolutions, they are still reporting their heights or widths as less than 480 pixels, depending on the orientation of the device. StackOverflow suggests adding a meta tag and adding a timeout, but the simple code above should do the trick.
Phone vs Tablet vs Desktop
If the device is not mobile/small-screened, then check for the ontouchstart property in the documentElement. Both mobile devices and tablets will have this property that signifies the availability of a touchscreen.
Exceptions
Some devices are in a grey area in terms of size and functionality. The Samsung Galaxy Note is huge, but still declares itself a "mobile" device. The iPad Mini is 1.8" smaller than the iPad, but its viewport size is the exact same as the iPad. This makes it hard to make a phablet version of your website. There's not much that webmasters can do, except to treat devices how they want to be treated.
Checking for all kinds of mobile devices (Android and Windows Phone included) and checking for tablets is important. As a new tablet owner (Nexus 10) I am disappointed by the number of sites that insist on sending me to a version of their site that was meant for tiny screens. Undoubtedly, they are seeing "Android" in my user agent string and thinking I'm using a phone.
The desktop version isn't always right for tablets either. Most tablets don't have Flash, so any website with Flash animations should replace those animations with videos, moving gifs, or static images on the tablet version of the site. Additionally, there are ways to make your website optimized for a touchscreen, even if that screen is 7 inches or larger. This is why tablets may deserve their own website version. But in case you don't want or need a tablet version of your website, this article covers the two ways to split up your site.
Mobile (Phone) vs Non-Mobile (Desktop and Tablet)
After much research on the user agent strings of different devices, I discovered there's an easier way to determine whether you're using mobile or not. You're supposed to detect features, not check the user agent string to determine what device is being used.
var isMobile = (screen.width < 480) || (screen.height < 480);
Even though phones, iPods and other small screen devices have very high resolutions, they are still reporting their heights or widths as less than 480 pixels, depending on the orientation of the device. StackOverflow suggests adding a meta tag and adding a timeout, but the simple code above should do the trick.
Phone vs Tablet vs Desktop
If the device is not mobile/small-screened, then check for the ontouchstart property in the documentElement. Both mobile devices and tablets will have this property that signifies the availability of a touchscreen.
var isMobile = (screen.width < 480) || (screen.height < 480);
var isTouchscreenDevice = 'ontouchstart' in document.documentElement;
var isTablet = !isMobile && isTouchscreenDevice;
var isDesktop = !isMobile && !isTablet;
var isTouchscreenDevice = 'ontouchstart' in document.documentElement;
var isTablet = !isMobile && isTouchscreenDevice;
var isDesktop = !isMobile && !isTablet;
Exceptions
Some devices are in a grey area in terms of size and functionality. The Samsung Galaxy Note is huge, but still declares itself a "mobile" device. The iPad Mini is 1.8" smaller than the iPad, but its viewport size is the exact same as the iPad. This makes it hard to make a phablet version of your website. There's not much that webmasters can do, except to treat devices how they want to be treated.
Subscribe to:
Posts (Atom)





