CS101 Study Guide

Site: Saylor Academy
Course: CS101: Introduction to Computer Science I
Book: CS101 Study Guide
Printed by: Guest user
Date: Friday, May 17, 2024, 12:36 PM

Navigating this Study Guide

Study Guide Structure

In this study guide, the sections in each unit (1a., 1b., etc.) are the learning outcomes of that unit. 

Beneath each learning outcome are:

  • questions for you to answer independently;
  • a brief summary of the learning outcome topic;
  • and resources related to the learning outcome. 

At the end of each unit, there is also a list of suggested vocabulary words.

 

How to Use this Study Guide

  1. Review the entire course by reading the learning outcome summaries and suggested resources.
  2. Test your understanding of the course information by answering questions related to each unit learning outcome and defining and memorizing the vocabulary words at the end of each unit.

By clicking on the gear button on the top right of the screen, you can print the study guide. Then you can make notes, highlight, and underline as you work.

Through reviewing and completing the study guide, you should gain a deeper understanding of each learning outcome in the course and be better prepared for the final exam!

Unit 1: Introduction

1a. Describe the history of software and computer design

  • Name a major historic trend in computer electronic circuitry.
  • What is the central historic trend in how computers are physically built?
  • What is one of the important algorithm-execution trends as computers evolved during their long history?
  • What was the first commercially-available computer programming language?

The history of computers really started in the days of ancient Greece when Aristotle (384 BC–322 BC) laid the philosophical foundation for the machines we use today. That thought process first led to mechanical and then to electronic machines. Within electronics, the trend was from vacuum tubes to transistors to integrated circuits. Those have become far more dense as time has gone on so that now a computer that once needed an entire building to support it can now fit easily into a handheld device. "Computer", taken in a general sense, can refer to the counting-sticks of prehistory and the beads of the abacus. Mankind has needed the ability to count, calculate, and organize data during most of its existence.

In the mid-1800s the first computer program was published by Lovelace, who worked with Babbage. Babbage had designed a computer that could not be fully implemented because of funding and a lack of suitable materials. That same machine was built in recent times according to his plans using modern materials. It worked exactly as originally designed.

As with Babbage's machine, programming languages have evolved as well. Some could not be implemented because of a lack of devices at the time. However, those early efforts began a process whose most important attribute is a gradual transition from machine-oriented to human-oriented languages. With that transition came the tools that enable the creation of systems having greater and greater complexity.

Review:


1b. Explain formal logic and how it is a subset of human logic

  • What is "formal logic"?
  • What type of thinking does formal logic entail?
  • What is the difference between formal logic and human logic?
  • How does Boolean algebra relate to formal logic?

Formal logic, a philosophy developed by Aristotle of ancient Greece (384 BC - 322 BC), admits to only one conclusion that is completely incompatible with any other. For instance: On/Off, In/Out, Yes/No, Black/White. Relating for a moment to set theory (Set Theory), nothing can be a member of more than one set at the same time.

Human logic, the way humans actually think, admits to an infinite number of conclusions. One can come to a conclusion that contains many components. Something can be a member of an infinite number of sets, to one degree or another, at the same time. A good example is color (Color Models: RGB, HSV, HSL). Using RGB notation, color can be described by three sets. Each set contains 255 possible members. For each set, we choose one of its 255 members to get a particular color. Other notations use a triplet of fractions that can be taken to any number of decimal places. Yet, computer hardware requires other notations to be translated to RGB. Therein is a serious limitation relative to the visual ability of humans. 

Thus, it is easy to see that formal logic, "binary thinking", is a small subset of human logic. Computers are simply boxes filled with on/off switches. Their operation can be described by formal logic. Their supporting mathematics can be described by Boolean Algebra (The Boolean Algebra of Sets), the formal syntax, and symbolic manipulation attending formal logic. This holds regardless of the sophistication of computers' electronics. Therefore, computers cannot be made to fully represent human thinking and abilities, by any stretch of the imagination. The role of the computer scientist is to make these highly-limited machines useful in a human-centric reality.

Review: 

  • An Introduction to Formal Logic
    • subsection on Logical Truth starting on pg. 7 
    • subsection 1.3 on two ways arguments can go wrong, starting on pg. 4. It is important to know when an argument is right or wrong, just as much as it is important when one is hearing, or not hearing, the truth.
  • A Concise Introduction to Logic: Read the introductory paragraph that appears immediately under the title.

1c. Describe the relationship between human logic, computers, and computer languages

  • What is the first step in writing a computer program?
  • How does the human-written program become something the computer can employ?
  • What are the limitations of the computer relative to mathematics?

How do humans write computer programs? The very first step is to have a vision of WHAT the computer needs to do. Then, that vision has to be articulated precisely in human language. This exposition can include text, figures, diagrams, tables, and other illustration tools. If you cannot articulate in human language what the computer is to do then it is not possible to write a corresponding computer program successfully. Management theory postulates a similar idea: no goal leads to no plan leads to no success.

By having a human-oriented expression of what the computer is to do, the human expression can be translated into computer-language syntax. We have already seen that there are many computer languages, all of which have the same basic capabilities. The most modern languages are better at facilitating the construction of complex systems, but, in the end, it is the human expression of what has to happen that gets translated into the syntax of some computer language. (This does not deny that modern systems are often composed of numerous modules, each of which may be written in a different computer language.)

Once the HOW of computer languages is employed, we have to take account of the computer's nature, its underlying essence. Computers, being finite binary machines, represent numbers in Base 2, rather than Base 10, as humans do. Often we see Base 16, hexadecimal, or Base 8, octal, notation. But, in the end, that becomes Base 2 within the computer. As such, and also due to the finite nature of computers, it is not possible for them to represent all fractions, very large numbers, or very small numbers with total accuracy. Whereas computer limitations make their accuracy inherently limited, mathematics itself is of infinite accuracy. Even an elementary calculation such as 1/3 is beyond the computer's ability to represent exactly. 

The computer's binary nature and its inherent inaccuracy must be taken into account when translating any process for computer implementation. Especially iterative programs, those that loop through a process as an answer is resolved, must take into account error build-up as operations proceed. Computers can be useful only when computer programs are written with careful consideration.

As you review this module, keep in mind that it is not so much the particular languages that matter by name. Rather, the reader should understand the evolution of computer languages. The key is the evolution from machine-centric to human-centric and the trend to increasing modularization. The trend toward building computer programs from pre-existing and trusted modules is also associated with modularization.

Review The History of Programming Languages. Focus on seeing the big picture of language evolution rather than trying to memorize particular language names and when they were created.


1d. Describe the basic computer model

  • What are the three major activities of a computer system?
  • What are the two major components of a computer system?
  • What mechanism allows computers to communicate with each other?
  • What are the two types of computer programs?

A computer is a very handy tool, a black-box that humans can program to carry out a sequence of steps. It has three basic capabilities: 1) input data, 2) process data, 3) output processing results. The computer does not invent the steps by itself. Even so-called "adaptive" systems still work according to human specifications. 

Lest we take "sequence of steps" literally, take note of the fact that a single core within a CPU can truly only do one thing at a time. But, modern CPUs contain multiple cores, each of which can operate independently. So, a single computer can actually be doing more than one thing at a time. Even peripherals such as printers and secondary memory (permanent data storage) can be operating while a CPU's cores continue with other work. Thus, a computer's throughput, how much it can get done within a given block of time, is greatly expanded well beyond "one thing at a time".

