Static/Dynamic vs Strong/Weak

Simply put it this way: in a statically typed language the type is static, meaning once you set a variable to a type, you CANNOT change it. That is because typing is associated with the variable rather than the value it refers to.

Java is a statically-typed language. The types of all variables are known at compile time (before the program runs), and the compiler can therefore deduce the types of all expressions as well. If a and b are declared as ints, then the compiler concludes that a+b is also an int. The Eclipse environment does this while you’re writing the code, in fact, so you find out about many errors while you’re still typing.

Whereas in a dynamically typed language the type is dynamic, meaning after you set a variable to a type, you CAN change it. That is because typing is associated with the value rather than the variable. In dynamically-typed languages like Python, this kind of checking is deferred until runtime (while the program is running).

For example in Python:

str = "Hello" # it is a string
str = 5 # now it is an integer; perfectly OK

On the other hand, the strong/weak typing in a language is related to implicit type conversions (partly taken from @Dario’s answer):

For example in Python:

str = 5 + "hello"
# would throw an error since it does not want to cast one type to the other implicitly.

Static Checking, Dynamic Checking, No Checking

It’s useful to think about three kinds of automatic checking that a language can provide:

Static checking: the bug is found automatically before the program even runs.

Dynamic checking: the bug is found automatically when the code is executed.

No checking: the language doesn’t help you find the error at all. You have to watch for it yourself, or end up with wrong answers.

Needless to say, catching a bug statically is better than catching it dynamically, and catching it dynamically is better than not catching it at all.

Here are some rules of thumb for what errors you can expect to be caught at each of these times.

Static checking can catch:

syntax errors, like extra punctuation or spurious words. Even dynamically-typed languages like Python do this kind of static checking. If you have an indentation error in your Python program, you’ll find out before the program starts running.

wrong names, like Math.sine(2). (The right name is sin.)

wrong number of arguments, like Math.sin(30, 20).

wrong argument types, like Math.sin("30").

wrong return types, like return "30"; from a function that’s declared to return an int.

Dynamic checking can catch:

illegal argument values. For example, the integer expression x/y is only erroneous when y is actually zero; otherwise it works. So in this expression, divide-by-zero is not a static error, but a dynamic error.

unrepresentable return values, i.e., when the specific return value can’t be represented in the type.

out-of-range indexes, e.g., using a negative or too-large index on a string.

calling a method on a null object reference (null is like Python None).

Static checking tends to be about types, errors that are independent of the specific value that a variable has. A type is a set of values. Static typing guarantees that a variable will have some value from that set, but we don’t know until runtime exactly which value it has. So if the error would be caused only by certain values, like divide-by-zero or index-out-of-range then the compiler won’t raise a static error about it. Tends to fail for every value.

Dynamic checking, by contrast, tends to be about errors caused by specific values.

Surprise: Primitive Types Are Not True Numbers

One trap in Java – and many other programming languages – is that its primitive numeric types have corner cases that do not behave like the integers and real numbers we’re used to. As a result, some errors that really should be dynamically checked are not checked at all. Here are the traps:

Integer division. 5/2 does not return a fraction, it returns a truncated integer. So this is an example of where what we might have hoped would be a dynamic error (because a fraction isn’t representable as an integer) frequently produces the wrong answer instead. No checking – wrong answer.

Integer overflow. The int and long types are actually finite sets of integers, with maximum and minimum values. What happens when you do a computation whose answer is too positive or too negative to fit in that finite range? The computation quietly overflows (wraps around), and returns an integer from somewhere in the legal range but not the right answer.

Special values in floating-point types. Floating-point types like double have several special values that aren’t real numbers: NaN (which stands for “Not a Number”), POSITIVE_INFINITY, and NEGATIVE_INFINITY. So when you apply certain operations to a double that you’d expect to produce dynamic errors, like dividing by zero or taking the square root of a negative number, you will get one of these special values instead. If you keep computing with it, you’ll end up with a bad final answer.

Autoboxing and Unboxing

The Java compiler applies autoboxing when a primitive value is:

Passed as a parameter to a method that expects an object of the corresponding wrapper class.

Assigned to a variable of the corresponding wrapper class.The Java compiler applies unboxing when an object of a wrapper class is:

Passed as a parameter to a method that expects a value of the corresponding primitive type.

Switch Statement

Each case of switch is supposed to be an integer or String since Java 7, a condition returns a boolean so that results in an incompatible type. Consider the strings to be similar to labels, compared as if String.equals were being used. Switch / case statements do not allow conditionals, but how about this beautiful and minimalist approach? Worth looking into.

age >79? first_case_method(): age <50? second_case_method(): age <40? third_case_method(): age <30? fourth_case_method(): age <20? fifth_case_method():...: default_case_method();

Interfaces and Polymorphism

An interface is akin to an agreement/contract for a class, if a class implements an interface it is agreeing to implement all the methods specified in the interface definition. Interfaces can contain abstract methods and fields, but typically contain no implementation code. All methods in an interface need to be implemented in the class which implements the interface else the class will not compile. Interface fields are treated the same as static variables in the class.

