Instance: It refers to the Oracle process that accesses the database. An instance works on the database but first it has to mount it. An instance can mount atmost one database but a database can be mounted by multiple instances.
Database: It refers to the set of files where the metadata and the application data is stored. This is the operational data.
SID: An SID identifies an instance.
The Exists clause:
The exists clause is used to check for the existence of rows in the subquery. Based on whether the rows exist, the outer query would be executed. If the subquery does not return any rows then the outer query would not be executed.
- select 1 from table t2; => This would return as many rows as there are in the table "t2" . If we have the following query:
select count(*) from table t1 where exists (select 1 from table t2); => The result would be the row count of the table t1 if there t2 is not empty and has some rows.
- select count(*) from table t1 where exists (select 1 from table t2 where t1.id = t2.id); => This is an example of a corelated subquery.
An interesting question:
Suppose there is a table "Emp(id, salary)" and you need to return the top 3 employees w.r.t salary. You could do this:
select * from (select * from Emp E order by salary desc) where rownum < 4;
A subquery involves nesting however when the column from an relation (table) in an outer query is also used in an enveloped query then the queries become correlated.
What can be achieved by a correlated query can sometimes not be achievable by simply using joins or nested queries.
For instance: in the Supplier-Parts database from CJ Date’s Intro to DBMS, the following is an example of a correlated query:
Find all the supplier name for suppliers that supply part "P2":
select SNAME from S
where ‘P2′ IN
(select P# from SP
where S.S# = SP.S#)
Note: The outer query is executed once every time the inner query returns a result.
The clone method is a protected method in class Object. Therefore object.clone() is visible to only its subclasses which is every class in the Java hierarchy.
Also note that there is a marker interface: Cloneable; which specifies if the instances of the classes implementing this interface can be cloned or not => if the clone method can be invoked on them.
What is a shallow copy/clone of an object:
A shallow copy comes into play if the object to be cloned references other objects. The shallow copy will reference the same objects and not copies of them. If the object to be cloned referenced primitives or immutable objects then the cloning behavior provided by invoking Object.clone() in a derived class would lead to a deep copy/cloning.
A shallow copy means that the copy object itself is different, but if the original object referenced other objects, the copy will reference those same objects, and not a copy of them.
How does it work:
The subclass needs to override the Object.clone() by providing a public clone() method. Also, the marker Cloneable interface also needs to be implemented. The first call in the overridden clone method should be super.clone() and that ultimately travels up to Object.clone().
The object.clone() does a byte by byte (or whatever the word size is) copy of the classes in the hierarchy. This leads to shallow cloning for reference types since the references are copied into the newly cloned instance. It would be a good idea for the overriding clone method in the derived classes to provide for any deeper cloning if necessary.
Why use a copy constructor if clone is present:
Final fields in a class cannot be set to a value once the clone has been created therefore a copy constructor might be needed.
Difference between notify and notifyAll
NotifyAll wakes up all the threads that are waiting on the specified object lock. Please note that it might be necessary to use notifyAll instead of notify in cases when a specific or a specific subset out of a set of threads need to be notified. For instance: in a producer – consumer scenario, the producer should use notifyAll to wake up all the consumers out of which only one would be able to utilize the product that the producer has available. The producer might have 2 quantities of products available for consumption and there might be consumers that require more than 2 and so just using notify might wake up those and there would be no progress.
Also note that notify will not relenquish the lock like wait does. Notify will only relenquish the lock once the synchronized section is exited. The thread invoking notify might continue to run although the thread that is waiting has been notified and is now in a RUNNABLE state ready to acquire the lock.
Note that the round-robin scheduling might appear to be fair but it is not in the following case (in case of a single CPU machine):
- Intermediate results from a calculation are not required – all that is required are the final results. For instance, if there are 5 threads started to do a calculation that provides a result in 5 seconds, then no matter what kind of time slicing is done, the average time for producing the final result is equal to or more than the average time in a non-timesliced version.
On the other hand, if intermediate results are required then the round-robin (timesliced) scheduling is the fairest. It the timeslice is 1 second, then the average time for each thread to produce an answer would be (1+2+3+4+5)/5 = 3 seconds. On the other hand, for a non-timesliced version, the average would be (1+6+11+16+21)/5 = 11 seconds.
For a multiple CPU machine, it gets complicated.
If intermediate results are not required (on a 4 CPU machine), we have:
- Average for a non-timesliced version = (5+5+5+5+10)/5 = 6 secs.
- Average for a timesliced version = (5+5+5+7+8)/5 = 6 secs (for a timeslice of 2 secs)
If intermediate results are required:
- Average for a non-timesliced version would be (1+1+1+1+6)/5 = 2 secs
- Average for a timesliced version would be (1+1+1+1+2)/5 = 1.2 secs (for a timeslice of 1 sec)
Note that for intermediate results, the timesliced version of scheduling is the most fairest.
Depend upon abstraction. Code to interfaces and not to concrete implementations.
This is similar to the OO principle: "program to an interface and not to an implementation". However, the DIP makes an even stronger statement about abstraction. It means any component (high or low level) within an application should depend upon abstractions. A high level component is one whose behavior is defined in terms of other lower level components.
The following guidelines help in avoiding OO designs that violate the DIP:
- No variable should hold a reference to a concrete class. Do not use new, use factories.
- Do not derive from concrete classes. Derive from abstract or interfaces. If your are deriving from concrete classes then there is a dependence on the concrete class.
- Do not override base class methods. Those concrete methods in the base class are meant to be shared between all the derived classes.
Inverson of control:
This generic term is also synonymous with Dependency Injection.
The assembler injects the dependency and reduces tight coupling between classes.
Driver: The visitor family allows separation of concerns and allows functionality (basically one or more methods) to be added to a hierarchy of classes without modifying anything in the hierarchy.
For instance: in the visitor pattern, the visitable classes would just define a single method (accept) in the simplest case and within that a ploymorphic call would be made to the passed in Visitor instance’s visit() method.
OCP principal: (the Open Closed Principle): The visitor family allows changing the behavior of existing classes (for instance, in the case of the Visitor Pattern, these classes are termed as Visitable) without updating the existing codebase.
The main patterns of interest in this family are:
The Visitor Pattern:
There is a dual dispatch happening wherein the first dispatch is to invoke the correct accept method in case there are more than one.
The second dispatch is to invoke the correct visit() method on the Visitor instance.
One of the main benefits of the visitor pattern is that it is extremely fast as it involves only two polymorphic dispatches.
The Decorator Pattern:
This one is different from visitor although they are members of the same family of patterns – the Visitor family. It is primarily different ’cause it does not require the interface of the Visitable to be updated with the addition of the accept() method. There are no dual dispatches.
This pattern is also called the toolkit pattern since new tools (new behavior) can be acquired at run time => the application therefore can be termed to be using new tools.
The SRP principle (Single Responsibility Principle) underlines the separation of concerns in a good design. This implies, in a decorator context, that a class (such as one representing the entity: CAR) should not burden itself with a characteristic (such as the alloy wheels) that is not intrinsic to its behavior. In the case of the preceding example of a CAR, the decorator can implement the interface of the CAR and delegate all calls to the CAR instance but "decorate" the one for getPrice() by taking into account the presence of alloy wheels and adding that to the base price and thereafter delegating to the CAR instance.
Have been studying on Generics in Java and have evaluated the following:
- Thinking in Java has a comprehensive chapter on Generics although towards the end, I found some inaccuracies.
- The Generics tutorial linked from Java Docs is thorough but for someone who is hitting Generics aka templates in C++ for the first time, I would recommend starting with "Thinking in Java".
- Any doubts that you might have can be quickly cast aside by checking out the immensely useful site: http://angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html
Hopefully some of you might find this information useful.