Parallel processing uses the same computer memory so that a single program can use threads to allow its modules to function independently but in coordination. Unrelated programs can also be running on other cores and still coordinating, but they are within the same physical memory, although not in the same program space. The operating system manages all this and distributes the workload according to the number of cores and memory available. Therein may lie a bit of trouble because a computer can only handle so much workload before its internal management overcomes any benefit of having multiple things going on at the same time.

An opportunity to further increase throughput (workload over time) beyond what one computer can handle is presented by distributed processing. Using networks, multiple heterogeneous computers can communicate and coordinate. Totally independent programs, not sharing the same memory or program space, can still exchange data and cooperate. It is also possible for different computers to be running the same program but with different data, while another computer consolidates results. Thus, here again, throughput can be improved. The modern world has shown that the exchange of data can yield many benefits, not only for industry but also for study, entertainment, and personal reflection.

As a general-purpose tool for human benefit, the computer can be quite powerful. Put it to good use.

Review:

  • Introduction to Computer Systems: Review the paragraphs associated with the table of contents. Together, these give a nice introduction. Do not let yourself become confused by references to storybooks you are not familiar with. Those references appear mainly in the first paragraph of each section and are not essential.
  • The Processor: Review the paragraphs associated with the table of contents. Each set of notes is very brief.
  • Introduction to Number Systems and Binary: This is an excellent video for understanding the basics of number systems. It is only 10 minutes long.

1e. Explain the programming life cycle

  • What is the very first step one should take when beginning a software development project?
  • At what point in a project is it best to catch something that has gone awry?
  • Describe an advantage of the waterfall model of software development projects.
  • Is software development a purely sequential activity?

We must always prioritize WHAT the computer is to be made to do. And what it is to be made NOT to do. It is seriously insufficient to only know HOW to make the computer do things. That approach leads practitioners into the trap of looking for nails to bang on with whatever hammer practitioners happen to have. Claiming that the hammer a practitioner happens to have is a universal tool for all needs is an even worse approach. If we are to provide value, we have to first discover what needs to be accomplished. Once that is established, we can discover how to best bring a solution to those needs.

Notice that the paragraph above puts computers and languages, hardware and software, midway on the list of activities attendant on projects intended to provide satisfying solutions. There are seven general cyclical steps in a software project. Things related to writing software should be left to Step D and later.

  1. Analyze
  2. Plan
  3. Design
  4. Implement
  5. Test and Debug
  6. Deploy
  7. Maintain

While a project may start off with these activities taking place one after another, the activities do not stand alone. Each provides information that informs prior and future steps in the process. Any project plan, however, has to clearly differentiate between the various activities so that milestones and progress can be measured. That is true with any process a project may follow. Otherwise, it is not possible to tell when a milestone has been reached or a project has been completed.

Do not put faith in process alone. Many teams get caught up with various process-related activities and forget about delivering a superior product. It is not necessarily the case that the project is successful just because all the process squares have been checked.

Review:

  • The Programming Lifecycle: This is a very short general-purpose reading. The listing of steps is not completely reflected in the diagram. And, the list of steps merges analysis and planning. But one can still get an overall sense of how a software project should proceed.
  • Comparing Waterfall, Unified, and Agile Software Development Processes: See the section at the end, Comparisons. It is interesting to note that even the Waterfall model is not a series of rigid steps with no feed-back or feed-forward. Whatever process is selected, it must be adapted to the project at hand. 

1f. Discuss the history of the Java programming language

  • What is the difference between a compiler and an interpreter?
  • How are compilers and interpreters involved in computer programming?
  • What is an Integrated Development Environment (IDE)? Why is it important?
  • Why is Java important to the evolution of computer languages?

Unless specified by the customer, the choice of computer language should be left until after the design phase of a software development project. Computer languages are simply means of expressing human thought in a way that a computer can do something with it. They are not the main focus of a computer software project. The main focus is customer long-term satisfaction.

For the purposes of this course, Java is the specified computer language. While compilers, combined with linkers, turn source code directly into machine code that is directly executable by a processor, interpreters read the source code and execute it line-by-line as the source code is read. In the raw sense, interpreters keep reading the source code and determining what to do from there, given variable values. In this case, what the processor does is implied by the source code, whereas a compiler/linker creates machine code first for direct execution by the processor.

Java is an object-oriented language that combines a compiler with an interpreter. Source code is compiled into bytecode and the bytecode is executed through a virtual machine that runs on the computer. Each processor type needs a Java Virtual Machine (JVM) written particularly for it. But, the source code is highly portable since the JVM, if standards are followed, always runs the code in exactly the same way, regardless of the computer's word size or processor type. This is in contrast to languages such as C/C++ where, for instance, the number of bits associated with an integer varies with the compiler/linker and the word size of the computer at hand. Therein lies a caution, although Java's syntax is very similar to C/C++, it is not at all the same computer language.

The history of Java is interesting. It originated at Sun Microsystems, a company that ultimately went bankrupt. Its assets were purchased by Oracle, a still-thriving company with a long and successful history. Java continues today. Its standards are guided by a committee of experts but are controlled by Oracle. Java continues as a steady, well-respected, language. Java skills are in high demand. 

Review:


1g. Set up a Java Development Kit (JDK) for Java development

  • What is the difference between JDK and JRE?
  • Where does one go to obtain the JDK?
  • Is JDK's installation process exactly the same for all operating systems?
  • What are two important (Integrated Development Environments) IDEs that support Java programming?

Here is where we start getting our hands dirty. We start by downloading and installing the Java Development Kit (JDK). Following the instructions in the readings, you download the JDK for your type of computer and the operating system it is running. While the JDK should operate the same on any computer, its underlying modules are not the same for all computers and operating systems.

JDK contains several tools. The most important are the Java Compiler (javac) and the Java Runtime Environment (JRE). javac reads the programmer's source code (*.java files) and compiles it into *.class files that contain bytecodes. java reads the *.class files and runs them through the Java Virtual Machine (JVM) to execute the program. You can write your first program using a simple text editor (Notepad, for instance).

While it is possible to write source code using a text editor, you should learn to use an IDE. As your programs become more and more complex, and employ more and more lines of code, modules, and third-party libraries, project timeliness and quality will suffer. Basic tools take increasing effort and time as complexity and lines of code grow. Project schedules and budget can rarely be expanded to accommodate this extra time. So, quality will necessarily suffer. You may well hear some practitioners brag that "I do my programming with a text editor" in an attempt to put themselves above others. But, nobody thinks you are smart if you deliver sloppy work, exceed budget, or cause delay. The demands of timeliness and quality are far too high with modern systems for you to not use appropriate tools.

Review Downloading and Installing JDK: Do not bother with the last section on JDK Versions. At the very bottom of the page is a second section marked JDK Versions. Examine this for installation instructions on your particular computer and for some example code. There is also a discussion on programming tools.


1h. Set up a NetBeans IDE for Java programming

  • Where does one go to download NetBeans?
  • Why is NetBeans important to Java programming?
  • With what other tools does NetBeans integrate?

We talked earlier about why an IDE is important to computer programming. This goes for all languages, not just Java. Besides programming support, NetBeans facilitates the use of MySQL, a popular open-source database management system (DBMS). MySQL is directly compatible with Oracle DBMS so that proofs-of-concept can be readily transitioned to production.