Interfaces can extend multiple other interfaces, and inherits all fields and methods of the super interfaces, which could also be overridden in the base interface. The class implementing the interface needs to implement all methods.

Since Java 8, provision has been made for default methods to alleviate the problem of developers adding to an API and existing classes no longer implementing all required methods. A class can override the default implementation. If a class implements multiple interfaces with matching default methods, complications arise.

Classes cannot extend multiple super classes owing to the Deadly Diamond of Death, however they can implement multiple interfaces.If a class implements multiple interfaces, there is a chance that method signatures may overlap (same name and parameters), which is not permitted in java.

Interfaces enable you to treat an object by the role it plays rather than by the class type from which it was instantiated. Once a class implements an interface you can use an instance of that class as an instance of that interface. Variables can be declared to be of the interface type. If several objects implement an interface, then interface types can be used instead of class types in parameter declarations. This provides flexibility.

Generally polymorphism is the provision of a single interface to different types. It can be used at different levels, for example overloading methods so that they behave differently depending on the argument to which they are applied. There can also be polymorphic data types, when a data type appears to be of a generalised type, specifically generics in Java.

Interfaces are a way to achieve polymorphism, it enables methods to be accessed by several classes, for example if you want one method to store various objects (from different class hierarchies) in a database, implement an interface called Storable. When each class implements these methods, then they can be called to store the objects in a database without considering which particular type of object they are, all they need to be is Storable.

Equality

The equals method is defined in class Object, and since all objects in Java implicitly or explicitly inherit from this class, they too will inherit the equals() method as implemented by Object. The default implementation in Object will simply return true if the objects pass the “==” condition.

However, you are free to override the equals() method in your own class and specify the criteria which must be checked to see if two objects are meaningfully equal. For example, you might say that two instances are only equal if each of its attributes contain the same values as another object, or you might instead want to simply check a few attributes which make up the objects “business key” and ignore the others.

The equality of String classes follow the same rules as any other class in Java; “==” will be true if they do refer to the same instance, and equals() will be true if they contain the same values.

Nested Classes

Nested classes enable you to logically group classes that are only used in one place, increasing the use of encapsulation. Nested classes include local classes (introduce a new named type), anonymous classes (don’t need to refer to it, e.g. inline ActionListeners for menus), lambda expression, inner class (similar to local class but more widely available and don’t need access to local context). Event handlers are a common use of inner classes. https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

InnerClass cannot have static members because it belongs to an instance (of OuterClass). If you declare InnerClass as static to detach it from the instance, your code will compile.

