Friday, December 24, 2010

When Apache web server
is starting up in FreeBSD system, Apache loads succcessfully and web server functioning properly, but the following warning error occurs:

[warn] (2)No such file or directory:
Failed to enable the ‘httpready’ Accept Filter

The resolution to the above problem is to a accf_http module, which function is to buffer incoming connections until a certain complete HTTP requests arrive, into FreeBSD kernel by using kernel linker:

I got everything set and working fine, im connecting to a vpn on the machine that nats the user to the external interface, the only thing i do not manage to solve is that i got multiple ips on my external interface

The only problem i got is that the vpn users randomly uses all the ips on that interface, one request can be with 84.16.247.166 and the next can be 188.72.222.18.

What im trying to do is that the vpn users only uses the 95.168.183.173 ip (its the default machine ip which all the other softwares also uses), how do i do that? I cant find anything about that in the nat section in pf nor in the openvpn config

===================================

Hello,

put

Code:local 95.168.183.173 in your openvpn.conf

Quote:
--local host
Local host name or IP address for bind. If specified, OpenVPN
will bind to this address only. If unspecified, OpenVPN will
bind to all interfaces.

---

If you want exactly to tell PF which is the external IP address for NAT you can set for example as follow:

Sunday, December 19, 2010

The True Story of Hello World

(or at least a good part of it)

Most of our computer science students have been through the
famous "Hello World" program at least once. When compared to a
typical application program ---almost always featuring a web-aware
graphical user interface, "Hello World" turns into an very
uninteresting fragment of code. Nevertheless, many computer science
students still didn't get the real story behind it. The goal of this
exercise is to cast some light in the subject by snooping in the
"Hello World" life-cycle.

The source code

Let's begin with Hello World's source code:

1.

2.

3.

4.

5.

6.

7.

#include <stdio.h>

int main(void)

{

printf("Hello World!\n");

return 0;

}

Line 1 instructs the compiler to include the declarations needed
to invoke the printf C library (libc) function.

Line 3 declares function main, which is believed to be our
program entry point (it is not, as we will see later). It is
declared as a function that takes no parameter (we disregard command
line arguments in this program) and returns an integer to the parent
process --- the shell, in our case. By the way, the shell
dictates a convention by which a child process must return an 8-bit
number representing it status: 0 for normal termination, 0
> n < 128 for process detected abnormal termination, andn > 128 for signal induced termination.

Line 4 through 8 comprise the definition of function main,
which invokes the printf C library function to output the
"Hello World!\n" string and returns 0 to the parent process.

Simple, very simple!

Compilation

Now let's take a look at the compilation process for "Hello
World". For the upcoming discussion, we'll take the widely-used GNU
compiler (gcc) and its associated tools (binutils). We
can compile the program as follows:

tells us hello.o is a relocatable object file, compiled for the
IA-32 architecture (I used a standard PC for this study), stored in
the Executable
and Linking Format (ELF), that contains a symbol table (not
stripped).

By the way,

# objdump -hrt hello.o

hello.o: file format elf32-i386

Sections:

Idx Name Size VMA LMA File off Algn

0 .text 00000011 00000000 00000000 00000034 2**2

CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE

1 .data 00000000 00000000 00000000 00000048 2**2

CONTENTS, ALLOC, LOAD, DATA

2 .bss 00000000 00000000 00000000 00000048 2**2

ALLOC

3 .rodata.str1.1 0000000d 00000000 00000000 00000048 2**0

CONTENTS, ALLOC, LOAD, READONLY, DATA

4 .comment 00000033 00000000 00000000 00000055 2**0

CONTENTS, READONLY

SYMBOL TABLE:

00000000 l df *ABS* 00000000 hello.c

00000000 l d .text 00000000

00000000 l d .data 00000000

00000000 l d .bss 00000000

00000000 l d .rodata.str1.1 00000000

00000000 l d .comment
00000000

00000000 g F .text 00000011 main

00000000 *UND* 00000000 puts

RELOCATION RECORDS FOR [.text]:

OFFSET TYPE VALUE

00000004 R_386_32 .rodata.str1.1