Worldwide accessibility is very important in today's business and industrial environment. This includes data acquisition, storage, management, processing, and delivery. Thus we have "cloud computing". We can make our local computers accessible or we can run our applications on someone else's computer, operating it remotely. Java is particularly good at this type of application. NetBeans greatly facilitates writing such programs.

Review Downloading and Installing NetBeans IDE: There is a brief introduction and then a table of contents. Pay particular attention to Chapters 1 and 2. For now, the rest can be used for reference.


1i. Write and run a simple Java program

  • What is the basic structure of a Java program?
  • What is the difference between Java source code and bytecode?
  • How is it that a simple text editor like Notepad can be used to write Java source code?
  • List the general steps in getting a Java program to compile and execute.

So far, we have studied the "theory" of computers, programming, and the Java programming language. In this section, we put theory into practice. While it is true that theory is important, it has no value unless it has a positive effect on what we actually do. On the other hand, practice without a solid theoretical foundation rarely leads to more than taking shots in the dark. It is important to understand what one is doing and why before actually doing anything.

For very simple programs, using a text editor such as Notepad is sufficient. We can write the program, save it, compile it, and run it, using distinct steps. Problems arise when trying to debug programs that are longer and longer, with increasing complexity. Ultimately, a text editor such as Gedit becomes useful because that tool can highlight the various components of Java source code (and other languages too). Ultimately, an integrated development environment (IDE) becomes essential. Such a tool not only does the same as a sophisticated text editor, but it also highlights code that does not pass the compiler's review. It can also point out places where better programmer practice should be applied. Then, during execution, one can step through the program line by line to discover logical errors and misvalued variables. Programmer mistakes become very easy to spot, as well as faulty third-party modules.

Be sure to take this opportunity to practice, practice, practice by going beyond "Hello World".

Review:

  • Introduction to Java: Sections 3, 4, 5, 6 are for review of previous material. Concentrate on the others so that you go through the entire process of creating, compiling, and running a Java program.
  • Fill in the Blanks - Review: This quiz would be well worth going through to increase your attention to important detail.

1j. Explain how computers are a tool to assist people and describe appropriate and inappropriate uses of computers

  • If we learn we can do something, should we necessarily do it?
  • In what way does innovation cause change?
  • In what way does change cause innovation?
  • Does innovation require advances in technology?

Innovation has been described as the process of making improvements by introducing something new. While short, the construction of the previous sentence is very important. Notice the prominence of the word "improvement". The phrase "something new" is a supporting adjective, not the main point of the definition. In the same way that "change" is not necessarily improvement, neither is "something new". 

"Improvement" itself can not be defined alone. It must be defined relative to an existing situation. Before implementation, the implications and risks of the "improvement" must be known and well understood. Thus, innovation is more than learning how to do new things. It is more than changing what already exists. There must be a goal in mind and the change or innovation must advance toward a positive goal. That advancement must be measurable so that present status can be determined relative to the goal.

Thus, innovators are far more than "change agents". They are those who enable the present situation to advance toward a better future. 

To review, see Innovation and Its Application.


Unit 1 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • abacus
  • Aristotle
  • Babbage
  • Base 2 numeric notation
  • Base 10 numeric notation
  • binary thinking
  • Boolean Algebra
  • bytecode
  • C/C++
  • compilers
  • formal logic
  • hardware
  • human logic
  • integrated development environment (IDE)
  • innovation
  • interpreters
  • Java
  • Java Development Kit (JDK)
  • Java Runtime Environment (JRE)
  • linkers
  • Lovelace
  • machine code
  • memory
  • NetBeans
  • networks
  • operating system
  • processor
  • program
  • programming languages
  • set theory
  • software
  • source code
  • word size

Unit 2: Object-Oriented Programming

2a. Discuss the differences between object-oriented and procedural languages

  • How is a class different from an object?
  • Describe the evolution of design and programming practice from pure-procedural, through modular, to object-oriented.
  • What is a use-case?
  • Explain how procedural software can be found within object-oriented software.

"Object-oriented" refers to a world-view that identifies and describes "things". These "things" have attributes and behaviors. A system is built of "things" that communicate and coordinate. A specific "thing", a particular car, invoice, or receipt, is called an object. A description, attributes, and behaviors, of a general "thing", cars, invoices, or receipts, is called a class. We describe the attributes and behaviors of classes and then instantiate specific ones as objects. Objects interact, exchange data or messages, so as to update each other and otherwise coordinate.

A purely procedural approach uses only a sequence of instructions. We can choose which instructions to execute and can repeat sets of instructions. Between pure-procedural and object-oriented is the modular approach which is the use of subroutines and scope within procedures. While not truly object-oriented, its principles allow us to make the best use of languages that take a modular approach. An example is the C language. It is not object-oriented, but the principles can be applied to its modules and data structures. This improves our use of such languages.

Despite all of this, it is not a choice of procedural, modular, or object-oriented. Rather, those three represent an evolution. Procedural code is still used to write an object's behaviors. Classes are an expansion of the concepts behind modules. When employing object-oriented languages to their best effect, all three are used, with a solid object-oriented approach being the goal.

Review Traditional vs. Object-Oriented Approaches: Pay particular attention to Part 5, note the similarity between the project management described here and what was discussed earlier.


2b. Explain the difference between classes and objects

  • What are the two components of a class description?
  • From where do objects come? From what are they instantiated?
  • Are "class" and "object" synonyms?
  • Is a class necessarily described only within itself? If not, explain.

"Class" refers to a general description of something that gives it attributes and behaviors. For instance, a car may have doors. Each door may have a different color (attribute) and the doors may open and close (behavior). "Object" refers to a specific entity that exists within the universe of our application. For example, we may have a specific car that is assigned a unique attribute such as "license plate". There is no other car like that one. You can identify a particular car by a key attribute or by its position in a vector, an address location in memory.

There is an interesting case with classes in that they can inherit other classes. For instance, the car class may inherit a door class. With that capability, it is possible to describe a general-purpose door that has all the attributes and behaviors as every door. A particular type of car can inherit the general door and add to it. Thus, the classes making up the application's world can be built up from many other classes. But, beware of overdoing inheritance. Remember the modular nature of the object-oriented approach. You should be able to easily extract classes for reuse, just as one should be able to extract subroutines, functions, and structures from procedural languages. 

The concept of classes can be extended through polymorphism, the ability of a class to behave differently under different circumstances. For instance, a class-animal may behave differently if it is inherited by class-human instead of by class-dog. It depends on what attributes and behaviors have been overridden by the inheriting class. Overriding basic operators is another example. Numbers may behave differently under such circumstances. Use such capabilities carefully since they increase the software's complexity. Increasing complexity does not make us appear smart. Rather "smart" is shown in maintainable and understandable systems that are produced within budget and schedule, and which satisfy long-term customer needs and wants.

Review Objects and Object-Oriented Programming: The first half is review, be sure you understand what is discussed in paragraph nine onward. 


2c. Explain object-oriented concepts such as inheritance, encapsulation, and polymorphism

  • Define the following terms: inheritance, encapsulation, polymorphism, decoupling, subclass.
  • What is the advantage of inheritance?
  • Describe the difference between a subclass and a class extension.
  • Why is decoupling essential to the implementation of object-oriented concepts?