classOuterClass{staticclassInnerClass{staticint i =100;// no compile errorstaticvoid f(){}// no compile error}}

BTW: You’ll still be able to create instances of InnerClass. static in this context allows that to happen without an enclosing instance of OuterClass.

You can use the same modifiers for inner classes that you use for other members of the outer class. For example, you can use the access specifiers private, public, and protected to restrict access to inner classes, just as you use them to restrict access do to other class members. But you can’t use access modifiers when declaring a class within a method.

Primitives and Objects

Objects : defined in a class, instantiated, constructed and assigned to an identifier. The have state, behaviour and identity. They are stored on the heap.

Data types : Primitive types are special data types built into the language; they are not objects created from a class. Primitives are stored on the stack.

Literal : A Literal is the source code representation of a fixed value; literals are represented directly in your code without requiring computation. A literal can be a value of a primitive type [like 1, true, 't'or 1.2f], the String type [like "" or Something], or the null type [null].

boolean result =true; // boolean- is data type
// true- is literal

Control Flow Structures

break terminates the loop (jumps to the code below it). continue terminates the rest of the processing of the code within the loop for the current iteration, but continues the loop.

More Info / Reading List

Availability, along with confidentiality and integrity form the CIA triad. Availability implies reliable and timely access to a desired resource. A denial of service attack (DOS) can be launched from a single source or more recently distributed among a range of sources (DDOS). It is a form of attack where the intention is to exhaust the target’s resources by flooding it with requests such that it is rendered unavailable resulting in a denial of service to legitimate users. Distributed attacks are coordinated by a command system of handlers which the bots/agents are in contact with. Together the bots are often referred to as a botnet. When synchronised these attacks can bring down web services of large organisations as can be seen in the cases of Yahoo, Amazon, eBay, CNN and several (Abliz, 2011).

These attacks are on the increase, continually growing more sophisticated and are potentially devastating for businesses reliant on Internet services. There are several types of DOS attacks which correspond with the layers of the Open System Interconnection (OSI) model. Some attacks target a specific protocol or layer and are outlined below. (Elleithy, et al., 2005) Some attacks exploit known vulnerabilities, aiming for a few requests to consume excessive resources and others rely on flooding and brute force using a large volume of requests.

DOS agents are designed around attacking a specific target, it could be a particular application on a host, an end system, router, link, network or a particular infrastructure. As such they operate at different protocols dependent on the target, and the OSI layers which are implemented by the specific target. The Internet Protocol (IP) is a best-effort packet switching protocol which is connectionless, i.e. it doesn’t maintain a connection and resends packets as required. The transport layer provides end-to-end communication services for application supported by the Transmission Control Protocol(TCP) and the User Datagram Protocol (UDP). (Abliz, 2011) DOS attacks include Ping-of-Death, UDP flood, TCP SYN flood, Ping Flood, IP TTL Expiry attack.

Internet Control Message Protocol (ICMP) is an error reporting protocol used by network devices to report errors to the source IP address. Ping operates by sending ICMP Echo Request packets to the targets and waits for a reply. The Ping-of-Death attacks send oversized ICMP packets. A Ping Flood involves sending ICMP packets at a high rate .

The TTL Expiry attack consists of sending IP packets with a Time To Live (TTL) set to expire at the targeted router. When the network device detects that the TTL is 0, the packet is discarded and sends an ICMP message to the sender. When receiving a large volume of expiring packets, the CPU uses significant resources processing these packets and sending replies.

SYN, SYN-ACK Flood

The TCP 3-way handshake initiates with the client sending a TCP SYN (synchronise) packet to a server. The server receives the SYN, allocates some resources and sends a SYN acknowledgement (SYN-ACK). When the client receives this SYN-ACK, it sends an acknowledgement back and when the server receives the ACK, the socket connection is established.

The SYN flood works as follows, when establishing a TCP connection a client initiates a session by sending a SYN packet with an invalid return address. The host acknowledges receipt of the request by generating a SYN-ACK packet and assigns resources required by the anticipated connection. If the connection is never completed, the resources are held, resulting in a diminishing pool of available resources for other connections. (http://techmightsolutions.blogspot.co.uk/2013/05/syn-flood-attack-using-scapy.html)

It is possible to simulate such an attack on a small scale. Then measure the ability of a web server to deliver web pages while such an attack is on going.

Paessler

Given that this project includes benchmarking different configurations, it would be useful to have a script which explores and reports on the system configuration. We can then run this script prior to the benchmark to ensure that we have an accurate record of the system we are testing.

Most of this information is freely available in the /proc directory which is present on all Linux systems. It is a virtual file system, including files such as meminfo, cpuinfo and numbered directories representing processes. In any process directory you can explore the status, io, etc. using cat <filename>.

We could implement a bash script which could monitor system performance for a given time, save the output to a log file and then analyse the data afterwards. Initially considering recording memory, disk and cpu usage, I’ve implemented this script and found that the values reported for CPU usage do not match the raspberry pi cpu usage monitor displayed on the panel. http://www.systeen.com/2016/05/07/bash-script-monitor-cpu-memory-disk-usage-linux/

# memory - display the free and used memory in megabytes
# using awk extract the data from the second line
free -m | awk 'NR==2{printf "%.2f%%\t\t", $3*100/$2}'
# execute top for 1 iteration
# grep the line containing load
# use awk to extract the second last entry on the line
top -bn1 | grep load | awk '{printf "%.2f%%\t\t", $(NF-2)}'
# disk file usage in human readable format
#using awk extract the 5th field from the line containing /
df -h | awk '$NF=="/"{printf "%s\t\t, $5}'

Wrap this with a while loop to take readings at specific time intervals.

Log Files

Apache2 provides an access and an error log in the /var/log/apache2/ directory. access.log contains all details of requests processed by the server including the IP address the request originated from, timestamp and user agent. All messages and errors from the server are stored in error.log. For example

AH00558: apache2: Could not reliably determine the server's
fully qualified domain name, using 127.0.1.1. Set the
'ServerName' directive globally to suppress this message

Virtual Hosts

As soon as you want to host multiple sites from the server, then it is necessary to work with the configuration files. Apache2 loads configuration data from individual files as an alternative to editing a long configuration file which may introduce errors.

Virtual Network Computing (VNC) is a widely used remote technology, particularly in heterogenous networks. For this reason, several open source VNC projects exist, including RealVNC and TightVNC. VNC enables one to control a number of different computers from one keyboard. It is different to a remote terminal session such as SSH as you do not log in to a server. Anything you do on the VNC session is as if done by the user currently logged into the remote desktop.

VNC requires a client and server to create a session. The server runs on the remote desktop and open a vncviewer on the client. VNC estalishes remote access over either a local arean network or over the internet using TCP/IP, implementing a Remote Frame Buffer (RFB) which grabs the screen image and sends it to the client. The client displays the remote screen in a window on the client desktop. The client transmits mouse and keyboard data back to the server.

VNC creates stateless sessions, enabling the user to disconnect and reconnect from different machines irrespective of which operating system is installed on the client or server.

Security

However RFB does not travel over a normal connection in an encrypted mode. Consider using OpenSSH and use VNC through an encrypted tunnel.

Raspberry Pi Specifics

The first time you run a VNC server it will prompt for a system password. The server will appear as hostname:1, hostname:2 etc. The server chooses the first available display number and tells you what it is. Setting the DISPLAY environment variable can cause applications to use a specified display.

RealVNC

As of September 2016, RealVNC software is available for free for academic and non-commercial use on Raspberry Pi’s. Note that only one VNC server can be installed at one time. So if you have installed tightVNC previously, you will need to remove it.