Tomer Gabel's annoying spot on the 'net RSS 2.0
# Wednesday, 11 March 2009

So I had to find myself a new job. Delver was about close down, the employees (including yours truly) were handed notices and the next few weeks were spent searching for my next job. I guess breaks come not only when you least expect them but also from the least likely direction: Delver was bought by Sears and made into SHC Israel, not to mention the company’s first overseas headquarters and development center.

38_sears_holdings

You’ve read correctly: Sears. Not Amazon, not Google, not Microsoft. Delver, a strictly web-based startup, wasn’t acquired by a web company; not even by a technology company at that. Instead we were acquired by one of the United States’ largest retailers. Why, you ask? Well, with any luck you’ll find out in a few months :-)

Wednesday, 11 March 2009 17:34:35 (Jerusalem Standard Time, UTC+02:00)  #    -
Personal

I was making modifications to one of our components, and running all of the unit tests revealed that all database-dependant integration tests were failing:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 0 ms ago.
<snip> (cut for brevity’s sake)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2104)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:729)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)

Strange error message, but as it turns out the inner exception was far more revealing:

java.net.ConnectException: Connection refused: connect

As can be expected, the local MySQL server was up and running, and I was able to connect with the command line tool as well as with SQLYog, so it was obviously not a problem with MySQL or the local firewall. Next up I tried to telnet to the appropriate port (the easiest way I know to check port-level connectivity) without success:

Can't connect to localhost

I next tried to connect to the loopback IP (127.0.0.1), and experienced a major WTF moment when the connection succeeded. I use Windows Server 2008 and, as it turns out, it supports IPv6 out of the box. localhost has a slightly different meaning under IPv6 (it maps to ::1), and as I understand it traditional IPv4 traffic is tunneled over the looback IPv6 connection; I’m not yet familiar enough with IPv6 to draw any conclusions on why the above shouldn’t work, but the bottom line is there are several ways of resolving the problem:

  1. Edit your hosts file (it’s hidden under Windows Server 2008, but you should be able to Start->Run->notepad %SYSTEMROOT%\System32\Drivers\etc\hosts) and change the mapping for localhost from “::1 localhost” to “127.0.0.1 localhost”. This does resolve the problem, although I can’t say what impact this will have on IPv6-enabled applications.
  2. Set the TCP stack to prefer IPv4 to IPv6 when attempting to connect (it’s the reverse by default). According to this forum post, this entails setting the registry value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters\DisabledComponents to the DWORD value 0x20.
  3. Disable IPv6 altogether for your network connection: remove the IPv6 protocol from your network connection component list. At this point in time IPv6 is still very rare so I doubt this will cause any significant issues, but YMMV.

For me, changing the hosts file was the quickest solution because it works and is easy to revert. I’ll have to keep a very careful eye on the behavior of my machine though.