An essential aspect of object-oriented programming is that class descriptions are separate from associated objects, class instantiations. Especially with third-party libraries, we often do not have access to class descriptions, only to their interfaces. This enhances modularity and allows us to use the same description for multiple purposes. It also eases class maintenance and evolution since only one class description exists for all associated objects. Important too is that an object instantiates a class description as a completely independent entity. An important result is that the value of a class attribute exists only for that object and does not affect the attribute's value of any other object. Behaviors of a class affect only a particular instantiation, object, of that class. 

Once an object is instantiated, its private behaviors and attributes cannot be accessed by anything outside that object, even by objects of the same class. It is possible to declare attributes and behaviors as public but that should be done with care. As systems become more complex, it is difficult to keep track of which other object, subroutine, or code component is modifying which objects at what time. This is especially true when multiple independent parallel or distributed processes are involved. Generally, it is best to not allow code from outside an object to directly modify anything within the object. By controlling access to class attributes and behaviors, we "encapsulate" those within the class description.

From a general description (class definition) we can create more specific descriptions. For instance, based on the description of a general ground-based vehicle, we can go on to describe trucks, cars, and buses. All would use (inherit) the description of a general ground-based vehicle. Or, we can extend the description of a general ground-based vehicle by adding a new behavior or attribute. These are very powerful approaches to design and programming if applied judiciously. They go well beyond pure-procedural or modular approaches since those do not take object-orientation to its fullest extent, although object-orientation does include procedural or modular concepts.

Review:

  • Inheritance, Polymorphism, and Abstract Classes: There is no real way to avoid reviewing this entire reading as it gives Java coding examples that accompany full explanations of important concepts in object-oriented programming.
  • Java Encapsulation: In all of computer programming, detail is extremely important, this reading shows syntax examples that implement object-oriented theory in Java, pay particular attention to the tables and figures as these go a long way to explain what the syntax accomplishes.
  • Decoupling: This short reading gives a fully-annotated Java example to illustrate an explanation of decoupling as a concept within object-orientation. 

Unit 2 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • class
  • encapsulate
  • inheritance
  • modular approach
  • object
  • object-oriented
  • polymorphism
  • procedural approach
  • vector

Unit 3: Java in Practice

3a. Write Java classes using file naming conventions

  • What is the difference between *.java and *.class files?
  • Within which class method does a Java program begin executing?
  • What is a reserved word?
  • Explain matching syntaxual pairs.

In Unit 2, we went through the basics of creating, compiling, and running Java programs. In doing so, we also learned the difference between source code and bytecode.

As you write your next programs, learn how to use indenting, it sounds like such a simple thing that has no impact at all on what the program does or how it will be compiled. It also has nothing to do with what bytecodes get generated. Yet, it can be critical to writing successful computer programs, especially as those programs become more complex. The same can be said of commenting. There is excellent material on both those topics in the readings.

