Computer Science: Arguments and Parameters
Often used interchangeably (and often confused).
Parameters are used in the definition of a function or method signature. They are the range of values and types that a function can take.
Arguments are the values that a function takes when being called or invoked.
Original Source of Confusion
From: https://chortle.ccsu.edu/java5/Notes/chap34A/ch34A_3.html - I think the point of confusion arises from the following original terminology:
Formal Parameter — the identifier used in a method to stand for the value that is passed into the method by a caller.
- For example,
amountis a Formal Parameter of some generic methodprocessDeposit
- For example,
Actual Parameter — the actual value that is passed into the method by a caller.
- For example, the
200used whenprocessDepositis called is an Actual Parameterr. - Actual Parameters are often called Arguments
- For example, the
Computer Science: Transient Objects
It's often useful to have "temporary", in-memory objects, that aren't persisted or saved to a database.
Such Transient Objects can be Fields, used in Serializing/Deserializing, validation, etc.
Transient Fields
// Java
@Entity
public class Person {
@Transient
private String temporaryNote;
}
Note that in Java, the @Transient annotation and keyword transient accomplish much of the same. Fields and their values are ignored and/or replaced with another value.
If one both implements Serializable and uses the transient keyword in Java, default values are created, persisted, and the original values are stored in a separate file. (This was often used for PII since it separates sensitive data into two parts that have to be reassembled.)
// Java
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private transient Address address;
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject();
oos.writeObject(address.getHouseNumber());
}
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
ois.defaultReadObject();
Integer houseNumber = (Integer) ois.readObject();
//...
this.setAddress(a);
}
//...
}
# Ruby
class MyModel < ActiveRecord::Base
attribute :small_int, :integer, limit: 2
end
Data Transfer Objects
Plain Old Java Objects or some other intermediary object (say in Ruby) can be used to then Get and pass data into the relevant domain entity (Hibernate or ActiveRecord, above).
Resources and Links
Computer Science: Pointers
Variables are typically a compound with a name, a declaration keyword, some value setting symbol, and a value.
int myVar = 1;
Pointers point to a Variable’s address / reference in memory.
One can think of a Pointer as a reference to a value in memory or as a memory address.
int *numAddress = & myVar;
Dereferencing the Pointer / address to get the value back.
int derefNum = *numAddress;
myVar == derefNum; // True
Computer Science: Processes and Threads
A Process typically corresponds to a Program. (Many programs use multiple Processes that intercommunicate through Inter-Process Communication (IPC) - Electron.js.)
Processes are often run in an unmanaged way ("fire and forget", running silently in the background).
A Process usually has multiple Threads.
Threads have their own Stack and don't necessarily Synchronize their activities. Threads are often managed by the same Program (running, composing, starting, stopping, execution, intercommunication). They can interact in somewhat unpredictable ways, in total isolation, or be Synchronized using:
synchronized- Mutual Exclusion Locks (Mutex)
- Semaphors
- Atomic Types that are inherently thread-safe and Synchronized.
To illustrate this relationship further:
- Consider explicitly creating a Thread or Runnable object in Java or
Exec forkin JavaScript: the Process spawns another Thread. - One Process, multiple Threads.
One finer point that’s sometimes forgotten: the Node engine is Single-Threaded and so, one Process is one Thread (under normal circumstances). So,
Exec fork,spawn, andChild execwill all create new Single-Threaded Processes.
Computer Science: Heap vs Stack
Objects stored in Heap memory are persisted across all Threads.
Objects stored in Stack memory are available through the execution of a method or function (typically the scope of a function).
It's convenient to think of a Stack as a "local" Heap.
Objects can be stored:
- In the Heap
- In the Stack without being persisted to the Heap
- In both
In C++, Stack memory is automatically managed by the Garbage Collector, and Heap memory requires explicit calls (to say persist something in memory across the lifespan of a specific function).
Computer Science: Hexadecimal Numbers
Fully general algorithm.
// JavaScript
// 0-9
// A-F represent 10-15
const NUMS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
const decimalToHexadecimal = (num, remainders = []) => {
if (num < 0) {
// Specific to num < 0
// A trick to convert negative decimals to hex
num = num + Math.pow(2, 32)
}
const r = num % 16
const d = Math.floor(num / 16)
remainders.push(NUMS[r])
if (d < 1) return remainders.reverse().join("")
return decimalToHexadecimal(d, remainders)
}
const hexToDecimal = hex => {
let num = 0
// Any hexadecimal that begins with 8-F is negative
if (NUMS.indexOf(hex.charAt(0)) >= 8) num -= Math.pow(2, 32)
let order = hex.length
for (let i = 0; i < hex.length; i++) {
order--;
var n = NUMS.indexOf(hex.charAt(i));
num += n * Math.pow(16, order);
}
return num;
}
Int to Hex
Int to Hex.
Hex to Binary in JS:
// JavaScript
var hexToBinaryMap = {
"0": "0000",
"1": "0001",
"2": "0010",
"3": "0011",
"4": "0100",
"5": "0101",
"6": "0110",
"7": "0111",
"8": "1000",
"9": "1001",
"a": "1010",
"b": "1011",
"c": "1100",
"d": "1101",
"e": "1110",
"f": "1111"
}
function intToHex(num) {
var hex = parseInt(num, 10).toString(16);
if (hex == "0") hex = "0000";
return hex;
}
function hexTo16BitBinary(hexString) {
var l = hexString.length, innerString = "", result = "";
for (var i = 0; i < l; i++) {
innerString += hexToBinaryMap[hexString.charAt(i)];
}
return innerString;
}
Computer Science: Signed and Unsigned Numbers
Signed numbers can be positive, negative, or zero (The Naturals, full Reals).
Unsigned can’t (Positive Ordinals, etc.).
Important Terminology
Radix – number of unique digits used to represent a number
- 16 bit binary – base 2 (radix 2) since it uses 2 numbers in the base.
- Hexadecimal is radix 16 since it uses base 16
Base – the number system (2, 10, decimal, etc.).
- Refer to Log notes above.
- Implicitly base 10 or 2 otherwise.
Mantissa – Two meanings:
- The Significand (IEEE 754 double-precision 52-bit or 53-bit with hidden bit Significand) and the numbers following a decimal (
x.yyyyyyy). - The first sense defines the number of bits that are used to represent the significant numbers (including a sign or not) that are multiple against some power value (e.g. – [the binary representation of]
12345 x 10-5). - The second sense expresses the intent of the first operation.
- The Significand (IEEE 754 double-precision 52-bit or 53-bit with hidden bit Significand) and the numbers following a decimal (
Computer Science: Bitwise Operators
Convert to Binary - convert some Number to the Binary representation of that same Number:
// Java int x = 1000; Integer.toBinaryString(x);// JavaScript const x = 1000; const xx = x.toString(2);~- Bitwise Not (negation, complementation) - inverts the value of every Binary String index:0if1and vice-versa.4is0100(Base 10 to Binary)~0100 = 1011System.out.println(Integer.toBinaryString(~4)); // 1011
&- Bitwise And - compares every Binary String index and returns1if both characters are1otherwise0.5is0101(Base 10 to Binary)0100 & 0101 = 0100System.out.println(Integer.toBinaryString(4 & 5)); // 0100
|- Bitwise Or - compares every Binary String index and returns1if at least one character is1otherwise0.0100 | 0101 = 0101System.out.println(Integer.toBinaryString(4 | 5)); // 0101
^- Bitwise Xor ("Exclusive Or")- compares every Binary String index and return1if exactly one character is1otherwise0.0100 ^ 0101 = 0001System.out.println(Integer.toBinaryString(4 ^ 5)); // 0001
<<- Bitwise Left Shift (unsigned) - increases the length of the Binary String by the shift value, right-fills with0.1 << 3 = 1000System.out.println(Integer.toBinaryString(1 << 3)); // 1000
>>- Bitwise Right Shift (unsigned) - shifts a Binary String to the right by the shift value, fills with0if there's empty space0001 >> 3 = 0000- Alternatively:
0001 >> 3 = 0 System.out.println(Integer.toBinaryString(0001 >> 3)); // 0000
Note that Java will truncate the leading leftmost
0.
Resources and Links
Computer Science: Object Oriented Design Principles
General concepts and principles of Object Oriented Design (OOD).
Types and Classes
- The term
Typeoriginates from a long line of math, logic, and philosophy that culminated in ZFC Set Theory and Rammified Type Theory in the early 20th century. - ZFC Set Theory formalizes the prior notion of a Class as a specific kind of well-ordered and -behaving Set (fixing the bugs in Fregean, Cantorian, and Russellian systems).
- Rammified Type Theory formalizes the prior notion of a Class as a hierarchy of Types.
- Classes are abstract patterns or templates that are instantiated into or as particular Objects (per Plato).
Modern programming languages often include a mixture of Classes, Types, and/or Sets.
Below, Class and Type will mostly be used interchangeably (and while these align with the mathematical concept of a Set, Set will be strictly reserved the Data Structure Type).
Parent,Ancestor,Supertype, andSuperclasswill also be used interchangeably.Child,Descendant,Subtype, andSubclasswill be used interchangeably as well.
OOD Principles
- Encapsulation:
- Boundaries exist (Getters and Setters, Dot Notation, field access, Ruby's
@,attr_accessor) between Classes and particular Objects. - Visibility (Java's
public,protected,package, andprivate) can be controlled.
- Boundaries exist (Getters and Setters, Dot Notation, field access, Ruby's
- Aggregation:
- Class definitions can be nested.
- Classes can exist as Inner or Outer Classes.
- Inheritance:
- Classes exist in hierarchies and features of top-level Classes are present in their Descendants.
- Generics in Java.
- Multiple Inheritance and Multiple Inheritance Conflict Resolution in Python.
- Polymorphism:
- A Class can implement multiple Interfaces (Java).
- Generally, a Class needn't be singly-Typed (can be Typed in multiple ways without necessarily requires Multiple Inheritance).
- Abstraction:
- Where a Class is a Parent of another.
- Where some Superclass is used to reason about or define permissible Subclasses.
- A Class can implement an Interface (which defines Methods only up to their Signature) and must have the stipulated Functions or Methods present (Java and GoLang's Interfaces).
- A Class can be Abstract which requires it to be Subclassed to be Instantiated (if the language supports such a concept).
- In Java, an Abstract Class can define Fields with initialized Values and fully defined Methods.
SOLID
- Service Responsibility Principle:
- Class definitions and Types should be scoped to specific functionality or role.
- Even with good OOD, one might be tempted to
importa single Class everywhere (or at least in multiple places). - Despite say proper Visibility and Encapsulation controls, developers might then misuse functionalities or import unintended Variables or Methods.
- This aligns with proper Separation of Concerns as a guiding principle. Resources should be defined only up to and isolated by their intended functionality (rather than sloppily blurring or intermixing intentions, intended uses, or meanings).
- Open and Closed:
- Types should be extensible (extendable, subclassable).
- But Subclasses shouldn't modify their Parent or Super Classes.
- Accessing Properties, the Constructor, Fields, and/or Methods of a Parent requires some explicit and verbose keyword or operation (
super,super()). Even still in doing so, the Ancestor definition does not alter the Superclass definition (itself).
- Liskov Substitution Principle:
- If
Pis a property of a TypeAandBis a Subtype ofA, thenPis a property ofB. - Properties, Methods, and Fields of a Parent will be automatically inherited by (implicitly or explicitly present in the defintion of) their Subtypes.
- If
- Interface Segmentation:
- Types shouldn't unnecessarily implement (or be an implementation of unnecessary) Interfaces.
- Types also shouldn't unnecessarily inherit from unneeded Superclasses.
- Dependency Inversion Principle:
- Unidrectional Top to Bottom dependency chain.
- More abstract Types don't depend on their less abstract Subtypes.
- Liskov Substitution could be a symmetric principle. In tandem with the Dependency Inversion Principle, inheritance of Properties, Methods, and so on become one directional.
Java
Consult this article for a discussion on Java-specific OOD principles, concepts, and code examples.
Go
Consult this article for a discussion on GoLang-specific OOD principles, concepts, and code examples.
Ruby
Consult this article for a discussion on Ruby-specific OOD principles, concepts, and code examples.
Python
Consult this article for a discussion on Python-specific OOD principles, concepts, and code examples.