Wednesday, 11 March 2009 13:02:08 (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Software
# Monday, 02 February 2009

If you've ever tried to develop using PHP on IIS7 (Vista), you'll find that errors in your script result in the default IIS7 "friendly" HTTP 500 error page, which is useless for debugging. This happens in both FastCGI and ISAPI modes.

To save you hours of crawling through the 'net, the solution (found on this forum post) is very simple:

  • Start a command prompt;
  • Copy-paste the following: %windir%\system32\inetsrv\appcmd.exe set config -Section:system.webServer/httpErrors -errorMode:Detailed
  • Run iireset
  • Enjoy.
Monday, 02 February 2009 19:58:44 (Jerusalem Standard Time, UTC+02:00)  #    -
Development
# Sunday, 25 January 2009

Unfortunately the startup I work for (Delver) did not survive the current market crisis and has failed to secure additional funding. As a result I’m on the market again, and am looking for senior developer and/or software team lead positions, especially those with relocation opportunities. My résumé can be found here, and the most recent version can always be found under Navigation on the right side of this website.

Have an interesting job offer? Get in touch!

Sunday, 25 January 2009 18:07:16 (Jerusalem Standard Time, UTC+02:00)  #    -
Personal
# Sunday, 18 January 2009

Update: I was wrong, and private setters do not appear to work (strange, I’m sure I verified this in my test code, but it didn’t work in practice). See below.

It’s been ages since I used XmlSerializer, or even written meaningful amounts of code in C# for that matter, which is why I was utterly stumped by this problem. Try running this code:

[XmlRoot( "test" )]
public class Test
{
    private readonly string _string1;
    private readonly string _string2;

    public Test( string string1, string string2 )
    {
        _string1 = string1;
        _string2 = string2;
    }

    [XmlAttribute( "attr" )]
    public string String1 { get { return _string1; } }

    [XmlElement( "element" )]
    public string String2 { get { return _string2; } }
}
/// ... XmlSerializer xs = new XmlSerializer( typeof( Test ), "" ); XmlSerializerNamespaces xsn = new XmlSerializerNamespaces(); xsn.Add("", ""); // Gets rid of redundant xmlns: attributes StringWriter pw = new StringWriter(); xs.Serialize( pw, new Test( "1", "2" ), xsn ); Console.WriteLine( pw.GetStringBuilder().ToString() );
You’ll get an InvalidOperationException stating that “Test cannot be serialized because it does not have a parameterless constructor.” A quick look at the documentation (or a search which may lead you to this post on StackOverflow) will get you the answer: add a parameterless constructor and mark it private. Run the test code again and this time no exception will be thrown; however, you probably won’t be expecting this result:
<?xml version="1.0" encoding="utf-16"?>
<test />

The solution? Add a setter to each of your serializable properties. Don’t need a setter because the class is immutable? Mark it as private and you’re good to go. Tough – you’re going to need one anyway, private/internal/protected setters don’t appear to work. If you must use XmlSerializer you should throw a NotImplementedException from these setters, but in my opinion the resulting contract clutter implies you should simply avoid XmlSerializer altogether.

Although this behavior makes sense in light of how XmlSerializer can be used for both serialization and de-serialization, what threw me off was that no exception is thrown – the contract doesn’t require a setter property, and the serializer output is corrupt. Beware!

Sunday, 18 January 2009 17:03:06 (Jerusalem Standard Time, UTC+02:00)  #    -
Development
# Monday, 12 January 2009

A couple of months ago I decided to give Twitter a try, and this ended up a permanent fixture in my online life. As it turns out it’s an excellent tool for posting small bits of information such as links, so I’ll be posting there much more often, but I’ll keep the in-depth posts to the blog.

twitter_logo_sm

Either way you can see my Twitter page here (or follow via RSS).

Monday, 12 January 2009 13:06:29 (Jerusalem Standard Time, UTC+02:00)  #    -
Personal
# Sunday, 14 December 2008

Chrome "final" is out, so go ahead and update your browser. This is essentially an 0.4.x development version that's been promoted to 1.0 status; if you're looking for more information on Chrome releases, check out this blog. You can get the development releases on the Chrome dev channel page.

I'm still using Chrome on both machines at home, but at work I'm testing out the new Firefox 3.1 beta 2. While there are many subtle differences between 3.0 and this beta, the primary differences are: a new privacy browsing mode (a la Chrome's incognito mode), a thoroughly revamped JavaScript engine that brings Firefox's performance to nearly-Chrome levels, and improvements to the way tabs can be rearranged.

Finally, Microsoft have finally retired FolderShare and replaced it with Windows Live Sync. I've only just started using it, and so far it looks the exact same as FolderShare, which is definitely a good thing. They've also added Unicode filename support, the lack of which was for me the biggest drawback in using FolderShare. I just hope Microsoft intend to actually improve this amazing tool, since it hasn't seen any visible improvement in over two years. To be blunt, the Microsoft treatment of FolderShare so far hasn't been very impressive, as is evidenced by the FAQ posted on the Sync team blog:

Q. What will happen to my computers running FolderShare? What about my folders and files?
A.
 Sync is designed to make the transition easy for you. When Sync releases, any computers running FolderShare will stop synchronizing files [emphasis mine --TG] and will notify you that you need to download Sync. All of your files and folders will remain untouched on your computers, but you need to install Sync on each computer to continue synchronizing files.

Sunday, 14 December 2008 11:17:53 (Jerusalem Standard Time, UTC+02:00)  #    -
Software
# Tuesday, 09 December 2008

Update (12-Jan-09): The latest Windows Live Essentials installer supports Windows Server 2008 (including x64), so no more hacks are necessary to get Messenger and/or Live Writer to work.

Update (7-Jan-09): Check out the addendum on Hyper-V performance issues below.

I’ve been using the 64-bit version of Windows Server 2008 as my development platform for the last few weeks, and have been quite happy with it. Following is a more or less verbatim transcript of the e-mail I sent out to the development guys at Delver, which may of be of some benefit to others:

Memory Requirements

Like it or not, this operating system does need more memory, but it also handles more memory (unlike 32-bit Windows which is practically limited to 3.3 [or so] GB). With 4GB on this machine I run the following applications constantly and it hardly ever swaps:

  • Google Chrome (with a buttload of tabs)
  • Total Commander
  • Process Explorer
  • Eclipse
  • Outlook
  • mRemote
  • MediaMonkey
  • Notepad++
  • Visual Studio 2005 + ReSharper 3.1.1
  • Skype
  • Live Messenger
  • FolderShare
  • KeePass

As an aside, this is also a list of software I currently use and recommend :-)

Application Compatibility

Practically every application I’ve tried so far works (the exception being the file monitor in MediaMonkey, I’ve an open bug on this). I also make it a point to try x64 versions of software where available, and these are the important bits you should know:

  • Eclipse has a 64-bit version (which runs on 64-bit JREs). I tried it for a bit and it appears to work fine, but are there some problems with Subclipse (the integration plug-in for Subversion). Subclipse can work in one of two modes: using a Java-native Subversion client library, which is unfortunately very unstable (the IDE simply crashes after 5-10 operations), or a native-code thunking API called JavaHL. The Subclipse distribution only comes with 32-bit binaries, however, and I couldn’t find 64-bit JavaHL binaries (the SlikSVN x64 client works like a charm, but doesn’t come with a JavaHL implementation). For this reason I’d recommend the following:
    1. Install a 32-bit JRE on your machine (the latest JRE is recommended). Either set your JRE_HOME accordingly or (preferably) use the -vm flag for the Eclipse launcher.
    2. Install a 64-bit JDK for development purposes. Configure Eclipse (via Windows->Preferences->Java->Installed JREs) to use the 64-bit JDK as the default runtime. This lets you develop on a 64-bit VM.
    3. If you use YourKit Java Profiler, make sure to install the integration plug-in in 64-bit mode (it lets you decide) if you use a 64-bit VM for development.
  • Checkpoint VPN-1 SecuRemote (the Checkpoint VPN client) has no x64 version, which means it simply cannot be installed. I resorted to a Windows XP 32-bit virtual machine running on Hyper-V for when I need VPN access. Hurray for Checkpoint.
  • Visual Studio 2005: Just install it as you normally would, along with ReSharper. You don’t need to do anything, and debug sessions for .NET code start as 64-bit processes. One caveat: it appears that the 64-bit debugger does not support edit-and-continue; if this is really an issue for you, here are instructions on running the debugee as a 32-bit image.
  • The various Microsoft Live! installers (Messenger, Writer, etc.) don’t support Windows Server 2008, even though the products themselves do. A quick Google search will get you instructions on how to install them anyway (use the individual MSIs directly). (12-Jan-09) No longer relevant, just download the latest installer.
  • The following applications have native x64 versions that “just work”:
    1. Eclipse (other than the problem described above). The version is not easy to find, you have to go through the Other Downloads page any find the x86_64 build.
    2. MySQL. Everything works as you’d expect.
    3. Gimp has an experimental x64 version which, again, isn't that easy to find: you have to go via the SourceForge project page and look in the stable releases. So far this version seems quite fast and robust.

Things To Do

You’ll probably want to perform these steps to get the environment closer to what you’re used to:

  • Disable the annoying shutdown event tracker.
  • Disable Internet Explorer enhanced security mode.
  • Start->right click on Computer->Properties->Advanced System Settings->Performance Settings...->Advanced and select Programs instead of Background Services (changes the paging behavior and makes everything much more responsive).
  • To get a more Vista-like look:
    1. Install the Desktop Experience feature from the Server Manager
    2. Change the “Themes” service startup mode from Disabled to Automatic
    3. Right-click your desktop->Personalize->Theme and change to Windows Vista
    4. Right-click your desktop->Personalize->Window Color and Appearance and change to Windows Aero
  • If you want audio:
    1. Change the Windows Audio service’s startup mode from Disabled to Automatic.
    2. If you get audio stuttering, change the registry key HKLM\Software\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\SystemResponsiveness from 100 (0x64) to 20 (0x14)

If you want to use virtualization (Hyper-V), make sure you update to the latest BIOS (I had an older BIOS installed that didn’t have an updated processor microcode) and enable the feature in the BIOS menu (usually disabled by default).

Benefits

  • It’s fast (feels way snappier than Vista)
  • 64-bit OS (closer to our actual production environment)
  • Virtualization support (Hyper-V)

Update: Hyper-V and Multimedia Performance

Apparently installing the Hyper-V role can have some repercussions when it comes to multimedia performance in Windows. Specifically, when running under the hypervisor you may experience very high CPU spikes (mostly kernel time) when starting up any DirectShow-based application (e.g. Windows Media Player or the considerably better Media Player Classic Home-cinema) or a remote desktop session. These will effect make your machine freeze for 5-10 seconds.

According to the rather insightful comments here, this quite likely has to do with NVidia drivers though I have not yet verified this. I don't have consistent need for Hyper-V so I simply disabled it, which resolved the problem. If you require virtualization and still want proper multimedia support you may have to resort to ATi cards.

Tuesday, 09 December 2008 18:20:13 (Jerusalem Standard Time, UTC+02:00)  #    -
Personal | Software
# Sunday, 02 November 2008

It appears it's been two months since my previous post on Chrome, so it's time for a retrospective look at the browser and its alternatives:

  • Chrome is fast.

Bleeding fast, in fact. It's been said before and I'll reiterate it - it just feels fast. I don't have any objective measurements nor do I care; my surfing habits haven't changed since moving from Firefox to Chrome, but the increase in responsiveness is both perceived and welcome.

  • Chrome is stable.

Seriously, it doesn't crash. Firefox is actually quite stable, but it suffers from its own version of winrot, and either becomes exceedingly slow or simply crashes within a day or two. Chrome hardly ever does.

Additionally, the Shockwave plugin has an annoying tendency to break oddly on the machine at work (specifically, videos play only until 00:02 with no sound), and whereas with Firefox I had to restart the browser, with Chrome I can simply terminate the process hosting the Shockwave plugin (usually recognized by being the Chrome.exe process with highest CPU utilization, but I prefer to use Process Explorer to make sure) and Chrome restarts it just fine.

All said and done, I've seen Chrome crash maybe twice these past few months, and I use it exclusively (at work and on my two home machines).

  • Chrome is full featured.

Really, it is. Most people, particularly those used to vanilla Internet Explorer 7 (or even, God forbid, 6) will not lack any functionality, at all. For power users, however...

If there's one feature in Chrome that I'm seriously missing, it's ABP (Adblock Plus, or an equivalent ad blocker). This ubiquitous Firefox extension simply sits there, unobtrusively blocks crap from taking your bandwidth and overloading your brain, is so simple to use even my granddad could get the hang of it and it Just WorksTM.

And don't buy into the Privoxy nonsense; it can take hours to configure just to be as effective as ABP, not even remotely as user friendly and requires you to run yet another server process. In my opinion it's not really worth the hassle for any but the fastidious power users (please don't take this personally, Privoxy guys -- I don't think I'm your target audience anyway).

  • Chrome needs session management.

It's hella-annoying to have to copy my URLs aside manually. The good old Session Manager extension for Firefox is another unobtrusive add-on that Just Works, one which the Chrome team should certainly emulate (at least until an extension framework is available).

  • Chrome does not handle Hebrew all that well.

RTL editing in Chrome is, to be blunt, a difficult affair at best. Although text navigation may appear to work at first glance, as soon as Hebrew characters enter the equation the whole thing becomes a right mess that's harder to handle than even Firefox in its prehistoric, Firebird days. Encoding detection seems to be a lot less robust than in Firefox (props, ShooshX!) at least for Hebrew - since that one's completely open-source, I'd certainly advise the Chrome team to import that code-base.

  • Chrome desperately needs full-page zoom.

Along with Adblock Plus, this is the one killer-feature for Firefox it's really difficult for me to do without. I use both Chrome and Firefox on my living room HTPC (Pioneer PDP-4080XA plasma display via HDMI at 1280x720) from quite a few meters, and the full page zoom in Firefox is simply light-years away from Chrome in successfully enlarging web-sites. So much so, in fact, that I've found myself more often than not going back to Firefox for that particular machine.

So, bottom line: do I like Chrome? Hell yes. I'll definitely continue using it and monitoring its progress. The browser has been amazingly impressive since day one, kudos to the astoundingly talented guys at Google who integrated the whole thing. In fact, the product is so solid it doesn't even feel like an underdog contender. I'll probably end up alternating back and forth with Firefox until it boils down to a question of taste.

Sunday, 02 November 2008 22:10:43 (Jerusalem Standard Time, UTC+02:00)  #    -
Software
# Tuesday, 16 September 2008

(Cross-posted on Stack Overflow)

Update (17-Sep-08): Corrected the answer to an integer arithmetic question ("rotate to the right" was obviously incorrect - I was careless when I wrote this. Thanks, Kuperstein!) and some formatting adjustments.

Preparation

I never interview the applicant on the first phone call. This doesn't give me the time to go over the candidate's CV and consider if there are points I'd like to bring up on the interview, such as specific work experience or glaringly missing skills. Additionally, setting up a specific time for the phone interview allows the candidate time to mentally prepare, drink a coffee and settle down in a quiet spot somewhere. Just puts everyone at their ease.

When first calling the candidate I always take the time to introduce the company I work for, a synopsis of what we do and a general description of how the company operates. I then proceed to inquire if the applicant sees this as a potentially interesting place to work in and whether or not they have any questions; you'd be surprised at the time this can save, for example it's not always obvious whether or not the applicant is interested in working for a start-up company, or alternatively may not find the problem domain engaging.

Getting to Know The Candidate

To start the interview off, I usually skim over the candidate's CV and select two or three interesting projects that the candidate was involved in. I ask the candidates to describe their involvement (sometimes, but not often, going into a bit of detail if the domain is familiar to me), their specific contribution to the project, whether or not they had fun and why. This usually gives me a sense of what the candidates are looking for; are they heavily into design? Are they enthusiastic about a specific technology, and if so, do they have a sound reason for it? Were they frustrated by administrative issues, did they try to improve their working environment?

Technical Questions

Once those formalities and niceties are out of the way, I turn to my ever-growing collection of interview questions and select a small subset to present to the candidate. For example, a typical interview may include the following questions:

Integer Arithmetic

Does the candidate have a decent grasp of bits and bytes? I consider this a must-have; a candidate that fails this part has no chance in hell of tackling even the most trivial native code.

  • "Take an integer. How do you turn the 7th least significant bit off?" This question alone removes about half of the applicants from the equation. Some people tell you "you need to apply bitwise AND, but I can't remember the number you need to AND with" -- this isn't what you're looking for. A good answer would be something like "x &= ~(1 << 6)".
  • "How would you quickly divide an integer by eight (8)?" A good answer is, you shift right by three. A better answer would be "is the integer signed or unsigned?", with a bonus for Java developers who know the difference between >> and >>>.

Pointers and Pointer Arithmetic

This really depends on what your company does. Most developers today don't need to know in practice the particulars of pointers and pointer arithmetic optimizations, but if you're developing a highly scalable system and/or one with serious performance considerations, this is a very good measure of how likely the candidate will be able to tackle such challenges.

  • "How big is a pointer?" The only correct answer is, "depends on the architecture". 32-bit operating systems will have 32-bit pointers, 64-bit systems will have 64-bit pointers. Anything that doesn't fall into these two categories is not relevant for my purposes, and likely yours as well. If the candidate fails this question I usually mark this section as "failed" and move on.

Floating Point Numbers

  • "What is NaN?" A programmer who can't answer this question has never really worked with floating point numbers.
  • "How are floating point numbers represented in a typical modern architecture?" Failing this question is not a deal-breaker, but answering it correctly will score the candidate a lot of points. "sign, exponent, mantissa/fraction/significand" is a sufficient answer.

Essential Data Structures and Algorithms

This is the bread-and-butter of programming. A candidate should exhibit robust familiarity with commonplace data structures (hashtables, linked lists, trees etc.) and algorithms (sorting, graph traversal).

  • "Describe how quicksort works. Elaborate on its performance characteristics." Any professional developer should be able to explain quicksort in a few minutes, know its average- and worst-case complexity, and recognize pathological cases (typical school-level quicksort implementations exhibit horrible performance on pre-sorted data).
  • "How are hashtables commonly implemented?" A candidate should be able to describe the concept of a hashing function (uniform distribution) and how it relates to the internal data structure (normally an array of buckets).
  • "What backing data structure would you choose for a simple text editor?" The classic answer is arope, but it's unlikely that a candidate will be familiar with this data structure. A more likely response would be a "linked-list of strings", in which case you should ask about the complexity of various editing operations (deleting a line, inserting a line, deleting a character etc.) This question typically takes slightly longer to answer but I've found that it gives me a good measure of the candidate's intuition in choosing/analyzing data representations.

Threading and Sychronization

This is fast becoming the most important subject with which to distinguish the truly brilliant candidates from the merely competent; the ubiquity of multithreaded code nowadays also means that these questions can be used to quickly weed out the unworthy candidates.

  • "Describe one common way of synchronizing access to a shared resource." This is just a starter question, and if the candidate takes more than a few seconds to come up with an answer (mutex, semaphore, monitor or "synchronized" for Java developers, "lock" for C# developers) it's usually a good sign that they don't have any reasonable experience with multithreaded development.
  • "You have a shared cache with a very good hit ratio. How would you synchronize access to the cache with as little performance overhead as possible?" The answer is trivially a read-write lock which can accomodate multiple readers and a single, exclusive writer. Where appropriate, ask how the candidate would implement such a lock.
  • "Describe a nontrivial problem that you've had with threaded code." Responses usually fall into one of three categories: either (1) a reasonably experienced multithreaded developer would never make the same mistakes, in which case the candidate obviously isn't one; (2) a classic race-condition/deadlock/etc. scenario, which merely tells you that the candidate has some experience with multithreaded code and appears capable of tackling such challenges; or (3) rarely, a candidate may have a genuinely interesting "war story," in which case you'll probably want to hire them right away.

Peripheral Technologies

Approach this section with caution. A canditate that's familiar with a great deal of today's hot technologies may prove completely incompetent, whereas it's quite possible to find brilliant programmers that have never touched COM in their lives. I still like to get a sense of how "in touch" the developer is with contemporary technologies; familiarity with tools and technologies can definitely be a tie-breaker between two promising candidates.

  • "Are you familiar with COM? Describe an interface which any COM object must implement and its methods." Anyone who's even a bit familiar with Windows software development should be able to answer this question fully. For those unfamiliar with COM, describe it in a few words and ask the canditate to guess what the required methods of IUnknown are.
  • "What is a well-formed XML file? Give two examples of errors in an XML file which would render it non-well-formed." XML is prevalent in almost every software development domain. A candidate which cannot answer these questions (and doesn't have a very good excuse) will not go past this interview.
  • "What's XPath? Explain what a predicate is and how it's used." This is not most-have. I'd expect serious developers to at least have an idea of what XPath is. The second question is there to differentiate those who profess to know XPath from those who've actually done work with XPath and/or XSLT.
  • "If you had to verify the input of an e-mail address field, how would you go about it?" There are only two valid answers to this question: "I would use a regular expression," or "I'd like to use a regular expression, but I know that fully matching e-mails according to the RFC is insanely complex, which is why I'd get a proven library to do it for me." If the canditate is being a smart-ass you can always ask them about the performance characteristics of commonplace regex engines (which have pathological cases).
  • I also like to just toss buzzwords (Ruby, Boo, JSON, Struts, J2EE, WCF) around and examine the candidate's responses. It may also provide an interesting subject to ask about in a personal interview later on.

Concluding the Interview

The previous section usually takes between 10 and 15 minutes. At this point I normally ask the candidate if there are any questions they'd like answered, or anything I should know before we conclude the interview. Once that'd done, I thank them for their time and tell them (even if they've failed miserably) that I will call them back in a day or two with an answer.

Hope this helps, comments are welcome.

Tuesday, 16 September 2008 19:39:11 (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Personal
Me!
Send mail to the author(s) Be afraid.
Archive
<2009 March>
SunMonTueWedThuFriSat
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234
All Content © 2017, Tomer Gabel
Based on the Business theme for dasBlog created by Christoph De Baene (delarou)