When writing programs, it is important to create meaningful names (identifiers) for your classes, methods, and variables. Recognize that some identifiers are reserved to the language itself. Those cannot be used to name anything else. Programmer identifiers must be unique but are meaningless to the compiler. Still, they are essential to programming, from the human perspective. (Calling something xxx is no different from calling that same thing yyy, from the compiler's perspective.) Indenting, commenting, and meaningful identifiers all have to do with human-readable code. Such code is essential to debugging, finding and fixing syntax errors or logic errors in a program. Readable code is also important to maintenance, modification, and evolution. Do not be caught in the trap of thinking you are smart if nobody can understand the code you write. That is a mark of a non-professional and is easily spotted by technical team leaders. If you take that route, do not be surprised when you find yourself on the outer edge of the plate as the economy goes through its cycles. As a cycle brings on a decline, the plate shrinks. Non-Professionals fall off the plate (get laid off) at that point. Your job becomes insecure and you become less employable.

We spoke about Integrated Developer Environments (IDEs) and advanced text editors earlier. Those can help a great deal with a language's syntax. For example, they can identify matching syntaxual pairs such as ( ) , { }, and [ ]. These details are easy to miss as one translates human expressions of processes into something the computer can understand (a particular computer language). Let the computer help you with the details so that you can concentrate on what you are trying to accomplish.

Review Small Java Problems: Sections 1, 2, 6, 21 are for review, pay special attention to the rest.


3b. Use pre-written Java classes from various packages in the Java API

  • Name important Java language packages (libraries).
  • In what way does the order of import statements matter?
  • What can be made available in a package?
  • Explain the value of interfaces.

Packages are composed of several classes, interfaces, and other formal types. These make up callable libraries, some within the Java language itself, while others are written by third parties for specific purposes. 

Java packages organize classes into unique namespaces. Classes in the same package have access to private and protected members of all classes in that package. Packages can contain the following types: classes, interfaces, enumerations, and annotations. Programmers can group classes and interfaces according to various criteria depending on the system being created.

Java interfaces expand beyond what other languages provide. They are very useful for describing abstract data types. Interfaces offer method signatures, but not method contents. Classes implement interfaces by declaring the interface in an implements clause. It is in the class description that method bodies are provided for interfaces.

When we import a package, we gain access to the classes and interfaces that have been made available within the associated library

Review Importing Libraries in Java: This is a very short reading, be sure you understand its contents (the paragraphs about this learning outcome contain two links that offer additional details for those who wish to delve further).


3c. Explain and use primitive data-types in Java

  • What is a "data type"?
  • What is the difference between primitive data types and classes?
  • In general, how are data types represented in computer memory?
  • Name Java's eight primitive data types

Often you will hear that everything in Java is a class. But, that is not quite true. There are eight primitive, non-class, data types. These are: byte, short, int, boolean, char, float, double, long. Notice the case sensitivity of those terms. Be mindful, for instance, that int is not at all the same as Int. Int is a class that does indeed contain an integer ( int) but it also contains methods for manipulating that attribute. The same is true of the other primitives. As you may have noticed, objects take up far more memory than do primitives. Thus, at times when class methods are not needed, it is sometimes useful to use a primitive instead of its associated class.

Context is essential in computer programming, not only in human logic but also in the way computers represent data. At the human level, if we say A=B, what does that mean? What does A stand for relative to the application's goals, design, and implementation? Meaningful naming of variables helps with that situation. Inside the computer, A is stored as a series of binary digits. The data type assigned in the source code allows the compiler to mark the binary digits with a "flag" that explains how to interpret them.

Review:


3d. Declare and use variables of different data types while writing Java programs

  • What is the syntactic difference between declaring primitive and non-primitive data types?
  • Why would one want to declare a non-primitive number vs. a primitive number?
  • What other kinds of data are there in Java besides primitive data types?
  • Could something called "Worker" be a data type in Java?

There are only two types of data in Java, primitives and objects. There are only eight primitives that can be defined. There are potentially an infinite number of objects that can be defined. The data type of an object is its class name. Java itself defines a fair number of these that have been found to be broadly useful. Third-party libraries define others for special purposes. Programmers can define their own.

Reusability is an important cause for writing good non-primitives, class definitions. If done well, these can be used in more than one program, improving as they go, while maintaining their basic functionality and interface. Studies have shown that it takes 25% more time to write reusable classes but that it is well worth the effort over the long term.

Something to keep in mind is that a primitive data type has a fixed number of bits associated with it. Therefore, a minimum amount of memory is occupied. There are no associated methods or other variables within the definition of primitive data types. Such is not the case with class objects. Classes have attributes (variables) and behaviors (methods, functions, subroutines). Depending on the type of variables contained, an object can vary in the amount of memory occupied. For example, an object may include a string of characters. That string can grow and shrink and grow again as the program proceeds. This may not be acceptable in low-memory embedded systems.

Review Primitive Data: Objects.


3e. Perform various mathematical operations using +, -. *, /, and % operators

  • Besides equals, =, what other assignment operators are there?
  • What are the arithmetic operators?
  • Do arithmetic operators only work on primitive numbers?
  • How can the sequence of arithmetic operations be changed from that imposed by operator precedence?

Assignment operators perform a fundamental role in computer programming. They copy memory contents from one location to another. Yet, arithmetic and assignment operators are often combined. This allows for a bit of shorthand in the code and a reduction in the number of bytecodes generated. It is interesting to note that the order of combination is important. For instance, x = ++y; does not yield the same value for x as does x = y++;. The latter copies the value of y to x and then increments y by one. The former increments the value of y by one and copies the result to x. The same is true for the -- operator.

Operator precedence is an important consideration. Without any other indication, an equation will be calculated based on the precedence of its operators. For instance, a unary minus, -x for instance, will be performed before something like a - x. So, you may see something like a - -x. In that case, the unary minus will be applied to x prior to that result being subtracted from a. Operator precedence can be overridden using parentheses. The innermost parenthesized equation components will be performed first. So, for example,  x - a * b will not yield the same result as (x - a) * b.

As you can see, computer programming is very detailed. Pay attention to those details and grow with them. Eventually, they will all fit together and make sense without a lot of overt memorization.

Review:


3f. Use String class and its methods while writing Java programs

  • What is the basic definition of "string"?
  • What does "null" mean in regards to String objects?
  • What does it mean to cascade class operations?
  • To what does "immutable object" refer?

Although strings are very complex entities, we study them only in their simplest form. Think of a string as a vector (sequence) of 16-bit characters that can be manipulated in various ways. Each character is individually addressable. Java uses "String" as the class name for this kind of variable.

There is one way in which a String can be operated on using a numeric operation. thisString = thatString + someOtherString; places the concatenation of thisString and someOtherString into the memory location of thisString, (someOtherString's text is placed at the end of thisString's text.) Notice that it is possible that concatenation may yield a result that requires more memory than referenced by the target variable. In such a case, new memory has to be allocated. If shorter than the target variable, there is "leftover" memory that becomes unoccupied. In either case, something has to be done to make the orphaned memory available to the program. Languages such as C/C++ require the programmer to write code to accomplish this. Java, on the other hand, handles such situations automatically. The process is called "garbage collection".

String objects are immutable. That means that a String's behaviors do not modify that String's attributes. Rather, they return a new string. Keep that in mind since it is something many programmers forget. If you do forget this, your programs will compile and run. But, they may yield unexpected results.

Become familiar with the various methods associated with the String class. They make common string operations easy to implement and save a lot of programming effort.

Review:


Unit 3 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • bits
  • case sensitivity
  • characters
  • classes
  • commenting
  • concatenation
  • data type
  • debugging
  • garbage collection
  • identifiers
  • immutable
  • implements clause
  • import
  • indenting
  • integer
  • interfaces
  • library
  • logic errors
  • memory
  • methods
  • objects
  • operators
  • operator precedence 
  • packages
  • primitives
  • primitive data type
  • source code
  • string
  • syntax
  • syntax errors
  • unary minus
  • variables

Unit 4: Relational and Logical Operators in Java

4a. Explain relational operators such as >,>=, <, <=, ==, and !=

  • How are values compared?
  • Do relational operators work only with primitives?
  • Are arithmetic operators the only way to manipulate data?
  • How is Boolean Algebra applied in this language?

Data takes many forms. We have reviewed primitives, classes, and several types of numeric data. There are also structures and booleans. You cannot use most relational operators with classes. The equals relational operator simply checks to see if two variables are pointing to the same memory location. For instance, you cannot apply greater-than or less-than to two boolean variables. So, while it may make sense in the human or numeric way, it is not always something the language can do. Similar rules apply to classes and structures, but not necessarily to their attributes. There are also times when comparisons are performed using a class method rather than a relational operator. Be alert for such cases and use the approach appropriate to the situation at hand.

Review Boolean Expressions: Critical information in these sections: 9, 10, 21


4b. Write Boolean expressions using relational operators

  • What is the difference between relational, logical, and boolean operators?
  • How can relational and logical operators be combined to create complex comparisons?
  • How can boolean operators be used to create extended comparisons?

By combining logical operators and relational operators, you can ask complex questions such as "Is A greater than B at the same time that C is less than D?" While this example seems rather simple, relational operators can be combined with logical operators to make extensive comparisons.

Boolean operators can be used in a similar way to ask such questions as "Are any of these conditions true?" or "Are all of these conditions true?". Of course, boolean operators can be used for other things. An example is the use of bit-shifting to divide an integer by two. In some cases, this can be a lot faster than using the normal division operator. An interesting discussion on this matter can be found here: Should I bit-shift to divide by 2 in Java?

Review Boolean Expressions: See these sections: 3, 7, 8, 11, 14, 15, 16, 19, 20, 22


4c. Use logical operators such as &&, ||, and !

  • What is the difference between the && and || operators?
  • What does the ! mean in English?
  • Can the operators &, &&, ||, |, and ! be combined within the same "if" statement?
  • Is an "if" statement the only way to effectively use the operators &, &&, ||, |, and ! ?
  • What is the purpose of the ternary, "?", operator?

Logical operators are very powerful, especially when combined with boolean operators since these allow complex questions to be asked programmatically. The more you understand about Boolean Algebra and its associated truth tables, the better you will be able to satisfy sophisticated requirements.

Although not highlighted in the readings, do not ignore Java's ternary, ? relational operator. The ternary operator has three arguments. It is used to combine relational and logical expressions while making decisions on which value should be assigned to the target variable. The basic expression is:

targetVariable = (logical expression) ? value if expression is true : value if expression is false;

This is the same as:

if (logical expression) targetVariable = value when logical expression is true;

else targetVariable = value when logical expression is false;

Notice that targetVariable value could also be an equation or conditional of one kind or another. 

It is certainly not the case that an if statement is the only way to get good value from relational, logical, and boolean operations. variableX = operationY; is also useful, if variableX is suitable for receiving the results of operationY. Consider the full range of options available to you. A Quick Intro to Java, section 2.10, pg. 23 on "targetVariable value" explores this niche topic further. 

Review Fill in the Blank: Operators: This review does a good job of bringing together the several lessons on Learning Outcomes 4a, 4b, and 4c.


4d. Evaluate truth-tables

  • Why are truth tables important?
  • What are the implications of De Morgan's Laws?
  • What is the "negation" of AND and OR?
  • What is the negation of a negation?
  • What is the precedence of negation?

There are two tools presented here that are important as your programs become necessarily more sophisticated and complex. (Yet, do not think making your programs look complicated is the way to career success. It is not.) Truth tables are used to organize relational and logical expressions to facilitate their expansion. De Morgan's rules help us reduce the complexity of a given expression so that it is easier to understand its implications and to implement the reduced expression in circuitry and computer code.

An example truth table:

A

B

A AND B (A && B)

A OR B (A || B)

false

false

false

false

true

false

false

true

false

true

false

true

true

true

true

true


Note the independence of the logical expressions A and B. Logical expressions are evaluated independently. Relational operators make use of those results. The result is boolean, either true or false.

According to De Morgan, !(A && B) = (A&&B) = !A || !B. He also states that !(A || B) = (A || B) = (!A && !B). These are good to know. You can legitimately restate the specification as long as the requirement is met. Restated specifications are sometimes easier to meet. Although the readings do not discuss the matter, binary circuitry (the type used with computers and embedded computational devices) can often be made less expensive through the use of De Morgan's Rules. This kind of thing is called "logical equivalence". You can view a good eight-minute video on this topic (Logical Equivalence). It is part of a series should you want to dig deeper than the readings take you.

Review Truth Tables and De Morgan's Law: Be particularly familiar with sections 2, 4, 7, 8, 9, 10, 11, 12, and 18; the rest are for practice.


Unit 4 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • bit-shifting 
  • De Morgan's rules
  • logical operators
  • relational operators
  • ternary operator
  • truth table
  • XOR
  • AND
  • NOT
  • OR

Unit 5: Control Structures

5a. Use control structures

  • How can a program adapt to evolving circumstances?
  • How do we control the flow of a computer program?
  • How do we cycle through a block of code until a certain condition is reached?

There is, as we have seen, a certain logic in the writing of computer programs. One step flows naturally into another so that a particular outcome is reached. Such sequential programming is a good way to start. However, especially in this modern age, programs must adapt to evolving circumstances. These circumstances arise because of the data put into a program and the increasing complexity of the steps to process that data. As in all things, there are effective and ineffective ways to achieve this.

In this course, we are studying the ways of formal logic, "if this then that and nothing else". There are other ways, not least of which is fuzzy logic from Lofti Zadeh, which admits to multiple-set membership but also which admits that, eventually, we have to make a crisp decision on how to react (Fuzzy Logic). There are also gaussian networks and other means of breaking up a decision space so that you can be more selective than formal logic allows. Many of these can be likened to statistics, a formal mathematics for making the best guess possible given the data at hand. We do not dig into these in this course but you should be aware they exist.

Constructs common to many languages: if-then, if-then-else, while, do-while, for, conditional operator, and switch statement, are an important part of C++. These allow us to select which block of code to execute, under which circumstances, and how long to continue the execution of that code block. We specify a condition and then decide whether or not that condition exists. Thus, our algorithms (problem-solving steps, steps to achieving a certain outcome) can grow in complexity and adapt to the circumstances and associated data.

Review: Control Structures: A relatively short reading that introduces the concepts and constructs to be discussed in detail in this unit.


5b. Write an 'if' statement

  • What are the two types of 'if' statements?
  • Which type of 'if' statement could be paraphrased, "If the specified condition exists, execute these steps. In any case, execute these other steps"?
  • What is the maximum number of code blocks within an 'if' statement?

'If' statements control access to a maximum of two blocks of code as shown in this table:

If (condition) then < control block 1>

.... < code executed regardless of condition >

If (condition) then < control block 1>

else < control block 2>

..... < code block executed regardless of condition >


Depending on the condition, a boolean true/false result, <control block 1> or <control block 2> will be executed. Regardless of the condition being true or false, the code after the 'if' statement will be executed. This allows us to run unique code on the basis of the situation at hand within the computer program. For instance, a variable called 'temperature' might cause a certain block of code to be executed if the value is beyond a certain threshold. Or, we might want to issue an overdraft notice if dollars_in_account falls below zero. The 'if' structure allows us to carry out these ideas.

Review: Decision Making: See these sections for a review of the basics: 2, 8, 13, 16, 17


5c. Write a 'switch' statement

  • What is the essential difference between switch-case and the conditional operator?
  • Which component of the switch-case is often forgotten by programmers but will compile and execute anyway? Why is it a bad idea to not employ this component?
  • Why would we want to use the conditional operator instead of if-then-else?
  • What can if-then-else and the conditional operator deal with that switch-case cannot?

if-then-else can be compared to the conditional operator in the following way:

if-then-else

conditional operator

if(condition)

{

< code block if true >

}

else

{

< code block if false >

}

variableName = (condition) ? <value if true> : <value if false >;


Notice that if-then-else can execute an entire code block, whereas the conditional operator simply assigns a value to a variable. So, the conditional operator is a convenient shorthand for simple cases. It can be used in more complex cases by calling a function that returns a value appropriate to the left-hand side of equals.

Switch-case concentrates on integer values only. The "switch" is an integer variable of some type. The "case" is what to do when the value is equal to a particular value. This table compares switch-case to if-then-else:

if-then-else

switch-case

if(result == v1) { <code block if true>}

else if(result == v2) { < code block if true>}

...

...

...

else { <code block if none are true> }

switch(result)

 {

case v1:

<code block if result == v1>

break;

case v2:

<code block if result == v2>

break;

...

...

...

default:

<code block if none are true>

}


As you can see, switch-case is more readable and understandable than lengthy if-then-else. On the other hand, if-then-else and conditional operators can deal with more than just integer types. You should pick the approach that is most appropriate to the program being written.

When using a series of if-then-else or switch-case, always have a default result, what should happen if none of the conditions hold. It is never good programming practice to leave out the critical condition, "none of the conditions hold". This could well be indicative of a logic or programming error earlier in the code. Even when nothing needs to be done in such a situation, at least put the default in with a dummy operation and a comment that nothing needs to be done. Make that conscious decision. Also, with switch-case, do not forget the "break" component. Otherwise, the code will continue to the next code block. 

Review: The Conditional Operator and the 'switch' Statement: See these sections for review: 2, 5, 6, 8, 9, 12


5d. Explain various looping structures such as for, while, and do loops

  • What is the difference between a while loop and a do-while loop?
  • What is the difference between a for loop and a while loop?
  • Why do we need conditional looping structures?
  • Can conditional looping structures be combined with non-looping conditional structures?

We have previously examined non-looping conditional structures. These ask a true/false question and execute a block of code once, depending on the answer to the question. Now we turn to looping conditional structures. These ask a question and continue to execute a block of code until the answer to the question is false. At variance with this idea is do-while. It will execute its block of code at least once, regardless of the answer to the question.

while loop syntax: while(condition) { <execute this block of code> }

As long as the condition is true, the block of code will be executed over and over again.

do-while loop syntax: do { <execute this block of code> } while(condition)

The block of code will execute at least once and then over and over until the condition is true.

for loop syntax: for(<operation 1>; <condition>; <operation 2>) { <execute this block of code> }

When this structure starts, <operation 1> is carried out. Then the condition is checked. If the condition is true, the block of code is executed. Then <operation 2> is carried out, following which the condition is checked. If the condition is true the block of code is executed again. Then <operation 2> followed by checking the condition. This process continues until the condition is false.

Clearly, looping conditionals keep us from having to duplicate blocks of code. Note that blocks of code can be anything legal in the language. So, non-looping and looping conditionals can be combined. Note also that if the condition never becomes false then the loop will continue until the program is manually halted.

Review:


Unit 5 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • algorithms
  • break
  • conditional operator
  • default
  • do-while loop 
  • for loop
  • if-then
  • if-then-else
  • looping
  • switch-case
  • while loop

Unit 6: User-Defined Methods

6a. Write methods with zero or more parameters

  • What is the difference between a class parameter and variable?
  • What are the two ways to change an attribute owned by a particular object?
  • What is the lifetime of a variable?
  • Is it valid to specify a class without specifying a constructor and destructor? How so?

In earlier readings, we saw that a class is composed of behaviors and attributes. These are used to describe a class of objects (all trucks in general, for example). Another name for "behavior" is method, and for "attribute", parameter. Depending on which author you are reading, you will see those synonyms regarding class descriptions. The figure illustrates this idea.

In Unit 6, we learn how to write class methods, how to pass parameters (arguments) into a class method, and how to retrieve data from a class. Recall that an object is a specific instance of a class. There can be many trucks, for example. All objects of a class operate (behave) in exactly the same way. But, each object may contain different values for its parameters (attributes). Each object is independent of all other objects, even those of the same class. 

Independence has interesting implications for concurrent processing, whether that takes place on the same physical machine in the same program memory (threads, parallel processing), or on the same physical machine in different program memory (distributed processing), or on different machines connected to a geographically-dispersed network (distributed processing). All three types can be said to be concurrent in that they have more than once process executing at the same time. Beware of vendors who claim "distributed processing" when they are actually spawning processes only in different program memory on the same physical machine, in the same physical memory of that machine, albeit in different program memory. Distributed processing is highly limited in its impact, and it imposes significant operating system overhead, if it is exercised within only one machine's physical memory.

With that in mind, we get into the concept of "scope". Scope refers to the accessibility and lifetime of variables and class parameters. The value of a class parameter is only valid for a particular instance of a class. It persists for as long as the object exists. A variable only exists only within its scope. Scope is generally marked by curly brackets { <variable specification> }. By "accessibility" we mean that a parameter or variable cannot be accessed outside its scope. An exception is that a class parameter or method can be accessed outside the class if the parameter or method is specified as "public". Except for constructor, destructor, mutator, and accessor methods, making attributes and behaviors public is generally a bad programming and design practice. But, there are cases when practicality makes it necessary.

Another important fact is that Java is a pass-by-value language. In other words, if you pass a variable's value into a method, it is only the value that arrives, not a reference to the variable. Even if you use the same variable name inside the method, changes to the value will not be reflected outside the method. One consequence of that fact is that if you pass an object into a method, it is not possible to change the object itself. However, it is possible to change public parameters of that object and to call its public methods. Those new values persist even once the originally-called method ends. That is because you are referring to a specific object and that object contains its own methods and parameters.

Review: 


6b. Make method calls

  • How is it possible to have two behaviors with exactly the same name within a class description?
  • When can there be a class attribute with the same name as a method variable?
  • Is it possible to change the value of a variable that is passed into a method so that its value outside the method is changed?
  • Can there be two variables with the same name within the same scope?

Methods have signatures. If the signature of the method is different, the method name can be the same. A method's signature consists of its name, the number of input parameters (arguments), and the types of its parameters. If any of those are different, then the signature is different and the correct method will be called by the JVM. There is no violation of scope in such cases.

Scope itself speaks to the existence of a variable. It exists only within its scope. Curly brackets,
{ < code > }, denote scope. For example:

variableName within //Scope A

variableName within // Scope B

{

// Scope A

int variableName = 0;

{

variableName -= 1; // valid access

}

}

{

{

// Scope B

int variableName = 0;

}

variableName -= 1; // invalid access

}

Be aware of the this pointer. this refers to the object at hand. For example: A class may have an attribute named thisAttribute. It may require initialization. A parameter of the class constructor may have the name thisAttribute. How does the program tell them apart? It is certainly valid to say, thisAttribute = thisAttribute, or to ask, thisAttribute == thisAttribute, within the constructor. But, that only refers to the constructor's input parameter. To initialize the class attribute, it is necessary to write,  this.thisAttribute = thisAttribute. this references the object and .thisAttribute refers to the attribute in question. By itself, thisAttribute refers only to the method's input parameter or to some other variable defined within the method.

Review Parameters, Local Variables, and Overloading: Sections 2, 3, 5, 16, 17, 20; however, the other sections provide good examples and further explanation.


Unit 6 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • accessibility 
  • arguments
  • attributes
  • concurrent 
  • concurrent processing
  • distributed processing 
  • method
  • method signatures
  • parallel processing
  • parameter
  • pass-by-value language
  • public
  • scope
  • threads
  • variable

Unit 7: Arrays

7a. Declare and use one-dimensional arrays

  • Why do we care about arrays? What are they good for?
  • What is the relationship between arrays and objects in Java?
  • Which data types can make up the cells of an array?
  • Can mixed data types populate the cells of the same array?

You may have heard the phrase "data driven applications". Broadly, it refers to the vast volumes of data that are available in the world today. It is possible to build time-dense "sensors" that gather data at a minute level. This data can be used to guide business and industrial activity to increase profitability. However, gathering data itself is useless if you can only listen and look. You have to also hear and see. To do that, you have to process your data. That processing requires the organization of data in some useful way. As in all things, there are ways and there are ways. In this unit we discuss arrays, a means of organizing data into multidimensional blocks.

Data of any single type can be organized into an array. Arrays can be of only one dimension (a vector) or multiple dimensions (a matrix). In matrix algebra, even a single variable can be thought of as a 1x1 matrix. It may be difficult to imagine matrices of higher than three dimensions. But, think of a room of rooms filled with chests of drawers and cubby-holes in each drawer, each cubby-hold containing a specific item.

In Java, arrays are objects. As in other languages, each cell (element) of an object (data of some type) can be operated on just like a single variable of that type. So, for instance, integers can be multiplied or object attributes and methods can be accessed. The idea of arrays containing objects can be very powerful since an object's class definition can contain variables of any type, including arrays. Thus, we can have arrays of arrays, each with their own independence and data element values.

Review Arrays: Arithmetic Expressions: At least read sections 2, 3, 4, 5, 15.


7b. Create, initialize, and access multi-dimensional arrays

  • How are multi-dimensional arrays created, initialized, and accessed?
  • Is there a limit to the number of dimensions or the size of any dimension? Why?
  • How can nested loops be used to initialize a multidimensional array?
  • How can randomly selected in-range integers be used for accessing a multidimensional array?

The ability to work with arrays beyond three dimensions greatly expands your potential for building programs that deal with situations of considerable complexity. Java sets no limits on the number of dimensions. Only available memory limits the size of each dimension. Thus, Java is positioned to enable solutions to problems not yet encountered. It "expands" to meet the situation at hand.

A good general approach to defining a multidimensional array is:

<data type><space><variable name>[ ]...[ ] = new <data type>[<size dimension 1>]...[<size dimension n>];

The size values must be an integer greater than 0.

Notice that the above approach works well for fundamental data types. However, more is needed if the data type is a class description. Each cell in the array needs to have an object created for it. Otherwise, the cells only contain a null pointer. For instance: <variable name>[<index>] = new <data type>();

Accessing every cell in an array requires nested loops, the number of loops being equal to the number of dimensions. Any kind of loop will do. This concept is illustrated by the following figure:

Of course, it is also possible to access arrays using random indexes within the ranges of the various dimensions. You do not have to arrive at index values only by looping. Choose the method appropriate to the situation and the language. Recall that Java uses a 0-based indexing system (array indexes start with 0), whereas other languages use a 1-based system (array indexes start with 1). Keep that in mind as you proceed.

Review:


7c. Use enhanced for-loops to iterate over an arrays' elements

  • What are the types of loops that can be used to iterate over an array's elements?
  • Once an array of fundamental-type elements is defined, how can we tell how many elements are in it?
  • How is it possible to visit each array element without explicitly counting through their total range?
  • What are the various ways to initialize an array?

Once data is organized and we know how to access that data, we can move on to doing something useful with that data. As we have seen, one can use various types of loops to count through all the elements of an array. Or, we can access those elements randomly, or in some order appropriate to the application at hand. 

What application is that? Use your imagination. What are you trying to accomplish? What do you want this tool thing, this computer, to do for you? Set about developing your vision, objectives, tasks. Then begin carrying out those tasks to reach measurable milestones identified by your project schedule. Schedule, budget, and accountability are needed for accomplishment to take place. In this way, the computer, limited as it is, can be a very useful tool, a blackbox that can become what you need it to be, within the limits of its fundamental capabilities.

The lessons associated with this learning objective describe several fairly common activities that computers are asked to perform. They serve as examples for how to write code for similar activities in the Java language. In our review questions, we explore other activities that will interest you.

Review:

  • Common Array Algorithms: At least: 1, 2, 3, 4, 6, 12, 14, 22, 23, 24, 25. The rest are good examples.
  • ArrayLists and Iterators: These are all pretty important. Rarely is there a subunit having only examples. Especially pay attention to classes whose objects hold objects of other classes, and fundamental data types. 

Unit 7 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • arrays
  • cell
  • dimensions
  • element
  • index
  • matrix
  • ranges
  • vector

Unit 8: Java I/O and Exception Handling

8a. Describe the Java I/O package

  • What package does Java use to move data into and out from a computer program?
  • What are the three fundamental data streams?
  • How is it possible to read data as one type and store it as another type?
  • How does a programmer communicate with the console?

We have spent a lot of time talking about organizing and manipulating data within the computer. But, we have spent little time on how to get data into and out of the computer. Java's utility package contains all we need for that. For this learning outcome we concentrate on the three fundamental data streams: System.in (data input), System.out (data output), System.err (error reporting). The computer has no value unless it has a positive impact on human needs. Input/Output allows the computer to connect to the real world.

What is "data" within the physical reality of the computer? Data exists as units of eight bits, switches that are either on or off. These units are called bytes. Data is composed of groupings and interpretations of bytes. If one takes a group of bytes and interprets that group differently, it becomes a different data value, or data values. Yes, it is possible that a single data value can be turned into multiple values. Turning one fundamental value into another is called casting. For instance,  double thisDouble = (double)3; turns the integer value 3 into the double value 3.0. Although not the same as casting, it is possible to turn a character string into a sequence of fundamental data values.

Data input and output is a vast subject within any language, depending on the type of data and where it comes from. Let's begin our exploration with the keyboard and console, two very common I/O devices.

Review:


8b. Read and write data from/to an external file

  • Name various sources of data that can be input to a computer program.
  • Name various targets of data output from a computer program.
  • What are the various ways to open a file?
  • What is good practice regarding the closing of files?

We have input data from the keyboard and output data to the console. There are many other sources and targets. These include files of different kinds, and also network addresses. "Data" itself has to be understood in the most general terms. A huge consideration is how the data is to be interpreted. Much depends on the source and target, and any intervening applications along the way.

In this particular learning exercise, we concentrate on file input/output. However, the lessons learned here are applicable to other sources and targets, as you will see as you learn more.

Review:


8c. Use the Java I/O package to retrieve data for populating method parameters

  • How is the Scanner class used for both keyboard and file input?
  • Why is it important to be able to read data from permanent storage devices?
  • What is the difference between a text and binary file?
  • Which other classes can be used for file input?

There are two general ways of dealing with data, as it arrives and historically. For instance, an application in precision irrigation will be interested in the immediate ambient temperature. However, that same application will be interested in temperature trends. For that reason, the immediate temperature has to be combined with past temperature readings. Thus, the immediate temperature has to be stored somehow for later access. How to read stored data values is what we consider in this component of the course.

Java offers several ways to read stored data. Here we consider the Scanner class combined with the File class. Storing and reading data is a vast subject within Java. Scanner and File classes offer basic approaches that fit well with numerous requirements. Let's begin our exploration of Java files with those.

Review java.io.File and File Input: There are two short readings here. Both should be taken in detail.


8d. Explain error-handling via exceptions

  • Under which type of situations are exceptions useful?
  • What do exception handlers do? What do they prevent?
  • What is the difference between error-checking and exception-handling?
  • Is it possible for a programmer to define their own exceptions? If so, how?

It is not a matter of if but when things will go wrong in a computer program. I began my consulting career by approaching a potential customer to tell them that he had seen the source code to their main multi-user system and that they were sure to have multiple crashes, periods of time when their system would go down and would have to be restarted. They replied that such a thing was not possible, that their users did not know enough to accomplish that. After asserting that it was because their users did not know enough that the system would crash, given the software at hand, I waited a week. At the end of that week, the customer received another visit. They begged for help since their system was spending more time crashing/restarting than getting anything useful accomplished. The fix was to insert easily-accomplished exception-handling into the code. The job was done in one morning of work. Such is the importance of exception-handling.

Taken in the most general sense, "exception" refers to an event that is unacceptable to the situational domain covered by the program. Anything outside that domain is an "exception". For instance, if the user is asked to input a value between 1 and 10 inclusive, steps must be taken to account for values outside that range. Similarly, if a file is supposed to exist, it is an "exception" when that file does not exist, or if the file contains unexpected data. Do not think this means you have to deal with an infinity of specific error situations. Rather, think in terms of, "Is this an expected situation?" If it is not, then an exceptional situation exists and must be declared and dealt with in some way that allows the program to keep operating. Given the relatively narrow range of "acceptable", it is easy to identify the "unacceptable". Philosophically, the question is, "Is this situation within the domain of acceptability?" If it is not, then an exception exists.

Review Exceptions: When Things Go Wrong: 10.1, 10.2, 10.3


8e. Apply exception handling techniques

  • What are the two constructs for identifying and handling exceptional (error) situations?
  • How can programs be best designed for smoothly identifying and dealing with exceptional situations?
  • Can a programmer create their own Java exceptions? If so, how?
  • Explain exceptions thrown by the JVM.

if/else and try/catch are the two approaches we can use to identify and deal with situations that are outside a program's domain. try/catch is important since it will allow the program to cope with errors generated by the JVM. For instance, if the program attempts to open a file that does not exist, the JVM will throw an exception. If the program does not check for JVM-thrown exceptions during the file-open attempt, the program will crash upon exception. try/catch is like saying, "if-exception then an error preventing continuation has occurred". If the exception is not caught and properly handled, the program crashes.

Continuing with that thought, if the file is not found, what should happen? Should the program store all internal data, close all open files, and then exit? Should the program go into a quiescent mode and try again later? Should the program go off to do something else for a while? Should it ask for a different filename? That depends on what the program is supposed to accomplish and the system environment in which it exists. How you design your software is an important undertaking that will make all the difference in maintenance, expansion, and reliability.

Review Exceptions: When Things Go Wrong: 10.4, 10.5, 10.6, 10.7


Unit 8 Vocabulary

This vocabulary list includes the terms listed above that you will need to know to successfully complete the final exam.

  • casting
  • console
  • data
  • data streams
  • exception
  • exception-handling
  • File class
  • files
  • keyboard
  • Scanner class
  • utility package