00000009 R_386_PC32 puts

tells us hello.o has 5 sections:

.text: that's "Hello World" compiled program,
i.e. IA-32 opcodes corresponding to the program. This will be used
by the program loader to initialize the process' code
segment.

.data: "Hello World" has neither initialized global
variables nor initialized static local variables, so this section
is empty. Otherwise, it would contain the variable initial values
to be loaded into the data segment.

.bss: "Hello World" also doesn't have any
non-initialized variable, either global or local, so this section
is also empty. Otherwise, it would indicate how many bytes must be
allocated and zeroed in the data segment in addition to
section .data.

.rodata: this segment contains the "Hello World!\n"
string, which is tagged read-only. Most operating systems do not
support a read-only data segment for processes (running
programs), so the contents of .rodata go either to the
process' code segment (because it's read-only), or to thedata segment (because it's data). Since the compiler
doesn't know the policy adopted by your OS, it creates this extra
ELF section.

.comment: this segment contains 33 bytes of comments
which cannot be tracked back to our program, since we didn't write
any comment. We'll soon see where it comes from.

It also shows us a symbol table with symbol main
bound to address 00000000 and symbol puts
undefined. Moreover, the relocation table tells us how to
relocate the references to external sections made in section.text. The first relocatable symbol corresponds to the "Hello
World!\n" string contained in section .rodata. The second
relocatable symbol, puts, designates a libc function
which was generated as a result of invoking printf. To better
understand the contents of hello.o, let's take a look at the
assembly code:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

# gcc -Os -S hello.c -o -

.file "hello.c"

.section .rodata.str1.1,"aMS",@progbits,1

.LC0:

.string "Hello World!"

.text

.align 2

.globl main

.type main,@function

main:

pushl %ebp

movl %esp, %ebp

pushl $.LC0

call puts

xorl %eax, %eax

leave

ret

.Lfe1:

.size n,.Lfe1-n

.ident "GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)"

From the assembly code, it becomes clear where the ELF section
flags come from. For instance, section .text is to be 32-bit
aligned (line 7). It also reveals where the .comment section
comes from (line 20). Since printf was called to print a
single string, and we requested our nice compiler to optimize the
generated code (-Os), puts was generated
instead. Unfortunately, we'll see later that our libc
implementation will render the compiler effort useless.

And what about the assembly code produced? No surprises here: a
simple call to function puts with the string addressed by.LC0 as argument.

Linking

Now let's take a look at the process of transforminghello.o into an executable. One might think the following
command would do:

# ld -o hello hello.o -lc

ld: warning: cannot find entry symbol _start; defaulting to 08048184

But what's that warning? Try running it!

Yes, it doesn't work. So let's go back to that warning: it tells
the linker couldn't find our program's entry point_start. But wasn't it main our entry point? To be
short here, main is the start point of a C program from the
programmer's perspective. In fact, before calling main, a process
has already executed a bulk of code to "clean up the room for
execution". We usually get this surrounding code transparently from
the compiler/OS provider.

Now we should have a real executable. Static linking was used for
two reasons: first, I don't want to go into the discussion of how
dynamic libraries work here; second, I'd like to show you how much
unnecessary code comes into "Hello World" due to the way libraries
(libc and libgcc) are implemented. Try the following:

# find hello.c hello.o hello -printf "%f\t%s\n"

hello.c 84

hello.o 788

hello 445506

You can also try "nm hello" or "objdump -d
hello" to get an idea of what got linked into the
executable.

Loading and running

In a POSIX OS, loading a program for execution is accomplished by
having the father process to invoke the fork system
call to replicates itself and having the just-created child
process to invoke the execve system call to load and start
the desired program. This procedure is carried out, for instance, by
the shell whenever you type an external command. You can
confirm this with truss or strace:

# strace -i hello > /dev/null

[????????] execve("./hello", ["hello"], [/* 46 vars */]) = 0

...

[08053d44] write(1, "Hello World!\n", 13) = 13

...

[0804e7ad] _exit(0) = ?

Besides the execve system call, the output shows the call
to write that results from puts, and the call toexit with the argument returned by function main
(0).

To understand the details behind the loading procedure carried
out by execve, let's take a look at our ELF executable:

The output shows the overall structure of hello. The firstprogram header corresponds to the process' code
segment, which will be loaded from file at offset 0x000000 into
a memory region that will be mapped into the process' address
space at address 0x08048000. The code segment will be 0x55dac
bytes large and must be page-aligned (0x1000). This segment will
comprise the .text and .rodata ELF segments discussed
earlier, plus additional segments generated during the linking
procedure. As expected, it's flagged read-only (R) and executable
(X), but not writable (W).

The second program header corresponds to the process'data segment. Loading this segment follows the same steps
mentioned above. However, note that the segment size is 0x01df4 on
file and 0x03240 in memory. This is due to the .bss section,
which is to be zeroed and therefore doesn't need to be present in
the file. The data segment will also be page-aligned (0x1000) and
will contain the .data and .bss ELF segments. It will
be flagged readable and writable (RW). The third program header
results from the linking procedure and is irrelevant for this
discussion.

If you have a proc file system, you can check this, as
long as you get "Hello World" to run long enough (hint: gdb),
with the following command:

# cat /proc/`ps -C hello -o pid=`/maps

08048000-0809e000 r-xp 00000000 03:06 479202 .../hello

0809e000-080a1000 rw-p 00055000 03:06 479202 .../hello

080a1000-080a3000 rwxp 00000000 00:00 0

bffff000-c0000000 rwxp 00000000 00:00 0

The first mapped region is the process' code segment, the
second and third build up the data segment (data + bss +
heap), and the fourth, which has no correspondent in the ELF
file, is the stack. Additional information about the runninghello process can be obtained with GNU time,ps, and /proc/pid/stat.

Terminating

When "Hello World" executes the return statement inmain function, it passes a parameter to the surrounding
functions discussed in section linking. One of these functions
invokes the exit system call passing by the return
argument. The exit system call hands over that value to theparent process, which is currently blocked on the wait
system call. Moreover, it conducts a clean process termination, with
resources being returned to the system. This procedure can be
partially traced with the following:

Closing

The intention of this exercise is to call attention of new
computer science students to the fact that a Java applet doesn't get
run by magic: there's a lot of system software behind even the
simplest program. If consider it useful and have any suggestion to
improve it, please e-mail
me.

FAQ

This section is dedicated to student's frequently asked questions.

What is "libgcc"? Why is included in linkage?

Internal compiler libs, such as libgcc, are used to implement language constructs not directly implemented by the target architecture. For instance, the module operator in C ("%") might not be mappable to a single assembly instruction on the target architecture. Instead of having the compiler to generate in-line code, a function call might be preferable (specially for memory limited machines such as microcontrollers). Many other primitives, including division, multiplication, string manipulation (e.g. memory copy) are typically implemented on such libraries.

[] HttpWatch or HttpWatchPro - is an integrated HTTP sniffer for IE and Firefox that provides new insights into how your website loads and performs. Change the way that you develop, debug and tune websites today!

[] FireBug - Firebug integrates with Firefox to put a wealth of web development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.

[] Web Developer Toolbar - The Web Developer extension adds various web developer tools to a browser. The extension is available for Firefox and Chrome, and will run on any platform that these browsers support including Windows, Mac OS X and Linux.

[] yslow (Yahoo! YSlow) - YSlow analyzes web pages and suggests ways to improve their performance based on a set of rules for high performance web pages. YSlow is a Firefox add-on integrated with the Firebug web development tool. YSlow grades web page based on one of three predefined ruleset or a user-defined ruleset. It offers suggestions for improving the page's performance, summarizes the page's components, displays statistics about the page, and provides tools for performance analysis, including Smush.it™ and JSLint.

and both have an onClick event handler. If the user clicks on element2 he causes
a click event in both element1 and element2. But which event fires first? Which event handler should
be executed first? What, in other words, is the event order?

Two models

Not surprisingly, back in the bad old days Netscape and Microsoft came to different conclusions.

Netscape said that the event on element1 takes place first. This is called
event capturing.

Microsoft maintained that the event on element2 takes precedence. This is called
event bubbling.

The two event orders are radically opposed. Explorer
only supports event bubbling. Mozilla, Opera 7 and Konqueror support both. Older Opera's and
iCab support neither.

You, the web developer, can choose whether to register an event handler in the capturing or
in the bubbling phase. This is done through the addEventListener()
method explained on the Advanced models page.
If its last argument is true the event handler is set for the capturing phase, if it isfalse the event handler is set for the bubbling phase.

The click event starts in the capturing phase. The event looks if any
ancestor element of element2 has a onclick event handler for the capturing
phase.

The event finds one on element1. doSomething2() is
executed.

The event travels down to the target itself, no more event handlers for the capturing
phase are found. The event moves to its bubbling phase and executes doSomething(),
which is registered to element2 for the bubbling phase.

The event travels upwards again and checks if any ancestor element of the
target has an event handler for the bubbling phase. This is not the case, so nothing happens.

The click event starts in the capturing phase. The event looks if any
ancestor element of element2 has a onclick event handler for the capturing
phase and doesn’t find any.

The event travels down to the target itself.
The event moves to its bubbling phase and executes doSomething(),
which is registered to element2 for the bubbling phase.

The event travels upwards again and checks if any ancestor element of the
target has an event handler for the bubbling phase.

The event finds one on element1. Now doSomething2() is executed.

Compatibility with traditional model

In the browsers that support the W3C DOM, a traditional event registration

element1.onclick = doSomething2;

is seen as a registration in the bubbling phase.

Use of event bubbling

Few web developers consciously use event capturing or bubbling. In Web pages as they are made
today, it is simply not necessary to let a bubbling event be handled by several different event handlers.
Users might get confused by several things happening after one mouse click, and usually you want
to keep your event handling scripts separated. When the user clicks on an element, something happens,
when he clicks on another element, something else happens.

Of course this might change in the future, and it’s good to have models available that
are forward compatible. But the main practical use of event capturing and bubbling today
is the registration of default functions.

It always happens

What you first need to understand is that event capturing or bubbling always happens.
If you define a general onclick event handler for your entire document

any click event on any element in the document will eventually bubble up to the document and
thus fire this general event handler.
Only when a previous event handling script explicitly orders the event to stop bubbling, it will not propagate to the
document.

Uses

Because any event ends up on the document, default event handlers become possible.
Suppose you have this page:

Now if the user clicks on element1 or 2, doSomething() is executed. You can
stop the event propagation here, if you wish. If you don’t the event bubbles up todefaultFunction().
If the user clicks anywhere else defaultFunction() is also executed. This might be
useful sometimes.

Setting document–wide event handlers is necessary in drag–and–drop
scripts. Typically a mousedown event on a layer selects this layer and makes
it respond to the mousemove event. Though themousedown is usually registered on the layer to avoid browser bugs, both
other event handlers must be document–wide.

Remember the First Law of Browserology: anything can happen, and it usually does when you’re
least prepared for it. So it may happen that the user moves his mouse very wildly and the
script doesn’t keep up so that the mouse is not over the layer any more.

If the onmousemove event handler is registered to the layer,
the layer doesn’t react to the mouse movement any more, causing confusion.

If the onmouseup event handler is registered on the layer,
this event isn’t caught either so that the layer keeps reacting to the mouse
movements even after the user thinks he dropped the layer. This causes even more confusion.

So in this case event bubbling is very useful because registering
your event handlers on document level makes sure they’re always executed.

Turning it off

But usually you want to turn all capturing and bubbling off to keep functions from
interfering with each other.
Besides, if your document structure is very complex (lots of nested tables and such) you may save system
resources by turning off bubbling. The browser has to go through every single ancestor element
of the event target to see if it has an event handler. Even if none are found, the search still takes time.

In the Microsoft model you must set the event’s cancelBubble property to true.

window.event.cancelBubble = true

In the W3C model you must call the event’s stopPropagation() method.

e.stopPropagation()

This stops all propagation of the event in the bubbling phase.
Stopping event propagation in the capturing phase is impossible. One wonders why.

Setting the cancelBubble property in browsers that don’t support it doesn’t hurt.
The browser shrugs and creates the property. Of course it doesn’t actually
cancel the bubbling, but the assignment itself is safe.

currentTarget

As we’ve seen earlier, an event has a target or srcElement that
contains a reference to the element the event happened on. In our example this is element2,
since the user clicked on it.

It is very important to understand that during the capturing and bubbling phases (if any)
this target does not change: it always remains a reference to element2.

But suppose we register these event handlers:

element1.onclick = doSomething;
element2.onclick = doSomething;

If the user clicks on element2 doSomething() is executed twice. But how
do you know which HTML element is currently handling the event? target/srcElement
don’t give a clue, they always refer to element2 since it is the original source of the
event.

To solve this problem W3C has added the currentTarget property. It contains a
reference to the HTML element the event is currently being handled by: exactly what we need.
Unfortunately the Microsoft model doesn’t contain a similar property.

You can also usethe this keyword.
In the example above it refers to the HTML element the event is handled on, just likecurrentTarget.

Problems of the Microsoft model

But when you use the Microsoft event registration model
the this keyword doesn’t refer to the HTML element. Combined with the
lack of a currentTarget–like property in the Microsoft model,
this means that if you do

you cannot know which HTML element currently handles the event. This is the most
serious problem with the Microsoft event registration model and for me it’s reason enough
never to use it, not even in IE/Win only applications.

I hope Microsoft will soon add a currentTarget–like property — or maybe
even follow the standard? Web developers need this information.

Continue

If you wish to go through all event pages in order, you should now continue with theMouse events page.

All the JavaScript code mentioned in this blog should be tried on firebug.

The super popular live method was added to jQuery 1.3 . It works just great. Except when it does not work. As per the documentation this method does not work in following cases: blur, focus, mouseenter, mouseleave, change, submit .

How binding events work in jQuery

$('a').click(function(){
console.log('clicked');
});

In above case ‘click’ event is bound to all the links in the ‘document’. jQuery stores such binding information as ‘data’ attribute of the bound element. This is how I can access the list of all functions bound to an element.

$('a').data('events');// Object click=Object

If a new link is dynamically added then that new link will not get this click behavior. Tosolve this problem I can use live method.

Trying out live event

$('a').live('click',function(){
console.log('clicked');
});

If I add a new ‘a’ tag dynamically then that tag will automatically get the new click behavior. That’s great.

Just like the previous section, now I am going to find the events bound to ‘a’ element. However when I execute following code I get undefined.

$('a').data('events')); //undefined

