System Quality

A lot of software is being produced today. Yet I personally feel that there are many that do not meet quality standards. Granted, there’s no perfect system and bugs will exist in systems, but how many are really satisfied with the system the wrote? How many admit to themselves that despite being launched, it’s not good at all?

Reading this reminds me of the comparison between completion and success. Systems that get to production are just completed but may be barely usable, or even helpful in the production environment. I’ve seen systems that are so difficult to use and buggy that manual processes have to be employed in tandem with the system. It actually results in double work instead of achieving any efficiency.

In this era where software houses compete to offer the lowest price to build a system; where anyone can pick up a book or read an online tutorial and be able to code; the quality of systems will only hit an all-time low. When that happens software will not be bought because it is cheaper (or even free), but at how stable it is and how well it is able to perform its intended function. This should help promote the necessity for the quality of system, and in turn, the quality of developers.

Mooching

That’s the new geek term for Wi-Fi tapping. It has stirred up some controversy over here as people are caught and charged for tapping into someone else’s unsecured wireless network.

The question: Crime or No Crime?

Supporters for the “Crime” side are focusing on the “someone else” and saying its akin to Stealing or Trespassing. On the other side of the fence are people who stress on the “unsecured”, saying it is harmless (just reduces some bandwidth), Free-For-All, and it is the responsibility of the owner since he has the option and power to secure it.

There are many other side factors, such as the intent of mooching. There are those who want to surf for free, there are those who have automatic connections to the strongest signals. There are also people who mooch to post bomb hoaxes, those who ride on to conceal their identity and actions, or maybe those who wants to compromise other machines in the same Wi-Fi network.

The accusation is more obvious if there is a malicious intent when mooching, but for harmless mooching I’m currently leaning slightly towards no crime. I’ll still be sitting on the fence (and leaning to one side) for now as the reasons or analogies to back either decision isn’t strong enough.

Vista Incompatibility

As the new Microsoft OS comes to market, there have been various reports regarding incompatibilities of the OS with existing hardware and software.

Even the compatibility tool provided by Microsoft cannot assure users that their hardware is capable of running all the features provided by the new OS [1]. Users may end up with a Vista that’s not running the features they wanted. Should there be yet another Vista-compatible logo, something like FULLY Vista-compatible, to mean being able to run all known Vista features?

On the software side there are also many anticipated problems, such as in South Korea [2]. Governments and organisations have warned that Vista may be incompatible with their existing ActiveX programs, which would result in inability to consume their daily services like banking, trading and shopping. Games and software that work with the existing XP have also stated warnings against Vista compatibility.

Adding to the issues are advisories on possible security problems with Vista despite claims it is the most secure Windows OS so far (probably just relatively more secure than their first XP?).

With nothing to work with Vista, who’s going to use it?

[1] Buying Vista? Get a guarantee
[2] Microsoft Vista to Cause Confusion for Korean Net Users

Sending PDF for download

Symptom: When sending a PDF for download to IE, the error message appears:

There was an error opening this document. The file could not be found.

Cache-Control has been set to no-cache. Firefox works fine.

Cause: Unknown, IE specific problem with cache handling.

Solution: Set expiry date to trick browser that content expired. [1]


response.setHeader("Expires", "0");
response.setHeader("Pragma", "cache");
response.setHeader("Cache-Control", "private");

[1] http://drupal.org/node/18179

Sorting Javascript Arrays (of Objects)

There’re many ready Javascripts out there, which already allow you to sort arrays. However, if you come from a OO background like me, it won’t be long before you start using Javascript arrays of custome objects. You can’t really use those simple number or string sorting algorithms available, since they don’t inspect the attributes to sort correctly. You could write a custom sort function for that purpose, then rewrite it again and again for each of the attributes of that object, and again and again for all other objects.

Or you could follow that well known Comparable model from Java. By attaching methods to the custom objects [1] like a Comparable, you can write generic sort algorithms to performing sorting. You can even extend the feature to using a Comparator to influence the object’s natural sort order.

Side note: Javascript does not support method overloading, and it doesn’t report and error that it doesn’t [2]. It simply uses the last method declared. I’ve therefore named the other method sortArray2. Bad method name, but you should name it more appropriately if you decide to use it.

Javascript Object Array Sorting Example

[1] Introduction and Features of Javascript “Function” Objects
[2] JavaScript only pretends to support function overloading

Modern Internet Business Models

As many people (and articles) have identified, online businesses are moving towards newer models to offer free stuff using advertising [1] and service support [2] to sustain.

Advertising usually means the site provides free content, and generates revenue by displaying advertisement alongside their content. The site would need to update content regularly, in order to attract returning visitors. There seems to be also a trend of user-generated content, such as video-sharing, which empowers the site visitors to contribute to the site content.

Service support usually allows users to use their product for free, charging for support when problem arises or signing support contracts with bigger companies. It is noticed that such companies have to work with lower profits, as a result more company operations are streamlined, such as reduced sales staff and marketing. Early adopters to such products also usually help shape future versions of the product.

