Saturday, May 20, 2017

Java History and Motivation

Before we can start writing Java programs, it is important to understand the history and theory of programming. A computer program is simply a list of instructions that tells the computer how to accomplish a certain task. As an analogy, if our task is to drive from Chicago to New York City, we would break that down into a list of directions (start the car, pull out of the driveway, turn left onto 10th Street, turn right onto highway 90, etc). Although many routes exist from Chicago to New York City, we are only interested in ones that are fast and easy to follow. Similarly, there are many different ways to write a computer program, but the best programmers will write programs that are fast, easy to understand, etc.

All computer programs end up as a sequence of bits (0 or 1). Computers use electricity as the way to transport information. If the voltage on an electrical switch is greater than a certain value (usually 5 volts), then the bit evaluates to a 1. Otherwise, if the voltage is less than 5 volts, then the bit evaluates to 0. The image below shows an early computer, where programs are entered by pressing the red and purple switches at the bottom of the console. Each switch represents a bit with the value 0 (unpressed) or 1 (pressed):



The list of 0s and 1s that a computer is able to run is known as machine language. Although it is still possible to write computer programs using machine language, programs become very difficult to understand if they are more than a few lines long. The solution is to write programs in a human readable language (such as Java) and use a tool called a compiler to transform the program into a sequence of 0s and 1s to be read by the computer. We'll see many examples later on about what a human readable program looks like.

C was the first mainstream programming language that allowed people to write high level programs that got transformed into machine language. It was created by Dennis Ritchie in the 1970s and is still one of the most popular programming languages today, along with Java and a few others. Although C was a major step forward in writing good computer programs, it had several drawbacks. One of the biggest problems was too much complexity for large programs. C is a structured programming language, which is a type of programming language that focuses on the instructions needed to complete a task. For example, if we want to build a house, a list of tasks such as the following could be used:

1. Pick a location where the house can be built.
2. Survey the land and make sure that the house can be built there.
3. Purchase the property where the house will be built.
4. Get the necessary permits, get insurance, create a budget.
5. Create a blueprint detailing what the house will look like.
6. Build the house, including the foundation, walls, roof, electricity, plumbing, flooring, etc.