Why is that. In the previous section I showed that all the events bound to an element are stored as the data attribute of that element. Well, live is different. live events are not bound to the element directly. They are bound to the top level ‘document’. I can verify this by trying out this code

jQuery.data(document, 'events').live; //Object

How does live method work

live methods do not set anything on elements directly. All the event handlers are set at the document level. It means that in order for live methods to work, event bubbling is required. If you don’t know what event bubbling is then read here . It also means that event should not be stopped while it is propagating to document. If event propagation is stopped then event handlers bound at the document level will never know about that event and live method will fail.

The strategy to let someone else deal with the event is called ‘event delegation’. You can read more about event delegation here .

When live method is called then a binding is done at the document level. Loosely translated this is what is basically happening.

live does not work when event bubbling is not supported

In the previous section I showed that when event does not bubble up to document then live fails. It means that all the events that do not bubble will not work. Which means that events like blur, focus, mouseenter, mouseleave, change and submit which do bubble in IE will not work in IE. However note that these events will continue to work in Firefox.

If I click on ‘Java’ or ‘Javascript’ I will get proper response even though event propagation is being stopped. Also even though change event does not bubble in IE, above code works in IE.

livequery works because livequery ,unlike live, method does not do binding at the document level. livequery does binding at the element level. You can find that out by running following code.

