basic question on reference counting + virtual^redefining

Given

class C : public B

Q: i have a variable holding a C object , how do i get a variable of type B, connected to the same object?
A: simple assignment will do, but sliced!

Here’s the call to C constructor

C obj;

Using pointers — B* ptr = &obj;
Using references — B& ref = obj;

Q: Can 2 non-ref variables refer to the same object in memory?
A: I don’t think so. You need the address. nonrefs don’t know how to use addresses.
A: I guess it’s similar to java primitives. No way to create 2 int variables connected to the same int object
A: I feel the slicing problem occurs when you copy objects, but what about when you have just one object but multiple pointers?

Now we are ready to differentiate virtual vs redefining. Building on our example, say B has a public method m(), redefined in C. What is ptr->m() or ref.m()?

* difference — virtual is C::m() ^ redefinition is B::m(),
* difference — virtual is runtime binding ^ redefinition is compile time binding

Now a note on java. Java has only overloading (compile time binding) vs overriding ie virtual. C++ offers virtual ^ overloading ^ redefining. Last 2 are compile time binding.

ptr + virtual -} C // B ptr to a C object, to call a virtual method m()
ref + virtual -} C
nonref + virtual -} B
ptr + redefine -} B
ref + redefine -} B

In summary, only ptr/ref + virtual is really virtual. Not virtual if you use a nonref OR if you drop “virtual” keyword.

Destructors behave just like methods —
ptr + virtual -} C
ptr + non-virtual -> B. See P104 [[NittyGritty]]

Advertisements

%%tech strengths for fin IT jobs

— ranked
java + c# + c++
perl, unix — still widely used in financial but not many people know in-depth
SQL — outer join, self-join, sub-query and other complex joins, case expressions, group-by. See the t-sql book.

# eor
index design and utilization — banks heavy usage
milestoning pitfalls, limitations — banks heavy usage
refactor
complex data analysis using SQL — banks use it all the time.
query plan

make an autosys job start/stop@fixed days

Sometimes you might need to have a job start RUNNING at a fixed time (per Caldendar Cal1), and become success at a fixed time (per Calendar Cal2).

For now, let’s not dispute the requirement. (You might have a job that should not start in the window.)

Here’s a solution:
* Box b1 starts RUNNING per Cal1
* child file watcher w1 starts RUNNING right away
* a top-level job creates the file as per Cal2 => w1 becomes success.

Hibernate basic 2-table join — nested scan implemented in java

Zhu Rong,

To my dismay, hibernate (a popular,stable,fast java ORM framework) implements a 2 table join with individual SELECT’s on the inner table. As you explained, it’s more efficient to join inside the database?

Here’s my experiment. Hibernate supports a basic many-to-one mapping. Student object/table joining Course object/table. if i load 22 Student objects, hibernate uses lazy loading to delay querying the Course table until necessary. When it does query Course, it uses CourseId (join column, but not necessarily a PK or FK) to select just one Course. If 22 students are in 11 courses, hibernates runs 11 queries!

sleep() ^ yield() ^ wait()

Feature 1: does the thread let go of CPU@@
Feature 2: does the thread release lock@@
Feature 3: which real-world thread is affected? current call stack or another thread in an argument?
Feature 3a: is any Thread object explicitly mentioned? as arg or host object?
Feature 4: What objects are involved?

myObj.wait() is most complex:
1) yes
2) exactly 1 and only 1 lock (myObj), even if the thread holds multiple locks
3) current thread only
3a) none.
4) an object to serve as the waiting room

sleep() is simple:
1) yes
2) no, even if holding n locks
3) current thread only
3a) none. this is a static method.
4) No object involved. Thread.sleep() is a static method

yield() is similar to sleep()
4) No object involved. Thread.yield() is a static method
3) current thread only
2) no, even if holding n locks
1) yes

RAII mutex needed — no guaranteed unlock at thread death

(See other posts on thread death)

Update: RAII mutex introduces data inconsistency and is not always a good thing.

Mutex is shared by multiple stacks so can’t live on stack, but in a special semaphore memory area. According to [[OO MT using c++]], some semaphores (mutex locks) are shared among PROCESSES, so must live outside the address space of any process. When a process (or thread) dies, it could die owning the semaphore, blocking other processes indefinitely.

Because mutex release is manual, not by default, you should consider RAII, such as boost scoped_lock. See other posts on RAII mutex.

http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/topic/apis/concep26.htm says

If a thread is the owner of one or more exclusive write locks acquired by pthread_rwlock_wrlock(), pthread_rwlock_trywrlock(), or pthread_rwlock_timedwrlock_np(), when that thread terminates, the exclusive write locks are not automatically released by the system. This is an error in the application and indicates that the data associated with the lock is in an inconsistent state. If another thread attempts to get a shared read or exclusive write lock on the lock, that thread blocks forever.

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html echos

“When a thread terminates, the mutex does not unless explicitly unlocked. Nothing happens by default.”

[[c++ cookbook]] echos “If an operating system thread is killed, it will not release its locks…”

##RAII (mutex + eg) — briefly

Resource Release Is Finalization is arguably the more relevant part of RAII.

The “resource” in question is often a shared resource, but not shared simultaneously. It has to be acquired and released. Such resources include
* locks
* files
* DB connections
* heap objects (via pointers)

— exemplifications
java synchronized keyword
java finally() to close DB connection
std::auto_ptr
boost::scoped_ptr
boost::mutex::scoped_lock

simple race condition illustration

Simplest eg: consider 2 threads both running counter++ on a shared variable.You expect counter to increment twice but it may increment once.

Key factor: the operation is not an (so-called atomic) one-stepper. counter++ is a “load-and-store”. It’s not *atomic*. Between the steps, another thread can change the shared variable.

For a bigger example, consider a web page hit counter.