The are many more tasks than what's listed, and it's very difficult to understand everything on your own. How do I lay a brick foundation? How do I install the roof? How do I wire up the electrical outlets and install plumbing? Writing a program like this using structured programming is going to be difficult to follow. The solution is to just understand the high level details involved and how they fit together. I can hire an electrician to take care of the wiring, and I can hire a plumber to take care of the plumbing. The idea of breaking down a task into high level details is known as object oriented programming. Using this approach, I can focus on the parts of building a house that I need to (let's say creating the blueprint and financing the house) and let other people focus on the details of how the electricity and plumbing will work. We will take a detailed look at object oriented programming in a later post.

C++ (pronounced C plus plus) was the first programming language that popularized the object oriented programming model. It was created in 1979 by Bjarne Stroustrup, and it became popular in the 1980's. Although this was another major step forward in programming languages, there were still some major drawbacks. C++ was written as an extension to the C programming language, which made it easy to fall back on structured programming when writing applications. Many C++ programmers came from a C background, and brought bad habits from C over to C++, even though there were now better ways to do the same thing. Another major problem of C++ was that it wasn't platform independent. This means that once a program is compiled into machine code, it will not run on other computers. A platform is determined by the type of device running the program and the operating system (there are a few other factors, but those are the main ones). So, if I write a program in C++ on my Mac, the machine code will not run on a Windows computer or Android phone. This is a big limitation today, because web development is very popular, and being able to run the same program on different devices without having to make changes is a great productivity boost.

This brings us to Java. Java was created in 1996 by James Gosling to overcome many of the deficiencies in C and C++. The problem of platform independence was solved by compiling the code into an intermediate language, known as bytecode. Bytecode is a list of simple instructions that can be further compiled into machine code and run by the computer. The application that takes bytecode and runs it as machine code is known as the Java Runtime Environment (JRE). Since almost all computers and devices come with the JRE preinstalled, you can share your program's bytecode with someone else using another device, and it will run without any changes. The application that takes a Java program and coverts it into bytecode is known as the Java Development Kit (JDK). The JDK includes the JRE, and allows a programmer to write an application, convert it to bytecode, and run the corresponding machine code all in one go. The diagram below shows how a java program is converted to bytecode and run as machine code:


Don't worry about the difference between bytecode compiler and bytecode interpreter in the diagram. The point is that the bytecode will be transformed into machine code, which is run by the computer. Another benefit of compiling a java program to bytecode is that a large application can be written using many programming languages. As long as a programming language can be compiled to bytecode, it will run on the JRE. Many languages, including Python, Ruby and Scala, can be compiled to bytecode. This allows multiple teams working on the same project to use their favorite programming language and integrate it with code from another team in a different language.

Just as Java is a large step forward from C++, there are a few shortcomings in the Java language as well. I will show some of those in later posts. Many languages, such as C# (pronounced C sharp), were inspired by Java and created to address some of the deficiencies. Despite those attempts, Java has remained a reliable and powerful language, and is the programming language used most in the industry. Now that you understand the history behind Java, it's time to learn how to write our first program in the next post!

Monday, May 15, 2017

Welcome and Motivation


Welcome to Java trails, your guide to becoming a better software developer! The goal of this blog is to provide a comprehensive overview of the Java programming language. It is an exciting time to learn Java programming. Java is currently the most popular programming language, and it is the one most used in the industry. In fact, the TIOBE Index (https://www.tiobe.com/tiobe-index/), which measures programming language usage, lists Java as having one of the top two spots since before 2000. Learning Java will provide you with a solid programming foundation that will be useful for years to come. You will also have a marketable skill that will allow you to find highly sought after jobs in the software development industry. In addition, you will learn how to write clean, elegant code, which can be applied to other languages. This blog can be used by both students who want to learn how to write Java programs, as well as professionals who are learning Java for the first time or coming from other languages.

I will start by focusing on core Java programming concepts (assignments, flow control, object oriented programming, collections, core APIs, etc). Along the way, you will learn the tools that software developers use to maximize productivity and write the best code. Once you have a solid understanding of the basic programming techniques, you will be ready to move on to more advanced topics such as creating Java web applications.

Why another blog?


You may be wondering why another blog on Java programming is needed when there are many other tutorials and books on the subject. I found that most of the existing Java resources were lacking in one or more areas:

1. Depth. Most blogs contain enough information to get a basic understanding of Java, but they do not provide enough coverage of the language (threads, garbage collection, string parsing, etc.) that allows you to really understand what is going on and write professional code. My goal is to provide a solid foundation of all aspects of the Java programming language and not gloss over important concepts.

2. Clarity. Many academic resources and programming references are notorious for being too complex, when the ideas they are explaining are actually much simpler. Consider this paragraph from the Java Language Specification:

The floating-point types are float and double, which are conceptually associated with the single-precision 32-bit and double-precision 64-bit format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985 (IEEE, New York).

The IEEE 754 standard includes not only positive and negative numbers that consist of a sign and magnitude, but also positive and negative zeros, positive and negative infinities, and special Not-a-Number values (hereafter abbreviated NaN). A NaN value is used to represent the result of certain invalid operations such as dividing zero by zero. NaN constants of both float and double type are predefined as Float.NaN and Double.NaN.

From this description, you might understand that float and double variables are used to represent positive and negative decimal numbers. But I bet you had to look hard to figure that out. Having a technical specification is good for academics and language implementers who need precise definitions, but it is a poor resource for people learning a new language for the first time. I am able to explain complex subjects in a focused, simple style that will make the learning process much easier for you.

3. Up to date information. Java has been around since the early 1990s, and there are tons of books and tutorials that you can find on the subject. A common problem is that blogs do not get updated, and books get out of date as Java continues to add new features and mature as a language. As a result, you may think that you understand certain concepts only to find out that there are newer and better ways to do the same thing. My goal is to keep you informed about the latest changes in the language and update existing articles as new features get added.

I believe that learning Java programming will be a fun and rewarding experience given the proper instruction. So what are you waiting for? Let's get started on our journey to becoming a great Java developer!