$('p').data('events');

Above code will produce result if I am using livequery. Above code will not produce any result if I am using live method.

The key piece of code in the plugin that makes all this work is

// Create a timeout to check the queue and actually run the Live Queries
$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);

Every 20 milliseconds livequery runs all the bindings defined in livequery and then binds the matched element with the event.

By understanding the internals of how live and livequery are implemented, now you can choose to use livequery in certain cases where live will not work. Also it helps to understand how live actually works.

Live method finds elements and then throws it away. Not very efficient.

A typical use of live method is something like this.

$('p').live('click',function(e){
console.log('p was clicked');
});

As it has already been discussed a live method registers events at document level.

However when $(‘p’).live(…) is evaluated then jQuery first goes and finds all the ‘p’ elements. And then what does it do with those elements. Nothing. That’s right. jQuery throws away all those ‘p’ elements which were just found without using them. What a waste.

If your application has a lot of live methods and this might slow down the performance of the application.

A better solution would have been to design an API like this one:

$.live('p', 'click', function(){..});

jQuery is flexible and I can create my own live method but it will add to the confusion. Another solution would be to make the call to live method without first finding all those ‘p’ element. Here is how it can be done.

In the above case no element will be selected only to be thrown away. This is much better.

Seeing is believing

In the previous section, I showed how live method can be made to work without first selecting the elements. However a friend of mine asked me if I could conclusively prove that in the real live method a find is actually done. And in my solution a find call is not done.