[1] The Internet’s Biggest Google Whores
[2] Taking the plunge into open source

Read Byte Streams with Java IO

Maybe it’s the search terms I used, I couldn’t find straightforward and simple examples to read binary streams with JavaIO. It’s not I don’t know how to, but I think it’s useful for other developers who know less IO. So, here it is. The first example shows reading a byte at a time, the second shows reading in chunks.


// Example 1
InputStream in = somewhere.getInputStream();

int c;
while ((c = in.read()) != -1) {
	// process read byte
	System.out.print((char)c);
}

The input stream is where you want to read from, such as a new FileInputStream() or socket.getInputStream(). An integer c is declared to hold each byte as it is read. The in.read() method will return an integer in the range 0-255, which is the value of the byte read. Why not use a Java byte? This is because the Java byte is signed and has the range -128 to 127. Java gives you the “benefit” of getting the actual value so you can process it directly.

The while loop line is the most confusing part of the loop. If we resolve the inner bracket first, it reads a byte from the inputstream, and stores it in c. The bracket now resolves to the value of c, which is compared against -1. This comparison is done because read() will return a -1 if the end of stream is reached. This will break the processing loop and allow the program to continue.

If a valid value is read, it goes into the loop, and you can process the integer c. In this example it just prints the read byte. The cast to char is necessary, or else it will print the number code of the byte.


// Example 2
InputStream in = somewhere.getInputStream();
OutputStream out = new ByteArrayOutputStream(); // for example

byte[] buf = new byte[1024];
int len;

while ((len = in.read(buf)) != -1) {
	// process byte buffer
	out.write(buf, 0, len);
}

In this example we also have an inputstream to read from, additionally we prepare an outputstream where we will store the read bytes. You should change it to whatever your purpose was for reading the stream. For this method we’ll need two variables — a byte array buffer (buf) for storing the read bytes and an integer (len) which represent the number of bytes actually read. There’s no fixed number for the buffer size, it’ll work whether you put 10 or 100000 for now. I’ll explain the effect later.

Next we reach the confusing while loop again, this time it’s even more complicated. Let’s resolve the inner bracket again, what happens here is in.read() will modify the byte array to store the content of the read bytes. This means when you execute in.read(buf) by itself, the contents of buf before and after this statement might be different. The number returned will tell you how many bytes were read and stored in that byte array. The inner bracket now resolves to the value of len, which is matched against -1. This is because in.read() will return -1 if the end of the stream is reached, so we can terminate the while loop.

If some bytes were read, we go into the while loop, and write the read bytes to the outputstream. We will need to specify that we want to write the bytes 0 to len, because it may be possible that the inputstream read less than the size of the buffer. This may be due to a network latency, or it could be the last chunk of a file that is not a multiple of the buffer size. If len was not specified, we might be writing rubbish that contains data previously written into the byte array, thus corrupting the data.

Now that you understand the loop (hopefully), I’ll explain the effect of the buffer size. If you have a small buffer, you’ll need to run the loop more times, to read an amount of data. If you have a big buffer, you’ll loop less times for the same amount of data. Then why not assign a VERY BIG buffer? This depends on the amount of memory your application can spare. Allocating a big buffer means the byte buffer will take up that much memory, even if only a small part of it is used. So the decision on the size of the buffer depends on whether you have constraints on processing power or memory size, or even the typical size of data read. You don’t need a 1MB buffer to read 1KB streams.

The 2nd buffer method is more efficient than the one used in Example 1, which reads byte by byte. Therefore it is preferred the 2nd method is used.

WEP, WPA and WPA2

WEP, or Wired Equivalent Privacy, is a wireLESS standard for protecting data transmited over a WLAN network. Since wireless signals run over the air, they may be tapped easily. These data may include your login credentials to websites or application, sensitve emails, etc.

WEP uses a key which the user must enter into the router as well as all participating nodes. The key is then used to allow the user on the network and subsequently encrypt all trafiic using the key. Users will still be able to descrypt and see the data sent by another user on the same network, just as if the user had physical access to the Ethernet wire on the wired version. The problem with WEP is that it is not secure; by intercepting a big number of encrypted packets a cracker is able to crack the key used. There are also other known problems with WEP that cannot be solved with a bigger key.

After discovering this major security problem, WPA (Wi-FI Protected Access) was quickly created to replace WEP. As the 802.11i specifications was complete, WPA2 was introduced to comply with the new standard. WPA allows for two modes of operation, a “Personal” mode, where a Pre-Shared Key (PSK) is used for authentication and encryption, or an “Enterprise” mode where a IEEE 802.11X authentication server is used. [1]

The personal mode works similar to WEP, all users enter the “Network Key” to gain access to the network, then all traffic is protected. This scheme is suitable for home networks and small offices, where there are few machines and seldom changing.

No chance to try the authentication server mode yet…

[1] Wi-Fi Protected Access – Wikipedia, the free encyclopedia