chapters 12-15, theory done
This commit is contained in:
parent
d68be1ed2f
commit
8bc5728d9f
|
|
@ -0,0 +1,84 @@
|
|||
# 12. C++
|
||||
|
||||
## Classes and inheritance
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
// Base class
|
||||
class Shape {
|
||||
public:
|
||||
void setWidth(int w) {
|
||||
width = w;
|
||||
}
|
||||
void setHeight(int h) {
|
||||
height = h;
|
||||
}
|
||||
protected:
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
// Derived class
|
||||
class Rectangle: public Shape {
|
||||
public:
|
||||
int getArea() {
|
||||
return (width * height);
|
||||
}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
Rectangle Rect;
|
||||
Rect.setWidth(5);
|
||||
Rect.setHeight(7);
|
||||
|
||||
// Print the area of the object.
|
||||
cout << "Total area: " << Rect.getArea() << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Constructors and destructors
|
||||
|
||||
```cpp
|
||||
// constructor
|
||||
Person(int w, h) {
|
||||
height = h;
|
||||
width = w;
|
||||
}
|
||||
|
||||
// destructor
|
||||
~Person() {
|
||||
delete height;
|
||||
delete width;
|
||||
}
|
||||
```
|
||||
|
||||
## Virtual functions
|
||||
|
||||
Setting a parent class function in the children class, inheritance.
|
||||
|
||||
## Pointers and reference
|
||||
|
||||
```cpp
|
||||
// pointers
|
||||
int* p = new int;
|
||||
*p = 7;
|
||||
int* q = p;
|
||||
*q = 8
|
||||
cout << *q; // prints 8
|
||||
|
||||
// references
|
||||
int a = 5;
|
||||
int& b = a;
|
||||
b = 7;
|
||||
cout << a; // prints 7
|
||||
|
||||
// pointer arithmetic
|
||||
int* p = new int[2];
|
||||
p[0] = 0;
|
||||
p[1] = 1;
|
||||
p++;
|
||||
cout << *p; // prints 1
|
||||
```
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# 13. Java
|
||||
|
||||
## Overloading vs. overriding
|
||||
|
||||
* Overloading: two methods have the same name, but differ in the type or number of alignments.
|
||||
* Overriding: a method shares the same name and function signature as another method in its super class
|
||||
|
||||
## Collection framework
|
||||
|
||||
* ArrayList: dynamically resizing array, growing as you insert elements
|
||||
* Vector: similar to ArrayList, but synchronized
|
||||
* LinkedList
|
||||
* HashMap
|
||||
|
||||
```java
|
||||
ArrayList<String> myArr = new ArrayList<String>();
|
||||
myArr.add("one");
|
||||
myArr.add("two");
|
||||
System.out.println(myArr.get(0));
|
||||
|
||||
Vector<String> myVec = new Vector<String>();
|
||||
myVec.add("one");
|
||||
myVec.add("two");
|
||||
System.out.println(myVec.get(0));
|
||||
|
||||
LinkedList<String> myLinkedList = new LinkedList<String>();
|
||||
myLinkedList.add("two");
|
||||
myLinkedList.addFirst("one");
|
||||
Iterator<String> iter = myLinkedList.iterator();
|
||||
while (iter.hasNext()) {
|
||||
System.out.println(iter.next());
|
||||
}
|
||||
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
map.put("one", "uno");
|
||||
map.put("two", "dos");
|
||||
System.out.println(map.get("one"));
|
||||
```
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# 14.1. Multiple apartments
|
||||
|
||||
> Write a SQL query to get a list of tenants who are renting more than one apartment
|
||||
|
||||
| Apartments | |
|
||||
|-|-|
|
||||
| AptID | int |
|
||||
| UnitNumber | varchar(10) |
|
||||
| BuildingID | int |
|
||||
|
||||
| Buildings | |
|
||||
|-|-|
|
||||
| BuildingID | int |
|
||||
| ComplexID | int |
|
||||
| BuildingName | varchar(100) |
|
||||
| Address | varchar(500) |
|
||||
|
||||
| Requests | |
|
||||
|-|-|
|
||||
| RequestID | int |
|
||||
| Status | varchar(100) |
|
||||
| AptID | int |
|
||||
| Description | varchar(500) |
|
||||
|
||||
| Complexes | |
|
||||
|-|-|
|
||||
| ComplexID | int |
|
||||
| ComplexName | varchar(100) |
|
||||
|
||||
| AptTenants | |
|
||||
|-|-|
|
||||
| TenantID | int |
|
||||
| AptId | int |
|
||||
|
||||
| Tenants | |
|
||||
|-|-|
|
||||
| TenantID | int |
|
||||
| TenantName | varchar(100) |
|
||||
|
||||
```sql
|
||||
SELECT TenantName FROM Tenants
|
||||
INNER JOIN (SELECT TenantID FROM AptTenants GROUP BY TenantID HAVING count(*) > 1) C
|
||||
ON Tenants.TenantID == C.TenantID
|
||||
```
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# 14. Databases
|
||||
|
||||
```sql
|
||||
SELECT CourseName, TeacherName FROM Courses, Teachers WHERE Courses.TeacherID = Teachers.TeacherID
|
||||
```
|
||||
|
||||
Normalized databases are designed to minimize redundancy, while denormalized databases are designed to optimize read time. We can denormalize the databases by storing redundant data and avoid doing many joins.
|
||||
|
||||
As an example, we have this database. * indicates a primary key.
|
||||
|
||||
```sql
|
||||
Courses: CourseID*, CourseName, TeacherID
|
||||
Teachers: TeacherID*, TeacherName
|
||||
Students: StudentID*, StudentName
|
||||
StudentCourses: CourseID*, StudentID*
|
||||
```
|
||||
|
||||
### Query 1: student enrollment
|
||||
|
||||
> Get a list of all students and how many courses each student is enrolled in
|
||||
|
||||
```sql
|
||||
SELECT StudentName, Students.StudentID, count(StudentCourses.CourseID) as [Cnt]
|
||||
FROM Students LEFT JOIN StudentCourses
|
||||
ON Students.StudentID = StudentCourses.StudentID
|
||||
GROUP BY Students.StudentID, Students.StudentName
|
||||
```
|
||||
|
||||
For reasons and incorrect implementations and their justification, see chaper 14 in book.
|
||||
|
||||
### Query 2: Teacher class size
|
||||
|
||||
> Get a list of all teachers and how many students they teach. If a teacher teaches the same student in two courses, double count the student. Sort the list in descending order of the number of students a teacher teaches
|
||||
|
||||
```sql
|
||||
SELECT TeacherName, isnull(StudentSize.Number, 0)
|
||||
FROM Teachers LEFT JOIN
|
||||
(SELECT TeacherID, count(StudentCourses.CourseID) AS [Number]
|
||||
FROM Courses INNER JOIN StudentCourses
|
||||
ON Courses.CourseID = StudentCourses.CourseID
|
||||
GROUP BY Courses.TeacherID) StudentSize
|
||||
ON Teachers.TeacherID = StudentSize.TeacherID
|
||||
ORDER BY StudentSize.Number DESC
|
||||
```
|
||||
|
||||
## Small database design
|
||||
|
||||
How to design a small database
|
||||
|
||||
1. Handle ambiguity: understand exactly what you need to design, consult with the interviewer
|
||||
2. Define the core objects: typically each core object translates into a table
|
||||
3. Analyze relationships: how tables are connected to each other
|
||||
4. Investigate actions: walk through the common actions that will be taken and understand how to store and retrieve the relevant data.
|
||||
|
||||
## Large database design
|
||||
|
||||
When designing a large, scalable database, joins are generally very slow. You must *denormalize* your data. Duplicate the relevant data in many tables.
|
||||
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
# 15. Threads and locks
|
||||
|
||||
## Threads in Java
|
||||
|
||||
Every thread in Java is created and controlled by a unique object of the Java.lang.Thread class. When a standalone application is run, a user thread is automatically created to execute the `main()` method. This thread is called the main thread.
|
||||
|
||||
In Java, we can implement threads in two ways:
|
||||
|
||||
1. By implementing the java.lang.Runnable interface
|
||||
2. By extending the java.lang.Thread class
|
||||
|
||||
### Implementing the runnable interface
|
||||
|
||||
```java
|
||||
public interface Rnunable {
|
||||
void run();
|
||||
}
|
||||
```
|
||||
|
||||
1. Create a class which implements the Runnable interface. An object of this class is a Runnable object.
|
||||
2. Create an object of type Thread by passing a Runnable object as argument to the Thread constructor. The Thread object now has a Runnable object that implements the run() method.
|
||||
3. The start() method is invoked on the Thread object created in the previosu step.
|
||||
|
||||
```java
|
||||
public class RunnableThreadExample implements Runnable {
|
||||
public int count = 0;
|
||||
|
||||
public void run() {
|
||||
System.out.println("RunnableThread starting");
|
||||
try {
|
||||
while (count < 5) {
|
||||
Thread.sleep(500);
|
||||
count++;
|
||||
}
|
||||
} catch (InterruptedException exc) {
|
||||
System.out.println("RunnableThread interrupted");
|
||||
}
|
||||
System.out.println("RunnableThread terminating");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
RunnableThreadExample instance = new RunnableThreadExample();
|
||||
Thread thread = new Thread(instance);
|
||||
thread.start();
|
||||
|
||||
/* wait until above thread counts to 5 */
|
||||
while (instance.count != 5) {
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch {InterruptedException exc} {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Extending the thread class
|
||||
|
||||
Or, we can override the run() method of the Thread class.
|
||||
|
||||
```java
|
||||
public class ThreadExample extends Thread {
|
||||
int count = 0;
|
||||
|
||||
public void run() {
|
||||
System.out.println("Thread starting");
|
||||
try {
|
||||
while (count < 5) {
|
||||
Thread.sleep(500);
|
||||
System.out.println("In Thread, count is " + count);
|
||||
count++;
|
||||
}
|
||||
} catch (InterruptedException exc) {
|
||||
System.out.println("Thread interrupted");
|
||||
}
|
||||
System.out.println("Thread terminating");
|
||||
}
|
||||
}
|
||||
|
||||
public class ExampleB {
|
||||
public static void main(String args[]) {
|
||||
ThreadExample instance = new ThreadExample();
|
||||
instance.start();
|
||||
|
||||
while (instance.count != 5) {
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Synchronization and locks
|
||||
|
||||
Threads within a given process share ths ame memory space. It enables threads to share data, but it can create issues when the two threads modify a resource at the same time.
|
||||
|
||||
With the `synchronized` keyword, it can be applied to methods and code blocks, and it restricts multiple threads from executing the code simultaneously on the *same object*.
|
||||
|
||||
For more granular control, we can use a lock, which is used to synchronize access to a shared resource by associating the resource with the lock. A thread gets access to a shared resource by first acquiring the lock associated with the resource. At any given time, at most one thread can hold the lock and therefore, only one thread can access the shared resource.
|
||||
|
||||
## Deadlocks and deadlock prevention
|
||||
|
||||
In a deadlock situation, a thread is waiting for an object lock that another thread holds, and this second thread is waiting the an object lock that the first thread holds. In order for a deadlock to occur, all the following conditions must meet:
|
||||
|
||||
1. Mutual exclusion: only one process can access a resource at a given time
|
||||
2. Hold and wait: processes already holding a resource can request additional resources, without relinquishing their current resources
|
||||
3. No preemption: One process cannot forcibly remove another process' resource
|
||||
4. Circular wait: 2+ processes from a circular chain where each process is waiting on another resource in the chain.
|
||||
|
||||
Deadlock prevention entails removing any of the above conditions.
|
||||
Loading…
Reference in New Issue