Here I am showing you the overriding find method. In this method I am overriding the original find method. I will put a log message before passing the find method to the original method.

This is really a two-hour presentation I give to high school students, cut down to three minutes. And it all started one day on a plane, on my way to TED, seven years ago. And in the seat next to me was a high school student, a teenager, and she came from a really poor family. And she wanted to make something of her life. And she asked me a simple little question: she said, what leads to success? And I felt really badly, because I couldn't give her a good answer. So I get off the plane and I come to TED. And I think, geez, I'm in a middle of a room of successful people. So why don't I ask them what helped them succeed and pass it on to kids? So here we are, 7 years, 500 interviews later and I'm going to tell you what really leads to success.

The first thing is Passion. ( 擁有熱情 )Freeman Thomas says, "I'm driven by my passion". TED-sters do it for love, they don't do it for money. Carol Colleta says, "I would pay someone to do what I do". The interesting thing is, if you do it for love, the money comes anyway.

Work. ( 認真工作 )
Rupert Murdoch said to me, "It's all hard work. Nothing comes easily. But I have a lot of fun." Did he say fun?! Rupert? Yes, TED-sters do have fun working, and they work hard. I figure they're not workaholics (工作狂), they're workafrolics (工作玩家). [註: 演說者自創的字，是 work 與 frolic 的組合]

Serve! ( 為他人提供服務 )
Sherwin Nulan says, "It was a privilege to serve as a doctor. "Now a lot of kids tell me they want to be millionaires. And the first thing I say to them is, "OK, but you can't serve yourself. You got to serve others something of value. Because that's the way people really get rich".

Ideas. ( 富有創意的想法 )
Bill Gates says, "I had an idea: founding the first micro-computer software company." I'd say it was a pretty good idea. And there's no magic to creativity and coming up with ideas. It's just doing some very simple things. And I give lots of evidence.

Listen (聆聽)

Observe (觀察)

Be Curious (好奇心)

Ask Questions (時常發問)

Problem Solve (解決問題)

Make Connections (多多交流)

Persist. ( 無條件的堅持下去 )
Joe Kraus says, "Persistence is the number one reason for our success". You got to persist through failure (遭遇失敗), you got to persist through CRAP, which of course means: Criticism (被批評), Rejection (被拒絕), Assholes (被小人中傷) and Pressure (與壓力共處). [笑..]

So, the big end. The answer to this question is simple. Pay $4,000 and come to TED! Or failing that, do the 8 things -- and trust me, these are the big 8 things that lead to success.
Thank you TED-sters for all your interviews!

Tuesday, December 14, 2010

There is several ways in how to bind an event in Javascript. As far as I know four ways exist on behalf of binding a Javascript event. Here brief description of each way1. Through inline HTML Code

The Javascript event declared inline in HTML code, for example:
<input type=”button” value=”Alert Message” onclick=”showAlert()” />
Then showAlert() is a Javascript function that merely show an alert message:

function showAlert()
{
window.alert("Hello, World!!!");
}

This inline event binding works for all browsers.2. Traditional Binding

I think this way is more elegance than the first one, but before we can do this we must get the desired element. We can use two useful methods of document object to get the element we want, there is getElementById() and getElementsByTagName(). Both method receive one string parameter which show the ID of an element (for getElementById()) or elements name (for getElementsByTagName()). Please aware that the result of getElementsByTagName() is always array of element.

For simplicity I mix the HTML and Javascript code (although it maybe looks messy). The above code will produce a TextBox element and three <li> element. Hover the <li> element and click it will copy paste the nodeValue of <li> element to TextBox.

Traditional binding works well for all browser.3. W3C Binding

W3C binding works on browsers that comply with W3C standard. We need to remember one important method when attach event using W3C binding: addEventListener(). This method receives three parameters, first parameter is event name (such as: click, load, mouseout, etc.), second parameter is function that handle it, and third parameter is boolean values (true for event capturing or false for event bubbling).

Look at the following simple example on how to use addEventListener():

Run the code in W3C compliant browsers and hover the mouse cursor above an <li> element and you will see the background color of <li> element changed.4. IE Binding

As usual, Internet Explorer (IE) has its own way on binding an event. Remember this method when binding an event using IE binding: attachEvent(). This methods receives two parameters, first parameter is event precede with ‘on’ word (such as: onclick, onload, onmouseout), the second parameter is function that handle it.

If we want do the same thing (hover and out mouse effect) in IE way we can do with this code:

We must notice that this keyword inside a event handler function in IE point to window object not the current element, so we need a little more effort to achieve our goal. It something looks like this:

function liMouseOver()

{

var e = window.event;

var elm = e.srcElement;

elm.style.backgroundColor = "gainsboro";

}

Run the code in the browser and we should get the same result as before.

Legend

Year

= Year of Publication

Jolt **

= Jolt Winner

Jolt *

= Jolt Productivity Award

sum

= Number of reviews on Amazon

avg

= Average rating on Amazon

Scope of this List

For this Top 100 list I have included only books covering subjects found in the Software Engineering Body of Knowledge (SWEBOK). This means that I have left out books with main topics such as web design, computer science, business management and system administration. The main reason for this is that I had to limit the scope (or I would never be able to finish it).

I also excluded all books that dealt with specific technologies, such as Java, .NET, Ruby and PHP. I was only interested in the potentially timeless software engineering classics. In my opinion, technology books do not fall into that category. I did include books on project management (as project management is one of the competences in SWEBOK) but only when those books explicitly dealt with managing software development. (That's why there is no generic PMP-related material on the list.)

Finding the Books

To find all these potentially timeless classics, I checked the best-selling books in these five Amazon categories:

After I found all best-selling software engineering books, I subsequently found many other books through the "Customers Who Bought This Item Also Bought" cross-reference feature. And that's how I finally ended up with a list of 250 books.

Note: in case of multiple editions of the same book, only the most recent edition is listed on the chart, though reviews and ratings were combined for all available editions.

Doing the Calculations

When it was time to do the calculations, I checked the number of customer reviews on Amazon, and I ranked the books according to these numbers (= a measure of quantity). I also calculated the average Amazon ratings, and I ranked the books according to these ratings (= a measure of quality). I then checked the number of Google hits for each of the books, and I ranked them accordingly (= a measure of popularity). Finally, I took the three rankings, added extra points for all winners of Jolt awards, and then re-calculated it into a final ranking. This resulted in the list you now have before you.

Note: this little project was performed in the first week of June, 2008. Current Amazon reviews and ratings might have changed since then.

I admit that the system I used has no scientific basis. Nevertheless, I think the results are quite interesting, and I'm sure the list can be of great help if you want to broaden your knowledge of the field of software engineering, in all its exciting dimensions. I suggest you start with number 1, and then slowly work your way down. It shouldn't take you more than a couple of years…

Comments

Let's walk down the list and see what entries are worth pointing out...

First of all, it is obvious that Steve McConnell is the biggest hero among software engineers. (Well, at least among the reading part of the software engineering population...) Steve has no less than four entries on the list: Rapid Development (#3), Software Estimation (#14), Software Project Survival Guide (#47), and of course the Best Software Engineering Book Ever... Code Complete (#1). Congratulations to Steve for this stellar achievement!
There's only one other author with four entries on the Top 100 list. It's Martin Fowler, with Refactoring (#10), Patterns of Enterprise Application Architecture (#17), UML Distilled (#30) and Analysis Patterns (#83). And next in line is Alistair Cockburn, with three titles: Writing Effective Use Cases (#12), Agile Software Development (#22) and Crystal Clear (#46). It seems you cannot go wrong reading just about any of the books these guys are delivering!
After creating the top 100 list, one thing that immediately grabbed my attention was the #2 position for Head First Design Patterns, by Elisabeth Freeman, etc. The book ended two notches higher than the original (and more famous) Design Patterns (#4) by the Gang of Four (Erick Gamma, etc.) Several people had already informed me that Freeman's book is actually more readable than the classic one by the GoF. And now the Top 100 list seems to indicate that this is indeed the general public opinion. Freeman's book has a higher average rating on Amazon, and it was a Jolt Winner on top of that.
The best agile software development book is Agile Software Development: Principles, Patterns and Practices (#6), by Robert C. Martin. There are no less than 20 books on agile software development on the Top 100 list. It's obvious that no other topic has been so hot as the "agile" meme in the last decennium.
I would like to mention that I had a tough time deciding whether or not Mastering Regular Expressions (#18), by Jeffrey Friedl, actually belonged on the Top 100 list. I told you before that the list is about software engineering topics, and not about specific technologies. However, the book simply kept popping up in numerous searches and references. And I considered that regular expressions are actually not a technology but an (interpreted or compiled) technique or notation, just like UML, and useful for any software engineer, regardless of the type of application. So I relented, and Jeffrey got his #18 slot on the list.
For books with different editions I simply added the reviews and ratings for each edition, and used the last edition as the only Top 100 entry. Scott Berkun, the author of Making Things Happen (#35) was lucky that I knew that the previous edition of his book had a different name: The Art of Project Management. He wouldn't have ended so high if I had not been able to catch that essential piece of information.
One book that deserves a special treatment is Dreaming in Code (#52), by Scott Rosenberg. It was released in 2007 (first edition) and it has already scored Amazon 59 reviews.
And another newcomer that's worth point out is Manage It! (#67), by Johanna Rothman. Johanna's relatively new book still had only seven reviews on Amazon (at the time of calculation), but she scored a perfect 5.0 rating, and she added a Jolt award on top of that! Her book is the highest on the list with such a small crowd of enthusiastic supporters, and an almost perfect score for quality.
Speaking of Jolt awards, the top 7 books on the list all have received such an award. The highest entry on the list that did not receive a Jolt award is Peopleware (#8), by Tom DeMarco and Timothy Lister. The book is one of the highest rated books ever, and I'm sure that the Jolt jury regrets not having awarded Tom and Tim for their little (but visionary) masterpiece.
At the other side of the scale we find The Unified Modeling Language User Guide (#56), by Grady Booch. Of all the books on the Top 100 list, this one has the lowest average Amazon rating (3.30). But it is compensated by a large number of reviews (81) and a huge number of Google hits. It's a nice example of a book having popularity winning over quality.
Last of all, I think there's no better way of ending this post than including a reference to Hacker's Delight (#100), by Henry S. Warren. It seems like a nice book to close the list at the bottom. I had never heard of the book myself, but seeing that it has a perfect Amazon rating of 5.0 I'm sure that it's worth checking out.
Happy reading!
p.s. If you want to receive a nicely formatted Word-document of the list, you may email the author about it!This article was originally published as a blog post at http://www.noop.nl/. The original post will not be kept up-to-date. All future updates will be made in this Knol.