My Tales

  • Contractor Khan 2008-07-30 10:07
    Min is the reason why you should keep files on people that applied, as you are allowed to, for 6 months, with NOTES on what they admitted lying about.

    VB isn't that hard I suppose, what's the worst that could happen.

    VB life support machines. *Shudder*.
  • CRNewsom 2008-07-30 10:14
    Contractor Khan:
    VB life support machines. *Shudder*.


    You haven't heard of them? The Kevorkian Institute uses them almost exclusively.
  • Grovesy 2008-07-30 10:16
    Contractor Khan:
    Min is the reason why you should keep files on people that applied, as you are allowed to, for 6 months, with NOTES on what they admitted lying about.

    VB isn't that hard I suppose, what's the worst that could happen.

    VB life support machines. *Shudder*.


    Well, with VB6 at least you can't put life saving critical code in a finally block.
  • Markp 2008-07-30 10:18
    Contractor Khan:
    VB life support machines. *Shudder*.


    Is that
    a) life support machines developed in VB, or
    b) Min, the "machine" used to keep a VB application alive?
  • techie 2008-07-30 10:21
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?
  • unther 2008-07-30 10:22
    A similar thing happened here. We had a doctor of mathematics and computer science applying here telling us all about his skills in ... well, almost everything. In short, he presented himself as a programming god humbling all of us little grunts.

    In reality, he had no qualifications. He wrote his thesis on formal languages, which is probably the most theoretical part of computer sciences. He had no experience in programming or in designing business applications. He failed in writing a one-line-.NET-program (create an account in a CRM-system with just a title) after ONE week. He couldn't even read an SDK. However, HE was VERY surprised when he found out that we "simple grunts" could read UML without being a doctor of computer science.

    When we found out that he worked as a medium and clairvoyant on some 0900-number-company (stumbled over it when we googled his name), his days were counted...maybe this guy and his story would qualify for an entry here...

    Anyway, this scheme seems to work more often than you think.
  • Markp 2008-07-30 10:22
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    Does it matter? From my perspective, lying to a potential employer is a show-stopper, hands down.
  • JonC 2008-07-30 10:23
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.

    That would have been setting alarm bells ringing immediately for me.
  • mafro 2008-07-30 10:25
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    Blind assumption is safe in this case I believe.. Perhaps they were looking for someone with *experience* programming?

    That's what I tend to do...

    CAPTCHA: ingenium (!)
  • techie 2008-07-30 10:25
    Markp:

    Does it matter? From my perspective, lying to a potential employer is a show-stopper, hands down.


    Well, yes, since she was already an employee in the company apparently.
  • Dave 2008-07-30 10:26
    Markp:
    From my perspective, lying to a potential employer is a show-stopper, hands down.


    From my perspective, getting caught lying to a potential employer is a show-stopper, hands down.
  • Markp 2008-07-30 10:27
    techie:
    Markp:

    Does it matter? From my perspective, lying to a potential employer is a show-stopper, hands down.


    Well, yes, since she was already an employee in the company apparently.


    Read the article again. It seems to be saying she received the position in the other group after being denied by Alex's group.
  • Waffle 2008-07-30 10:35
    Markp:
    techie:
    Markp:

    Does it matter? From my perspective, lying to a potential employer is a show-stopper, hands down.


    Well, yes, since she was already an employee in the company apparently.


    Read the article again. It seems to be saying she received the position in the other group after being denied by Alex's group.


    Yeah, lying finally got her a job.
  • morry 2008-07-30 10:40
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?

  • jefg 2008-07-30 10:49
    package test;

    public class minBean {

    private String min = "Brillant";

    public String getMin() {
    return min;
    }
    }
  • KTC 2008-07-30 10:50
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?
    I think we can safely assume Min didn't know how to program in any language she said she can after Alex from her answers found out she "had never actually used Visual Basic. Or C++. Or, really, any other programming language". Or maybe the part where she freely answered affirmative to the question which stated she had never used any of "these skills and technologies".
  • Satanicpuppy 2008-07-30 10:59
    I tend to use "finally" as an attempt to gracefully fail after all other avenues have proven fruitless; I always sort of thought that was the point of finally...To clean up after failed Catches. I tend not to use finally though, so I'm not the best person to opine.

    I guess, thinking about it, you could use it as a sort of general cleanup...Seems...I don't know...Odd.
  • SomeCoder 2008-07-30 11:01
    morry:
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?



    That's what I was wondering. If you want a guarantee that your code will be executed... well I guess there are no guarantees. Don't use computers to execute business critical code?

    I guess my point is, if the computer is suddenly shut off, it doesn't matter where your put your code*, finally or no. It's not going to be run if the machine is off.


    *Note: I know it matters where you put business critical in an app but my point is, Alex was being a tiny bit pedantic in my opinion.
  • danixdefcon5 2008-07-30 11:04
    JonC:
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.

    That would have been setting alarm bells ringing immediately for me.
    That reminds me of one question I got in my previous job:

    "Which version of Solaris do I need to run Linux?"

    The only blooper I might pass, however, might be something like "Microsoft Sybase" or "Sybase SQL Server", as they are practically the same thing. Except Sybase actually runs in non-MS platforms!
  • shadowman 2008-07-30 11:04
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    Well, like others said, catching her lying in the interview pretty much precludes anything else.

    But I'd guess coupling that with glaring errors like 'Microsoft Solaris' on her resume might be a worthy indicator of her programming ability
  • jjeff1 2008-07-30 11:05
    Shortly before I worked a my current company, we hired a network engineer named Bob. He had a bunch of certifications and came recommended, from where I'm not sure.
    During the interview, my boss described the work environment (NT4) and expectations. The boss wasn't going to insult his intelligence by asking silly technical questions.

    Bob is the reason now we ask a lot of technical questions and never rely on anything the candidate thinks about their own level of knowledge.

    Bob's first day or so, he was asked to install Windows NT on a server and configure IIS.

    Bob (aside to new co-worker) "Does he actually expect me to do that?"

    Bob was offered a new position as a jr level guy, at a much reduced pay rate. Luckily, he turned us down.
  • techie 2008-07-30 11:06
    KTC:
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?
    I think we can safely assume Min didn't know how to program in any language she said she can after Alex from her answers found out she "had never actually used Visual Basic. Or C++. Or, really, any other programming language". Or maybe the part where she freely answered affirmative to the question which stated she had never used any of "these skills and technologies".


    I still don't think that's safe to assume. It could be that she's never used those skills and technologies in a professional capacity. Especially if there was a language barrier or anything. A WTF response to a valid programming question would have made this a great addition to the WTF files. Give me a smart person who understands logic, and I can teach them how to program. Give me a dumbass who has a CS degree, and they'll appear on this site eventually.
  • Satanicpuppy 2008-07-30 11:08
    SomeCoder:
    morry:
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?



    That's what I was wondering. If you want a guarantee that your code will be executed... well I guess there are no guarantees. Don't use computers to execute business critical code?

    I guess my point is, if the computer is suddenly shut off, it doesn't matter where your put your code*, finally or no. It's not going to be run if the machine is off.


    *Note: I know it matters where you put business critical in an app but my point is, Alex was being a tiny bit pedantic in my opinion.


    The secret is not to guarantee that your code will be completely executed, it is to guarantee that it will not be partially executed. Having a program fail completely is no problem at all...No harm, no foul, just run it again. Having it partially fail will screw up your whole week; that's why he mentioned database transactions.

    Using a Finally like they used it would be fine if all the Finally did was commit the transaction or something...Trusting it to break new ground is a recipe for the sort of subtle failure that makes you tear your hair out.
  • The Hermit 2008-07-30 11:09
    package test;

    public class Min {
    private String min = "Brillant";

    public String getResume() {
    return "I know VB";
    }

    public String getJob() {
    try {
    lieAboutVB("");
    } catch (GotCaughtException e) {
    getJobSomewhereElse();
    }
    finally {
    }
    return "finally, yay it worked!";
    }
    }
  • Alex Papadimoulis 2008-07-30 11:10
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    I'm sure she had some basic programming knowledge, but we really needed someone who had experience with the "keywords" she listed. It was a big, boring company, so 30% of the job was navigating the bastardisation of the specific technology stack, 69.5% was communication/bureaucracy, .5% was actual programming.
  • Brandon 2008-07-30 11:11
    if(computer.IsOver || computer.IsAboutToBeOver)
    {
    //execute critical business code
    }

    I win.
  • anon 2008-07-30 11:12
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing
  • danixdefcon5 2008-07-30 11:15
    SomeCoder:
    morry:
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?



    That's what I was wondering. If you want a guarantee that your code will be executed... well I guess there are no guarantees. Don't use computers to execute business critical code?

    I guess my point is, if the computer is suddenly shut off, it doesn't matter where your put your code*, finally or no. It's not going to be run if the machine is off.


    *Note: I know it matters where you put business critical in an app but my point is, Alex was being a tiny bit pedantic in my opinion.
    Same I thought. Finally blocks always execute, the only way they wouldn't execute would be in situations where no code will get executed, like kill -9'ing the process, or on power down. Anyway, any critical transactions should be inside a transaction block themselves, so these two cases would cause an auto-rollback anyway!

    Note: finally blocks will run even if the exception thrown is an unchecked one (i.e. RuntimeException).
  • techie 2008-07-30 11:16
    Alex Papadimoulis:

    I'm sure she had some basic programming knowledge, but we really needed someone who had experience with the "keywords" she listed. It was a big, boring company, so 30% of the job was navigating the bastardisation of the specific technology stack, 69.5% was communication/bureaucracy, .5% was actual programming.


    Fair enough. I basically got the job because I was eminently trainable, and the job had the same breakdown :)
  • jpers36 2008-07-30 11:17
    We have a couple places in our Java legacy code that use the following paradigm (simplified for readability, of course):

    public static int tester(String s) throws Exception
    {
    int retval = 0;
    try
    {
    retval = Integer.parseInt(s);
    }
    catch(Exception ex)
    {
    throw ex;
    }
    finally
    {
    return retval;
    }

    }


    The exception gets eaten and the method happily returns something, pretending there's no problem at all. Fixing it is on our list of things to do. Nothing's gone haywire ... yet.
  • anon 2008-07-30 11:18
    actually, you could return to jump over the finally, code still executes, just not the finally.
  • zoips 2008-07-30 11:18
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing


    finally is intended for (an attempt at) graceful cleanup when you plan to propagate the exception up the stack. At least that's always been my impression.
  • Anonymouse 2008-07-30 11:24
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    I believe the difference is, the finally block is in scope to access variables declared within the try block, while code added after, but not in a finally block, is out of scope.

    Of course that depends entirely on the language and it's scoping semantics so in some cases, there may be no difference. And also I suppose where the variables are declared.
  • anon 2008-07-30 11:25
    zoips:
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing


    finally is intended for (an attempt at) graceful cleanup when you plan to propagate the exception up the stack. At least that's always been my impression.


    I'll agree with you there. but I don't like exceptions to go outside of the function it happened in, I tend to prefer using if statements to validate input and take care of any problems that arise. if I have to interface with something that throws exceptions (for example most pre-built DB handlers only use that) I use try-catch as a replacement for if. if this code doesn't work, handle all the errors and cleanup gracefully and return a standard response of what happened instead of complaining to the routine that requested the function to run.
  • The Land of Cleve 2008-07-30 11:27
    Any idea where Min is today? She sounds ... familiar.
  • Brian 2008-07-30 11:28
    Wow, alot of people don't understand try/catch/finally here. It makes no sense to put a return statement in your finally block. If you think it does then you miss the point of finally.
  • Andrew 2008-07-30 11:28
    unther:
    A similar thing happened here. We had a doctor of mathematics and computer science applying here telling us all about his skills in ... well, almost everything. In short, he presented himself as a programming god humbling all of us little grunts.

    ...this scheme seems to work more often than you think.


    I don't think this person and Min are the same at all. This guy is far worse.

    He had a doctor of mathematics and computer science. She did not claim any advanced degree. Min's interviewer was likely more careful about skills. The other interviewer probably just assumed he knew how to program.

    Min admitted she knew no programming after she was caught. The good doctor told a lecture full of lies.

    Padding an entry-level resume is not as bad as using a Ph.D. to break into a field!
  • shepd 2008-07-30 11:30
    I'd even suggest Min is the reason you stop looking at requirements (unless they are absolutely required) and start looking at abilities. Too many employers would take a fresh graduate that lists 15 languages you want them to know on their resume they "learned" in some school at god-knows-where over someone who has been in IT for a decade, but only has 10 of the 15 qualifications you want. And I'm just talking about offering them an interview. Once you offer the interview, it becomes obvious who is best for the job.

    Guess who is going to figure out how to get the job done faster and with fewer errors... And guess who is going to be far more useful to your company when hard times come.
  • Jabmist 2008-07-30 11:30
    stack overflows will STILL call the finally

    package test;
    public class miscTest {
    public int loop(int x){
    return (loop(x+1));
    }
    public static void main(String[] args) {
    try{
    int x=0;int y=5; miscTest test = new miscTest();
    test.loop(1);
    double t = y/x;

    }catch(Exception e){
    System.out.println("catch start");
    int x=0;int y=5;
    double t = y/x;
    System.out.println("catch end");
    }finally{
    System.out.println("finally");
    }
    }
    }


    finally
    java.lang.StackOverflowError
    at test.miscTest.loop(miscTest.java:8)
    at test.miscTest.loop(miscTest.java:8)
    at test.miscTest.loop(miscTest.java:8)
  • Patrick 2008-07-30 11:33
    JonC:
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.

    That would have been setting alarm bells ringing immediately for me.


    Those aren't even typos. They're blatant errors which are mix-mash of various technical terms. I could understand misspelling "DCOM" as "DCMO". And yes, your HR department needs to be told that not only did she lie on her resume, but she said she lied to the interviewer.
  • Steve 2008-07-30 11:34
    I had one like "Min".

    I scratched the person, call him "Max" just for the sake of inventing a name, off the list after a brief phone interview on some fundamental technical grounds as well as a sneaking feeling that there was something wrong.

    A few months later, I was asked to take a look at some resumes for another position and there, again, was "Max". I mentioned my misgivings to the manager involved and dismissed the whole incident from my thoughts.

    A week or so later, there was "Max", settling into a workstation, having been hired over my misgivings. I told myself, "okay, I'll give 'Max' the benefit of the doubt and besides, 'Max' won't be working on my project, so it's someone else's problem."

    Except that about a month or so after that, for reasons which remain opaque to me, "Max" was assigned to my project as a Java programmer. "Max" claimed to be a database person and whined about having to program in Java, got into conflicts with one of the other programmers, and never actually completed anything useful -- I don't think I even got a Paula "brillant" from "Max".

    "Max" then wondered why his performance reviews were mediocre and complained of that his talents weren't being recognized.

    "Max" eventually got reassigned to another group which, to the best of my knowledge, has never produced anything beyond interiminable meetings and hangs on by attaching itself remora-like to other successful projects. Everyone seems happy.
  • Alex Papadimoulis 2008-07-30 11:35
    morry:
    where are you supposed to put the code? Magic fairy blocks?


    This answers it pretty well...

    Satanicpuppy:

    The secret is not to guarantee that your code will be completely executed, it is to guarantee that it will not be partially executed. Having a program fail completely is no problem at all...No harm, no foul, just run it again. Having it partially fail will screw up your whole week; that's why he mentioned database transactions.

    Using a Finally like they used it would be fine if all the Finally did was commit the transaction or something...Trusting it to break new ground is a recipe for the sort of subtle failure that makes you tear your hair out.


    ... but to expand on that, from a code perspective, if you're lucky enough to have an underlying transactional system, it's like this:

    try { StartTransaction(); DoStuff(); }
    catch { RollbackTransaction(); }
    finally { CommitIfNotRolledBack(); }

    The underlying transaction system will auto-rollback if it never gets committed or rolledback. However, the *real* problem occurrs when someone doesn't have an underlying transactional system.

    try
    {
    ProcessAllRecords();
    }
    catch //(or a conditional finally)
    {
    UndoAllProcessing();
    }

    If ProcessRecords() is not designed to be re-entrant, then you're pretty much screwed if an error occurs *and* UndoAllProcessing() never is run.

    To make matters worse, these problems compound themselves, so the second time you run the program, the un-catchable exception occurs again and further corrupts the underlying data.

    Finally should be used for things like memory cleanup so you don't end up with leaks, etc. If the program never hits that kind of finally block, it's OK, since the whole thing has crashed and burned already, and memory leaks are the least of your worries.
  • snoofle 2008-07-30 11:35
    put life saving critical code in a finally block...

    Life saving? No. Clean up? Yes:


    class Doctor {
    public Doctor() {
    goToMedicalSchool();
    doInternship();
    }

    public void treatPatient(Patient patient) {
    try {
    diagnose(patient);
    treat(patient);
    patient.setStatus(Better);
    } catch (TreatmentFailed tf) (
    callPriest(patient);
    patient.setStatus(Deceased);
    // cheap joke re: patent.setStatus(FileNotFound);
    } finally {
    discharge(patient); // to family or mortician
    }
    }
    }
  • diaphanein 2008-07-30 11:48
    SomeCoder:
    morry:
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?



    That's what I was wondering. If you want a guarantee that your code will be executed... well I guess there are no guarantees. Don't use computers to execute business critical code?

    I guess my point is, if the computer is suddenly shut off, it doesn't matter where your put your code*, finally or no. It's not going to be run if the machine is off.


    *Note: I know it matters where you put business critical in an app but my point is, Alex was being a tiny bit pedantic in my opinion.


    The point was that the assertion that code in a finally block is always executed is wrong. Period.

    For instance, in C#, here's an example of a finally block that'll never execute, even without pulling the plug from your computer. The only output will be "Before fail fast":


    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace FailFast
    {
    class Program
    {
    static void Main(string[] args)
    {
    try
    {
    Console.WriteLine("Before fail fast");
    Environment.FailFast(null);
    Console.WriteLine("After fail fast");
    }
    finally
    {
    Console.WriteLine("in finally block");
    }
    }
    }
    }
  • NCBloodhound 2008-07-30 11:48
    Reminds me of interviewing candidates with Active Directory experience. They would put 'AD' on their resume so we would ask them about it. They would typically say any of the following:

    "AD stands for Active Directory."
    "AD is what is used when you log in."
    "My consulting company told me to put that on there."

    When never found one that had actually had REAL experience with AD, so we hired a recent college grad and trained him. He was cheap and we could mold him into the developer we needed.
  • BentFranklin 2008-07-30 11:48
    Someone please educate me a bit: How does a database survive a power cycle in the middle of writing a transaction?

    Captcha: appellatio (A program that sucks?)

  • Ken B 2008-07-30 11:52
    Human Resources was a bit peeved that my group was so “picky” with our candidates ad rejected all of the qualified candidates (read: one) that they had sent over.
    You could have said "and I suppose you wanted me to hire *all* of the candidates you sent over?"
  • Andrew 2008-07-30 11:54
    The arguments over try...catch...finally remind me of a story about the Java finalize() method. This mehod has far worse indeterminant behavoir than try...catch...finally.

    We had an otherwise brilliant programmer, with a C/Perl/CGI background but not Java. He even had a Master's degree in computer science.

    He was tasked with writing a JSP webapp for the company. The application usually ran fine, but occasionally it randomly executed some code.

    After much discovery, he found out that his AppClass.finalize() also overrode the Object.finalize() method. The garbage collector was running his method at random intervals.
  • Andrew 2008-07-30 11:55
    The arguments over try...catch...finally remind me of a story about the Java finalize() method. This mehod has far worse indeterminant behavoir than try...catch...finally.

    We had an otherwise brilliant programmer, with a C/Perl/CGI background but not Java. He even had a Master's degree in computer science.

    He was tasked with writing a JSP webapp for the company. The application usually ran fine, but occasionally it randomly executed some code.

    After much discovery, he found out that his AppClass.finalize() also overrode the Object.finalize() method. The garbage collector was running his method at random intervals.
  • Dave 2008-07-30 11:57
    shadowman:
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    Well, like others said, catching her lying in the interview pretty much precludes anything else.

    But I'd guess coupling that with glaring errors like 'Microsoft Solaris' on her resume might be a worthy indicator of her programming ability


    I dunno could have just been a missed comma.
  • diaphanein 2008-07-30 11:58
    [quote user="danixdefcon5Same I thought. Finally blocks always execute, the only way they wouldn't execute would be in situations where no code will get executed, like kill -9'ing the process, or on power down. Anyway, any critical transactions should be inside a transaction block themselves, so these two cases would cause an auto-rollback anyway!

    Note: finally blocks will run even if the exception thrown is an unchecked one (i.e. RuntimeException).[/quote]

    Yes, but it pays to be aware of the situations in which they will not execute.

    Just last week, I wasted half a day debugging a production issue where an app, despite checking all error codes, wrapping all pertinent calls in try/catch blocks was failing silently. No error, not log, no non-zero exit status. As it turns out, a 3rd party library was graciously calling exit_group for me. Only way I was even able to find that was by doing an strace.
  • Paula Bean 2008-07-30 11:58
    Alex Papadimoulis:
    morry:
    where are you supposed to put the code? Magic fairy blocks?


    This answers it pretty well...

    Satanicpuppy:

    The secret is not to guarantee that your code will be completely executed, it is to guarantee that it will not be partially executed. Having a program fail completely is no problem at all...No harm, no foul, just run it again. Having it partially fail will screw up your whole week; that's why he mentioned database transactions.

    Using a Finally like they used it would be fine if all the Finally did was commit the transaction or something...Trusting it to break new ground is a recipe for the sort of subtle failure that makes you tear your hair out.


    ... but to expand on that, from a code perspective, if you're lucky enough to have an underlying transactional system, it's like this:

    try { StartTransaction(); DoStuff(); }
    catch { RollbackTransaction(); }
    finally { CommitIfNotRolledBack(); }

    The underlying transaction system will auto-rollback if it never gets committed or rolledback. However, the *real* problem occurrs when someone doesn't have an underlying transactional system.

    try
    {
    ProcessAllRecords();
    }
    catch //(or a conditional finally)
    {
    UndoAllProcessing();
    }

    If ProcessRecords() is not designed to be re-entrant, then you're pretty much screwed if an error occurs *and* UndoAllProcessing() never is run.

    To make matters worse, these problems compound themselves, so the second time you run the program, the un-catchable exception occurs again and further corrupts the underlying data.

    Finally should be used for things like memory cleanup so you don't end up with leaks, etc. If the program never hits that kind of finally block, it's OK, since the whole thing has crashed and burned already, and memory leaks are the least of your worries.

    Aha!
    Thanks, I really appreciate this explanation.
    Twice the benefit from today's visit!
  • DL 2008-07-30 11:59
    anon:
    actually, you could return to jump over the finally, code still executes, just not the finally.


    Sorry, that's incorrect. If you call "return" from within the "try" block, "finally" is still executed - that's the point!

  • Dave 2008-07-30 12:01
    anon:
    zoips:
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing


    finally is intended for (an attempt at) graceful cleanup when you plan to propagate the exception up the stack. At least that's always been my impression.


    I'll agree with you there. but I don't like exceptions to go outside of the function it happened in, I tend to prefer using if statements to validate input and take care of any problems that arise. if I have to interface with something that throws exceptions (for example most pre-built DB handlers only use that) I use try-catch as a replacement for if. if this code doesn't work, handle all the errors and cleanup gracefully and return a standard response of what happened instead of complaining to the routine that requested the function to run.


    Is that a subtle FILE_NOT_FOUND joke?
  • Pope 2008-07-30 12:03

    “Min,” I questioned, “why would put all these skills and technologies"


    Good idea to talk like her to really get the point across. Very effective. My big brother does that to pick up women at Chinese restaurants. With hands in the praying position he says, "Prease to be going out on date with me? I rike you."
  • Jason Bock 2008-07-30 12:04
    Holy crap, DON'T catch the general exception type!
  • Dave 2008-07-30 12:08
    Jason Bock:
    Holy crap, DON'T catch the general exception type!


    As long as you rethrow its not the end of the world.
  • blah 2008-07-30 12:18
    TRWTF is this article has more sloppy typos than Min's resume's bad Engrish.
  • Morasique 2008-07-30 12:20
    BentFranklin:
    Someone please educate me a bit: How does a database survive a power cycle in the middle of writing a transaction?

    Captcha: appellatio (A program that sucks?)



    Usually databases use journaling, so the change is logged in the journal before it actually happens. When the database starts, it checks the end of the journal to make sure it wasn't killed abnormally, and rolls back or commits whatever it needs to based on the journal to make the actual database consistent
  • The Vicar 2008-07-30 12:22
    Brandon:
    if(computer.IsOver || computer.IsAboutToBeOver)
    {
    //execute critical business code
    }

    I win.

    You forgot to add

    if(Virus == Very Yes)

    You won, but that's not a good prize.
  • kswanton 2008-07-30 12:23
    I've only had one bad interview experience. The lead was called in to handle the technical portion of the interview, which was made up of a few questions.

    One of the questions was 'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.

    The interviewer kinda smirked at me and said something along the lines of 'Well that is not efficient - is there a more efficient way to do it' to which I responded 'Not that I can think of...'

    In a condescending way he suggested that there was a much better way to check, that was quicker, less memory intensive, etc etc, and gave me the hint 'What about the first item in the list??? - what can you do with it that would make this easier?' I should have seen that the solution he was driving at, even though I thought it was wrong. After a while he gave me his answer which was to just compare the first element to each additional element in the list, if you ever get back to it you have a circular reference, still smirking like he was the smartest guy that I'd ever meet.

    At this point, I suggested that his solution was flawed - what if the circular reference did not point back to the first element, it would fail to detect it, such as:

    A points to B which Points to C which points back to B. In this case you'll never get back to 'A'.

    He ended the interview at this point and I never heard from them. Not sure if this was the reason why they did not call back or if it was just due to other reasons... or my solution *was* shitty... I guess I don't really care, the job was downtown, which I try to avoid like the plague.
  • SQB 2008-07-30 12:24
    anon:
    actually, you could return to jump over the finally, code still executes, just not the finally.
    Not in all languages. In Java, finally always executes, even when already returning.
    try { return true; } finally { return false; }
    returns false, not true (nor FILE_NOT_FOUND).
  • Axel R. 2008-07-30 12:24
    danixdefcon5:
    The only blooper I might pass, however, might be something like "Microsoft Sybase" or "Sybase SQL Server", as they are practically the same thing. Except Sybase actually runs in non-MS platforms!


    I hope your employer is not reading this, as MS SQL Server and Sybase SQL Server parted completely in... 1998 with the introduction of SQL Server 7.0
  • cakesy 2008-07-30 12:30
    I am good at interviews, I have gotten the last 5 interviews I went for. I can talk the talk, and have some good experience in a variety of positions. I used to really bad at interviews, didn't get a job offer after about 30 or 40 tries.

    The thing is, I was a much better programmer in those days. I cared a lot about learning new stuff, would go home and program for fun. Would learn new languages for fun, and write some interesting applications. Now I don't care about it that much, don't program much outside of work, don't work as hard. But because I am good at interviews, I can get the job. Brillant!
  • Jay 2008-07-30 12:55
    JonC:
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.


    Personally I'd give someone the benefit of the doubt on "Microsoft Solaris". I'd chalk it up to clumsy wording. Sun has a version of Solaris that runs on Intel platforms. Someone who installed Solaris on their Wintel box might carelessly refer to it as "Microsoft Solaris". Wrong? Yes. A lie? Not necessarily.

    In general, I'm always cautious about ridiculing someone for making a dumb statement for fear that maybe it will turn out that their statement is correct and I only thought it was wrong because they know something that I don't. I don't want to laugh at someone and call him an idiot ... and then find out that he's right and I'm wrong. I prefer to ask for clarification before deciding someone's an idiot. A little humility can save you a lot of embarassment.
  • Camel Chase 2008-07-30 12:55
    Also a finally gets executed no matter what Exception hits.

    Consider:

    try {
    db.begin;
    // do Stuff
    Object o = null;
    o.getClass(); // NullPointerException

    db.commit();
    db.close(); // <--Problem
    db = null;
    } catch (NumberFormatException nfe) {
    db.rollback();
    db.close;
    db = null;
    // return error
    } finally {
    // free the db handle.
    if (db != null) {
    try {db.rollback(); db.close();} catch (Exception e) {}
    }
    }


    Your code is probably wrong (not cxhecking for null), but it doesn't chew up your db handles.

    kthxbye.
  • bcharr2 2008-07-30 12:58
    shepd:
    Too many employers would take a fresh graduate that lists 15 languages you want them to know on their resume they "learned" in some school at god-knows-where over someone who has been in IT for a decade, but only has 10 of the 15 qualifications you want. And I'm just talking about offering them an interview. Once you offer the interview, it becomes obvious who is best for the job.

    Guess who is going to figure out how to get the job done faster and with fewer errors... And guess who is going to be far more useful to your company when hard times come.


    There is no hard and fast rule to the "Who is better, the college taught or self taught programmer?", because no 2 job candidates are exactly alike.

    I've seen individuals with degrees and without who could program. I've seen individuals with degrees and without who couldn't program.

    Oftentimes the best team can be a mix of those with and without degrees, assuming everyone involved can program.

    Which was the point of the article. The lady in question COULD NOT program, she simply knew how to use applications that had been developed in the languages that appeared on her resume.

    I once had a resume cross my desk that listed the following under programming languages: Word, Office, Excel. The gentlemen involved seemed like a nice guy, stated his love for computers over and over, and couldn't stress enough how fast of a learner he was. Did he get the job?

    No, he didn't even get to interview. If he loved programming that much, he would have taken the time to learn enough to be an asset to the company.

    This isn't a hero's quest, and I'm not your grandfatherly mentor who is going to peer deep down into your soul looking for all of your hidden potential that is just waiting to come out.

    In fantasy, heroes emerge at the moment of crisis and somehow seem to have all the skills they need. In the real world, the men and women who have committed themselves to years of preparation and training carry the day.
  • WhiskeyJack 2008-07-30 13:00
    Ken B:
    Human Resources was a bit peeved that my group was so “picky” with our candidates ad rejected all of the qualified candidates (read: one) that they had sent over.
    You could have said "and I suppose you wanted me to hire *all* of the candidates you sent over?"


    You could give all of them numbered marathon jerseys, and refer to them by number instead of name. And when one screws up, you fire him on the spot. Last person standing gets the job.
  • Old fart 2008-07-30 13:00
    If he was clairvoyant then you'd think he would have seen it coming...
  • Jay 2008-07-30 13:03
    kswanton:
    At this point, I suggested that his solution was flawed - what if the circular reference did not point back to the first element, it would fail to detect it, such as:

    A points to B which Points to C which points back to B. In this case you'll never get back to 'A'.

    He ended the interview at this point and I never heard from them. Not sure if this was the reason why they did not call back or if it was just due to other reasons... or my solution *was* shitty... I guess I don't really care, the job was downtown, which I try to avoid like the plague.


    I've had occasions where an interviewer has asked me a flawed question like that, and I always struggle with what to do about it. If you concede the point, then you're "admitting" that you didn't know the right answer, and presumably you're going to lose points. But if you point out the interviewer's error, there's the likelihood that he's then going to resent you and not want to give you the job.

    Of course, one could argue that you wouldn't want to work for someone who refuses to admit his own mistakes and demands that everyone who works for him treat every stray remark he makes like a pronouncement from God. It all depends whether you're looking for the perfect job, or if you're currently unemployed and will take ANYTHING that pays the bills.
  • NE 2008-07-30 13:03
    It claims succinctly with the example that the code always runs: http://msdn.microsoft.com/en-us/library/ke0zf0f5(VS.71).aspx

    Of course the documentation does suggest you run resource clean up in there, but who reads between the lines anyway?
  • Sutherlands 2008-07-30 13:04
    kswanton:

    One of the questions was 'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.
    I said the same thing, except the question asked of me was something to the tune of "How would you find if you have a circular reference and where that reference begins." To that, I replied something similar to yours, and the interviewer asked me if I could think of anything else... to which i said "Not off the top of my head." The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference. If you encounter the end, you don't. However... that only works when you're not trying to find the beginning of the list... which my interviewer decided to add on to the question. (The actual question is from what Google made up for one of their interviews when they were hiring, btw)
  • shepd 2008-07-30 13:18
    bcharr2:
    I've seen individuals with degrees and without who could program. I've seen individuals with degrees and without who couldn't program.
    That's what I'm getting at, I suppose. I've seen, around my area (EXTREME university influence), that >50% of employers list half-way decent paying jobs this way:

    Requirements:
    - Bachelor's degree or higher in Computer Science
    - Ability to commit to schedules

    Preferences:
    - Ability to program in [insert 5 - 10 current languages]
    - X years experience as an IT professional

    Then again, these places tend to be University upstarts that last for a couple of years and go bust (IMNSHO, due to a lack of perspective that you can only get from seasoned employees) so perhaps it's best they give me the warning up front.

    Every single place I've ever snagged an interview with has offered me a job. The thing is, even after having others in the industry review my resume several times, I get perhaps one interview out of two dozen applications. Usually due to the above requirements... *sigh* Luckily, I don't plan to leave my present job any time soon! Yay decent jobs! :-P Speaking of that, back to work...
  • GMo 2008-07-30 13:25
    Ken B:
    Human Resources was a bit peeved that my group was so “picky” with our candidates ad rejected all of the qualified candidates (read: one) that they had sent over.
    You could have said "and I suppose you wanted me to hire *all* of the candidates you sent over?"


    Logic doesn't work on HR types.
  • blagger 2008-07-30 13:26
    "Someone please educate me a bit: How does a database survive a power cycle in the middle of writing a transaction?"

    Any decent database has a transaction log. When the database comes back up it checks the log and rolls back any incomplete transactions.

    You're welcome.
  • Satanicpuppy 2008-07-30 13:30
    BentFranklin:
    Someone please educate me a bit: How does a database survive a power cycle in the middle of writing a transaction?

    Captcha: appellatio (A program that sucks?)



    Transactions don't mean jack until they're committed. That's the whole point. If it fails in the middle, the database will just toss the info as a bad write. If it fails the commit, same thing. If the commit succeeds, then there is no problem.

    Transactional databases can't have bad or incomplete writes. That's just the way it works.
  • jspenguin 2008-07-30 13:41
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing


    This will probably be said by several people before I finish typing this, but a "finally" block is always executed before the program continues -- even if you return or break from a loop from inside a "try" block.

    For example:

    public int connectAndGetStatus() {
    SomeConnection conn = new SomeConnection();
    conn.connectTo('example.com');
    try {
    return conn.getStatus();
    } finally {
    conn.close();
    }
    }


    In this case, conn.close() will be called whether conn.getStatus() succeeds or throws an exception. Since there is no catch clause, the exception will be propogated to the caller.

  • ok new as 2008-07-30 13:45
    its drum n bass but......
    ok was chatting with this girl 2nyt right, she was with her mum. her mom was yuck but damn she was hawt/ super sexy/ damn. shit fuck. JUNGLIST forever bitches. so hawt was her not het mom
  • Satanicpuppy 2008-07-30 13:55
    Axel R.:
    danixdefcon5:
    The only blooper I might pass, however, might be something like "Microsoft Sybase" or "Sybase SQL Server", as they are practically the same thing. Except Sybase actually runs in non-MS platforms!


    I hope your employer is not reading this, as MS SQL Server and Sybase SQL Server parted completely in... 1998 with the introduction of SQL Server 7.0


    I still work with both every day, and they're enough alike that I occasionally get confused. Compared with Oracle, mySQL, or Postgres, they're extremely close.
  • Markp 2008-07-30 14:08
    kswanton:
    One of the questions was 'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.

    The interviewer kinda smirked at me and said something along the lines of 'Well that is not efficient - is there a more efficient way to do it' to which I responded 'Not that I can think of...'


    Depends on what you mean by efficient. This is more memory efficient:

    public boolean hasCycle() {
    long counter = 0;
    Node node = first;
    while ( node != null && ++counter != 0 ) {
    node = node.next;
    }
    return node != null;
    }

    but doesn't have the greatest worst-case execution time. If the list kept an internal record of size, this would be a lot easier.

    I'd guess that the best solution would be a special case of checking a graph for cycles. And I'd also guess your solution would be the best for a typical programmer to be expected to know.
  • Smash King 2008-07-30 14:09
    - "Well, you state that you have years of experience on telecommunication. Is that right?"
    - "Yes sir, I do."
    - "Tell me more about your experience then"
    - "Well I... I, uhn, I watch 2 hours of TV everyday and I errrr... I make phone calls on average 3 times a day for the past 5 years..."
  • snoofle 2008-07-30 14:09
    Sutherlands:
    kswanton:

    One of the questions was 'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.
    I said the same thing, except the question asked of me was something to the tune of "How would you find if you have a circular reference and where that reference begins." To that, I replied something similar to yours, and the interviewer asked me if I could think of anything else... to which i said "Not off the top of my head." The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference. If you encounter the end, you don't. However... that only works when you're not trying to find the beginning of the list... which my interviewer decided to add on to the question. (The actual question is from what Google made up for one of their interviews when they were hiring, btw)

    I had someone ask me that. I also came up with the hash-solution. They responded with: what if the list is infinitely long? Figuring that this guy was an arrogant jerk for whom I no longer wished to work, I said: If you've got an infinite amount of data in a list, then your machine must have an infinite amount of memory in it, in which case it can handle an infintely large hash map. Then I laughed and walked out on him without another word.
  • snoofle 2008-07-30 14:13
    Markp:
    kswanton:
    One of the questions was 'How would you detect if you had a circular reference in a linked list?'...


    Depends on what you mean by efficient. ... I'd guess that the best solution would be ...

    Personally, I believe the best real-world solution is to make sure you don't insert the duplicate entry BEFORE doing the insert (maybe a linked list isn't the best choice if you don't want dups), but stupid interview questions warn you about the idiot in front of you, and for that I am grateful.
  • Ragnax 2008-07-30 14:14
    diaphanein:
    For instance, in C#, here's an example of a finally block that'll never execute, even without pulling the plug from your computer. The only output will be "Before fail fast":


    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace FailFast
    {
    class Program
    {
    static void Main(string[] args)
    {
    try
    {
    Console.WriteLine("Before fail fast");
    Environment.FailFast(null);
    Console.WriteLine("After fail fast");
    }
    finally
    {
    Console.WriteLine("in finally block");
    }
    }
    }
    }


    Environment.FailFast is a method implemented on the C# runtime environment object and is specifically designed to fail without executing try-finally blocks (or finalizers, for that matter). That makes it a special case.

    Besides: as far as I can tell the method only came into being with the .NET 2.0 framework, whereas the article reflects on the .NET 1.0 days...
  • WhiskeyJack 2008-07-30 14:20
    Sutherlands:
    The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference. If you encounter the end, you don't. However... that only works when you're not trying to find the beginning of the list... which my interviewer decided to add on to the question. (The actual question is from what Google made up for one of their interviews when they were hiring, btw)


    I'm not grokking this. Is there an explanation somewhere of how that would work?
  • Smash King 2008-07-30 14:22
    snoofle:

    I had someone ask me that. I also came up with the hash-solution. They responded with: what if the list is infinitely long? Figuring that this guy was an arrogant jerk for whom I no longer wished to work, I said: If you've got an infinite amount of data in a list, then your machine must have an infinite amount of memory in it, in which case it can handle an infintely large hash map. Then I laughed and walked out on him without another word.

    The infinite memory chips overheat until they melt, now what do you do?
  • danixdefcon5 2008-07-30 14:25
    Dave:
    Jason Bock:
    Holy crap, DON'T catch the general exception type!


    As long as you rethrow its not the end of the world.
    You just described the default behavior for a certain "custom" library I'm forced to use. Somewhere inside the thing, a simple method to get a connection from a DataSource throws an Exception, instead of the more manageable SQLException. Gaaah!
  • dzurn 2008-07-30 14:28
    Wait a second ... "Min" ... "Min"... Minuet?!

    This is just an elaborate holodeck fantasy!
  • Goplat 2008-07-30 14:31
    There's nothing better than a hash table? How about the tortoise-and-hare algorithm?

    int hasCycle(node *first) {
    node *t = first;
    node *h = first;
    do {
    if (!h) return 0;
    h = h->next;
    if (!h) return 0;
    h = h->next;
    t = t->next;
    } while (t != h);
    return 1;
    }
  • danixdefcon5 2008-07-30 14:32
    Alex Papadimoulis:
    ... but to expand on that, from a code perspective, if you're lucky enough to have an underlying transactional system, it's like this:

    try { StartTransaction(); DoStuff(); }
    catch { RollbackTransaction(); }
    finally { CommitIfNotRolledBack(); }

    The underlying transaction system will auto-rollback if it never gets committed or rolledback. However, the *real* problem occurrs when someone doesn't have an underlying transactional system.

    try
    {
    ProcessAllRecords();
    }
    catch //(or a conditional finally)
    {
    UndoAllProcessing();
    }

    If ProcessRecords() is not designed to be re-entrant, then you're pretty much screwed if an error occurs *and* UndoAllProcessing() never is run.

    To make matters worse, these problems compound themselves, so the second time you run the program, the un-catchable exception occurs again and further corrupts the underlying data.

    Finally should be used for things like memory cleanup so you don't end up with leaks, etc. If the program never hits that kind of finally block, it's OK, since the whole thing has crashed and burned already, and memory leaks are the least of your worries.
    Yeah, but not using a transactional system is a major WTF in itself! That was the reason I was infuriated when reading the MySQL 3.x documentation, and reading "Transactions are for losers, we don't support it, we can do all of that with LOCK TABLES!" or something along those lines.

    I migrated all my stuff back to PostgreSQL after reading that. Mind you, there was already Sleepycat BDB and InnoDB support, but I just couldn't bear with the idea of using a DBMS built by people who think transactions are not critical. Kind of like building a big ship with no life-rafts because "we don't need them" ... oh wait, somebody did that already.
  • alegr 2008-07-30 14:33
    Camel Chase:
    Also a finally gets executed no matter what Exception hits.

    Consider:

    try {
    db.begin;
    // do Stuff
    Object o = null;
    o.getClass(); // NullPointerException

    db.commit();
    db.close(); // <--Problem
    db = null;
    } catch (NumberFormatException nfe) {
    db.rollback();
    db.close;
    db = null;
    // return error
    } finally {
    // free the db handle.
    if (db != null) {
    try {db.rollback(); db.close();} catch (Exception e) {}
    }
    }


    Your code is probably wrong (not cxhecking for null), but it doesn't chew up your db handles.

    kthxbye.


    If your close() function can fail, you're doing it wrong. Any "finalising" actions, such as destructors are not supposed to ever fail. Just call close() in finally {}.
  • Joseph 2008-07-30 14:39
    Does Min know Max?
  • Ryeen 2008-07-30 14:43
    I believe their faces turned white after continuing to argue when they asked you to move on. I don't see how arguing with an interviewer is very productive and might be a good time to let trivialities slide.
  • diaphanein 2008-07-30 14:43
    Ragnax:

    Environment.FailFast is a method implemented on the C# runtime environment object and is specifically designed to fail without executing try-finally blocks (or finalizers, for that matter). That makes it a special case.

    Besides: as far as I can tell the method only came into being with the .NET 2.0 framework, whereas the article reflects on the .NET 1.0 days...


    Ok:


    System.Diagnostics.Process.GetCurrentProcess().Kill();


    Is that 1.0 enough for ya? Point is, unless you write it, you can't be sure what your call will do.

    And special case(s) or not, it still invalidates the assertion that the final block always executes.
  • secundum 2008-07-30 14:45
    ok new as:
    so hawt was her not het mom

    I have all of these technologies listed on my resume, too.
  • Franz Kafka 2008-07-30 14:46
    Andrew:
    The arguments over try...catch...finally remind me of a story about the Java finalize() method. This mehod has far worse indeterminant behavoir than try...catch...finally.

    We had an otherwise brilliant programmer, with a C/Perl/CGI background but not Java. He even had a Master's degree in computer science.

    He was tasked with writing a JSP webapp for the company. The application usually ran fine, but occasionally it randomly executed some code.

    After much discovery, he found out that his AppClass.finalize() also overrode the Object.finalize() method. The garbage collector was running his method at random intervals.


    Well duh... finalize is for cleaning up objects before you kill them. I'd use it too, for network connections and stuff, but it isn't guaranteed to run.
  • Leak 2008-07-30 14:46
    Alex Papadimoulis:

    try { StartTransaction(); DoStuff(); }
    catch { RollbackTransaction(); }
    finally { CommitIfNotRolledBack(); }

    I prefer

    try { StartTransaction(); DoStuff(); CommitTransaction(); }
    catch { /* handle the exception */ }
    finally { RollBackIfNotCommitted(); }

    since you only need one commit and one rollback in total - usually in C# I just set the variable I used for the transaction object to null and call it's rollback method in the finally block only if it isn't null.

    np: Meat Beat Manifesto - Radio Babylon (Beach Blanket Bimboland Mix) (Auntie Aubrey's Excursions Beyond The Call Of Duty Part 2 (Disc 2))
  • Uncle Paul 2008-07-30 14:47
    1.) Hire Min.
    2.) ???????
    3.) Profit!
  • Eam 2008-07-30 14:56
    danixdefcon5:
    Dave:
    Jason Bock:
    Holy crap, DON'T catch the general exception type!


    As long as you rethrow its not the end of the world.
    You just described the default behavior for a certain "custom" library I'm forced to use. Somewhere inside the thing, a simple method to get a connection from a DataSource throws an Exception, instead of the more manageable SQLException. Gaaah!


    Easy now. If that's how it works when the library re-throws, they're not really re-throwing, they're creating a new exception.

    It sounds like you're using .NET, so you should use:
    try {...} catch (Exception) { ...; throw; }

    Not:
    try {...} catch (Exception e) { ...; throw e; }
  • Crabs 2008-07-30 15:05
    Brian:
    Wow, alot of people don't understand try/catch/finally here. It makes no sense to put a return statement in your finally block. If you think it does then you miss the point of finally.


    I agree with you. Finally should be used to do things that need to get done after either your try or your catch finished. Something like this:

    SqlConnection sql = new SqlConnection();
    try{
    sql.Open();
    SqlCommand crapCommand = new SqlCommand("THIS IS A CRAP SQL CALL", sql);
    crapCommand.ExecuteReader(); //fails
    return 1;
    }
    catch{
    return 0; //this ends up happening
    }
    finally{
    sql.Close(); //this is what finally is for. otherwise your connection stays open foreverz
    }

    finally happens after the return statement. You should never have a return statement in your finally, as that's just weird. I'm sure it works somehow, but it's just not right.
  • SomeOne 2008-07-30 15:12
    More important than the finalize, was Min hot?
    My company should use that as a hiring requirement.
  • mister so-and-so 2008-07-30 15:12
    So, why not just fire him for being incompetent? How did you know that he and the clairvoyant were even the same person? Seems awfully petty to me, dog forbid he share the same name as a sex offender.

    (captcha "acsi")
  • Brandon 2008-07-30 15:15
    The Vicar:
    Brandon:
    if(computer.IsOver || computer.IsAboutToBeOver)
    {
    //execute critical business code
    }

    I win.

    You forgot to add

    if(Virus == Very Yes)

    You won, but that's not a good prize.


    I also forgot to check for the "Flagrant System Error" in the first place. I guess that could get included in the "computer.IsAboutToBeOver" variable.
  • cconroy 2008-07-30 15:16
    Joseph:
    Does Min know Max?


    Yes. They met at AVG.
  • silent d 2008-07-30 15:17
    Steve:

    <snip>

    "Max" eventually got reassigned to another group which, to the best of my knowledge, has never produced anything beyond interiminable meetings and hangs on by attaching itself remora-like to other successful projects. Everyone seems happy.


    You forgot the part where Min marries Max, they have a child named Avg, and *then* they all lived happily ever after.
  • The Heretic 2008-07-30 15:29
    At this point, I suggested that his solution was flawed - what if the circular reference did not point back to the first element, it would fail to detect it, such as:

    A points to B which Points to C which points back to B. In this case you'll never get back to 'A'.

    He ended the interview at this point and I never heard from them. Not sure if this was the reason why they did not call back or if it was just due to other reasons... or my solution *was* shitty... I guess I don't really care, the job was downtown, which I try to avoid like the plague.
    I don't know about your solution, but his solution was flawed and I would guess that his ego was what ended the interview.
  • Gamma 2008-07-30 15:30
    JonC:
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.

    That would have been setting alarm bells ringing immediately for me.


    Yeah, but it will pass HR screening. HR is the real WTF.
  • jg42 2008-07-30 15:30
    Was Min cute? ;-)
  • Edudbor 2008-07-30 15:43
    As far as I'm concerned lying to get an interview is different than lying THROUGH an interview.

    What Min did, in my eyes, was not lying. Now, the article presents it in such a way that we are to believe she had no coding skills at all. So, okay, she wasted the interviewers time. But when you consider that applicants are almost always passed through an HR person who is non-technical in SOME cases lying makes perfect sense.

    I was a C# developer that relocated across the country to a small town with limited employment opportunities. There was a company hiring for a VB.Net developer and they required 1-2 years of experience with VB.Net.

    I had 0 years of experience with VB.Net but I was a decent junior level C# developer. Aside from not having any VB.Net experience I was really a good fit for the job. I changed my resume to say 'C#/VB.Net Developer' at my last job. Because I did that, my resume made it to level 2, an actual developer/manager who would be the one doing an actual interview.

    The interview itself went well. I was given a technical test, in VB.Net. I was able to pass it. I also explained in the interview that the 'majority' of my previous work was in C# and not VB.Net but that there were certainly more similarities than differences between the two, what with the same .Net Framework and all.

    I ended up getting the job. Had I not changed my resume I would not have gotten an interview.
  • real_aardvark 2008-07-30 15:57
    zoips:
    anon:
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    also, any "mission critical" tasks would fare the same, and should have been recorded in a log system like a database uses instead of being 100% reliant on the code always executing


    finally is intended for (an attempt at) graceful cleanup when you plan to propagate the exception up the stack. At least that's always been my impression.
    Ah yes, the finally block: the goto of the modern world. An impression that many of the comments above reinforce.

    Then again, I got involved today in a half-hour's worth of heated discussion on the semantic benefits of using a while loop in C where a for loop was proposed, even though I know that in an abstract sense they're identical. Reliance on a 'break' statement seems to offend my maintenance-programmer sensibilities, I suppose.

    That reminds me -- must go off and check the C99 standards question that occupied the other seven and a half hours. Ta-ta!
  • krupa 2008-07-30 16:01
    // this comment will be read regardless of how you leave the site.
    }
  • Sutherlands 2008-07-30 16:02
    WhiskeyJack:
    Sutherlands:
    The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference. If you encounter the end, you don't. However... that only works when you're not trying to find the beginning of the list... which my interviewer decided to add on to the question. (The actual question is from what Google made up for one of their interviews when they were hiring, btw)


    I'm not grokking this. Is there an explanation somewhere of how that would work?

    Someone posted a solution already, but here's a simplified one.

    boolean isCycle(*head)
    {
    slow = fast = head;
    try
    {
    do
    {
    slow = slow->next;
    fast = fast->next->next;
    }while(slow != fast)
    return true
    }
    catch(NPE)
    {
    return false
    }
    }

    so if the fast one gets to the end of the list, there's no cycle. If the slow one meets the fast one, you know the fast one looped around at least once.
  • Vechni 2008-07-30 16:09
    Markp:
    Contractor Khan:
    VB life support machines. *Shudder*.


    Is that
    a) life support machines developed in VB, or
    b) Min, the "machine" used to keep a VB application alive?


    i don't understand "life support" i just said i did so maybe i get job? and maybe i save life?
  • real_aardvark 2008-07-30 16:12
    Satanicpuppy:
    Transactions don't mean jack until they're committed. That's the whole point. If it fails in the middle, the database will just toss the info as a bad write. If it fails the commit, same thing. If the commit succeeds, then there is no problem.

    Transactional databases can't have bad or incomplete writes. That's just the way it works.
    Granted that they minimise them. This is, however, a preposterous statement in the absolute. "Hello, little cosmic ray -- please don't burn a teeny but catastrophic hole in my transaction log."

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?

    I imagine that there might be an extremely sophisticated and locked-in system that could make this guarantee -- possibly through some sort of staggered RAID -- but it would be slow as shit and I doubt generally available.

    I worked on an OS file-system with built-in ISAM and transactional support, running on fault-tolerant hardware, and believe me, when it went down hard, all this guaranteed you was a half-day waiting for expensive dedicated support to patch the end of the base files back together again.
  • real_aardvark 2008-07-30 16:16
    blah:
    TRWTF is this article has more sloppy typos than Min's resume's bad Engrish.
    What, then, makes you suppose that Min's resume contained any bad English?
  • JL 2008-07-30 16:20
    danixdefcon5:
    Same I thought. Finally blocks always execute, the only way they wouldn't execute would be in situations where no code will get executed, like kill -9'ing the process, or on power down. Anyway, any critical transactions should be inside a transaction block themselves, so these two cases would cause an auto-rollback anyway!

    Note: finally blocks will run even if the exception thrown is an unchecked one (i.e. RuntimeException).

    No need for anything exotic. Even Visual Basic's ridiculous "End" command will abort finally blocks:

    Module Module1
    Sub Main()
    MsgBox("Started!")
    Try
    End
    Finally
    MsgBox("Ended!") ' Never executed
    End Try
    End Sub
    End Module
  • Steve 2008-07-30 16:27
    I heard that Paula Bean is now Min's supervisor.

  • Henry 2008-07-30 16:28
    Looks like Mi 'won'. Guess it goes to show, well all have to cut our teeth somewhere (somewhere else preferably)
  • PS 2008-07-30 16:29
    morry:

    where are you supposed to put the code? Magic fairy blocks?


    That's actually a genious idea. I propose this as an addition to the next version of the .NET framework.


    try {
    doStuff();
    }
    finally {
    semiCriticalTransactionCode();
    }
    magicFairyFinally {
    // Will ALWAYS run, even if the machine has no power
    criticalTransactionCode();
    }
  • Pfhreak 2008-07-30 16:33
    Sutherlands:

    Someone posted a solution already, but here's a simplified one.

    boolean isCycle(*head)
    {
    slow = fast = head;
    try
    {
    do
    {
    slow = slow->next;
    fast = fast->next->next;
    }while(slow != fast)
    return true
    }
    catch(NPE)
    {
    return false
    }
    }

    so if the fast one gets to the end of the list, there's no cycle. If the slow one meets the fast one, you know the fast one looped around at least once.


    This will work, but using try/catch that way is really not a best practice. The previous solution, which explicitly checked for the null values is a better solution. (Even though they achieve the same thing exactly, and my argument is largely based on coding semantics.)

    Also, the previous solution would be (almost immeasurably) faster, as exceptions are hardly the speediest operation. If you were doing N of these comparisons each unit time, you'd be wasting a lot of resources just handling that NPE.

    Also, captcha was 'nulla'.
  • Franz Kafka 2008-07-30 16:35
    real_aardvark:

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?


    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.
  • PS 2008-07-30 16:44
    JL:
    Even Visual Basic's ridiculous "End" command will abort finally blocks


    Speaking of the End command...

    http://www.devx.com/tips/Tip/12443
  • Saaid 2008-07-30 16:45
    Franz Kafka:
    real_aardvark:

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?


    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.

    Flush() is broken, then what do you do?
  • Jeff S 2008-07-30 16:46
    real_aardvark:
    Ah yes, the finally block: the goto of the modern world. An impression that many of the comments above reinforce.


    Huh? So what are you saying? You believe that using Finally is a bad practice? I have no idea what correlation you are drawing between finally() and goto...
  • Mikeh 2008-07-30 16:47
    I almost never use finally, if you want to do stuff after a try-catch block then you don't really need the finally, these two blocks are almost always the same:


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }


    try
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    return result


    The difference is when you do something like this:

    try
    {
    //do something that could throw an error
    return "something";
    }
    catch(Exception ex)
    {
    return "something else";
    }
    finally
    {
    //Always executes
    }

    Business critical logic should always be done in transactions if you're trying to avoid only half of something being done.
  • Franz Kafka 2008-07-30 16:50
    Saaid:
    Franz Kafka:
    real_aardvark:

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?


    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.

    Flush() is broken, then what do you do?


    Install your DB on a different platform.
  • Technical Thug 2008-07-30 16:54
    Franz Kafka:
    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.


    Flush() guarantees that you've pushed the data as far out as the OS can push it, but you still don't know where it's sitting. Is this an NFS connection? Are you inside a blade machine where all the blades are using each other's hard drives?

    It's really hard to really make sure the bits are on metal without violating a whole big pile of abstraction barriers.
  • jhunter 2008-07-30 16:58
    It depends on the language evidently because it doesn't with C#.

    class Program
    {
    public static void Main(string[] args)
    {

    try
    {
    Console.WriteLine("Attempting to access property");
    int x = Number;
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
    finally
    {
    Console.WriteLine("Finally block run");
    }
    }

    private static int Number
    {
    get { return Number; }
    }
    }

    Output


    C:\>TestApp.Console.exe
    Attempting to access property

    Process is terminated due to StackOverflowException.

    C:\>
  • real_aardvark 2008-07-30 17:01
    Jeff S:
    real_aardvark:
    Ah yes, the finally block: the goto of the modern world. An impression that many of the comments above reinforce.


    Huh? So what are you saying? You believe that using Finally is a bad practice? I have no idea what correlation you are drawing between finally() and goto...
    OK, the correlations:

    (1) goto is generally deprecated.
    (1a) A better alternative to goto is almost always available.
    (1b) In severely restricted and well-controlled circumstances (see Torvalds and Linux Kernel), goto is still the best solution.
    (1c) In 99.999% of circumstances where goto is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using goto is a mistake.

    I am now going to employ cut-n-paste -- another mistake, generally, but utilised here to emphasise my point. I promise you that the only change I will make is a simple substitution (well, two, because I'll lose the Torvalds analogy):

    (2a) A better alternative to finally is almost always available.
    (2b) In severely restricted and well-controlled circumstances, finally is still the best solution.
    (2c) In 99.999% of circumstances where finally is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using finally is a mistake.

    Counter-propositions welcome.

    Use RAII instead. This even works, in the usual half-assed way, with languages that have garbage collectors.
  • anon 2008-07-30 17:01
    My Tales:
    Easy now. If that's how it works when the library re-throws, they're not really re-throwing, they're creating a new exception.

    It sounds like you're using .NET, so you should use:
    try {...} catch (Exception) { ...; throw; }

    Not:
    try {...} catch (Exception e) { ...; throw e; }


    You are correct that it's bad form to throw (instead of rethrow) a caught exception, but you're incorrect in assuming that would change the exception type. The "custom" library must be doing:

    try {...} catch (Exception e) { ...; throw new Exception(); }

    I'd question, however, if the InnerException is properly set from the "custom" library. If so, I'd say they picked the wrong exception type to throw, but the original poster is making a mountain out of a molehill. If not, then yeah, that library should be dropped immediately.
  • BentFranklin 2008-07-30 17:06
    If 100% data integrity all the time is your requirement, I wonder if you could store trx in a special non-volatile RAM board until a read from the disk verifies that the write worked?
  • Franz Kafka 2008-07-30 17:11
    Technical Thug:
    Franz Kafka:
    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.


    Flush() guarantees that you've pushed the data as far out as the OS can push it, but you still don't know where it's sitting. Is this an NFS connection? Are you inside a blade machine where all the blades are using each other's hard drives?


    You're a DB server. The redo log is not on an NFS server. It's on its own disk, probably.

    /esse
  • hamsandwich 2008-07-30 17:12
    real_aardvark:
    Jeff S:
    real_aardvark:
    Ah yes, the finally block: the goto of the modern world. An impression that many of the comments above reinforce.


    Huh? So what are you saying? You believe that using Finally is a bad practice? I have no idea what correlation you are drawing between finally() and goto...
    OK, the correlations:

    (1) goto is generally deprecated.
    (1a) A better alternative to goto is almost always available.
    (1b) In severely restricted and well-controlled circumstances (see Torvalds and Linux Kernel), goto is still the best solution.
    (1c) In 99.999% of circumstances where goto is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using goto is a mistake.

    I am now going to employ cut-n-paste -- another mistake, generally, but utilised here to emphasise my point. I promise you that the only change I will make is a simple substitution (well, two, because I'll lose the Torvalds analogy):

    (2a) A better alternative to finally is almost always available.
    (2b) In severely restricted and well-controlled circumstances, finally is still the best solution.
    (2c) In 99.999% of circumstances where finally is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using finally is a mistake.

    Counter-propositions welcome.

    Use RAII instead. This even works, in the usual half-assed way, with languages that have garbage collectors.


    You're stating a bunch of opinions in a neatly-ordered list, not any real reasons to not use finally.
  • anon 2008-07-30 17:12
    (2a) A better alternative to finally is almost always available.


    Such as? The only one that comes to mind doesn't exist in most languages: desctructors and RAII.

    (2c) In 99.999% of circumstances where finally is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using finally is a mistake.


    Why? You have to back up an assertion like that (which was done for "goto").
  • Franz Kafka 2008-07-30 17:14
    BentFranklin:
    If 100% data integrity all the time is your requirement, I wonder if you could store trx in a special non-volatile RAM board until a read from the disk verifies that the write worked?


    Can't do that - reading from the disk goes through the block cache. 100% data integrity is usually a pipe dream, given most peoples' budget, so decide how much integrity you can afford and test your backups regularly.
  • Franz Kafka 2008-07-30 17:17
    real_aardvark:

    Use RAII instead. This even works, in the usual half-assed way, with languages that have garbage collectors.


    You can't do that with Java (maybe C#) because it doesn't support stack variables.

    To the guy bitching about r_a's assertions, he's just lambasting the whole 'finally is a fancy goto' meme.
  • real_aardvark 2008-07-30 18:36
    hamsandwich:
    You're stating a bunch of opinions in a neatly-ordered list, not any real reasons to not use finally.
    I'll save my breath and just shout at the top of my voice, then.

    "In 99.999% of circumstances where finally is used, it is a mistake." (I mentioned this earlier, but I haven't scratched it against a windshield. It may very well not be a real reason. It's probably just fools' gold, like every second job I've done in the last eight years or so.)

    I wasn't asked to give anybody a reason <not to> use finally. I was asked to justify the "correlation," or, as I would put it, "analogy," between goto and finally. Read between the lines. Indeed, read inside the lines. That was the intended purpose of the lists.

    If you're lazy and stupid and only moderately capable of tying your own boot-laces on a good day, then, by all means, continue to use finally. (I don't much like continue, either.)

    If you've seriously thought about the alternatives, and decided that they were worse options, then, by all means, be my guest.

    The general alternative is to make sure you don't leave a resource or a state or a calculation dangling until you're pretty damn sure it's valid: but, hey, that's design, right? We're programmers, not designers. We just hack the thing about until blood stops spurting, and then we call it pizza nd eat it. (Mine's with extra anchovies. I miss female companionship since my mother died.)

    If you've read all of the posts in this thread that make ludicrous claims about the use of finally, and you still think that it's the best option for you and for the four or thirteen or one hundred maintenance programmers who will follow on after you, then I'm truly happy to find somebody who actually thinks before he types the F-word.

    It was two lists, btw. That's kind of how analogy with goto ought to work, imho.

    You really, really, really want a simple answer? Here it is.

    Practically anything that is done in a procedural language using a finally block should, in fact, be done during object clean-up. DRY, man, DRY. Also, do not force yourself to depend upon arbitrary cross-dependencies between objects (and here I include functions, if you want to deal with a fully first-class language), any or all of which may have side-effects.

    Good enough for ya?

    If you really, really, want my opinion on the one true reason not to use finally, except in extremis, then buckle up your basic C++ skills (it really doesn't take much, and a decent Java or C# programmer should be able to follow the argument through), and read Herb Sutter. There is no finally in C++. This doesn't make me think that C++ is an inherently better language than any other (far from it) -- but it does make me wonder what the fuck other languages really need a finally clause for.

    Think again. Several times over, please.

    There will be a pop quiz during recess.



  • real_aardvark 2008-07-30 18:42
    anon:
    (2a) A better alternative to finally is almost always available.


    Such as? The only one that comes to mind doesn't exist in most languages: desctructors and RAII.
    Gosh, I was unaware that languages other than C++ leave objects, memory, and other resources just dangling around until somebody hits the three-fingered salute.

    That would, obviously, make "destructors" and "RAII" absolutely impossible to implement.

    As opposed to, say, deterministically impossible to implement.

    Addendum (2008-07-30 18:48):
    anon:
    (2a) A better alternative to finally is almost always available.


    Such as? The only one that comes to mind doesn't exist in most languages: desctructors and RAII.
    Gosh, I was unaware that languages other than C++ leave objects, memory, and other resources just dangling around until somebody hits the three-fingered salute.

    That would, obviously, make "destructors" and "RAII" absolutely impossible to implement.

    As opposed to, say, deterministically impossible to implement.

    Note the qualifier "almost," incidentally. It's sort of like lazy evaluation in the case of garbage collectors: except that in their case it's more like lazy euthanasia.
  • facilisis 2008-07-30 18:45
    Morasique:
    Usually databases use journaling, so the change is logged in the journal before it actually happens. When the database starts, it checks the end of the journal to make sure it wasn't killed abnormally, and rolls back or commits whatever it needs to based on the journal to make the actual database consistent


    Your database's journal file was corrupted by a catastrophic multiple drive head crash in your DB's raid array because of an earthquake. THEN, the power goes out in the middle of the transaction, from the same earthquake.

    Now what does it do?
  • AcidBlues 2008-07-30 19:17
    Sorry, this does not seem right. My understanding is that the list could contain a reference like a->next == a, in which case neither the slow nor the fast ever reach the end of the list, yet it contains a circular reference.

    Oh, way to go Google interviewers.
  • AcidBlues 2008-07-30 19:22
    Cannot speak about anything else than Oracle, but in the case of Oracle, you will be able to recover up to the last transaction ("redo") log you have a copy of. In Oracle you define the interval of the copies and the maximum size of your redo logs, so if you want to lose the least amount of data in the case of such a disaster, you'll probably define fairly small log files with very frequent flushes, better to off-size storage.
    Then you'll be able to recover up to the last of those saved logs.
    Of course, you pay a price in performance for running Oracle is this mode, but if you have such stringent data retention policies, you'll probably have the money to ensure them.
  • tgape 2008-07-30 19:27
    Morasique:
    BentFranklin:
    Someone please educate me a bit: How does a database survive a power cycle in the middle of writing a transaction?

    Captcha: appellatio (A program that sucks?)



    Usually databases use journaling...


    This is part of the answer, other posters have also given partial answers. For a more complete (and low-level, while still remaining generic) answer:

    A good database will arrange its write operations such that the difference between having not entered the data and having fully and correctly entered the data is a single, atomic (meaning, it can't be interrupted by anything short of a hardware failure - and generally, even a power failure will allow it to complete) operation.

    This is normally a very difficult task, especially if the database supports 'transactions'. Most modern databases use journalling, which makes it *much* easier (note: the below skips locking and parallelization, which would needlessly (because this isn't actual code) complicate the answer):

    1. You write what you are going to do.
    2. You update the journal end marker (a single, atomic update) to cover the new data.
    3. You update the database data for all of the operations involved.
    4. You update all the database indexes for the new data.
    5. You update the journal start marker to not include that entry (a single, atomic update)

    Now, there's two atomic updates there that have critical effects, rather than just one for a pre-journaling version. However, there's no need to dance around making dozens to hundreds of changes such that they don't take immediate effect until some later update occurs, because if it fails at any point after the journal is extended to cover the new update, the database will know exactly what it was trying to do, so can finish it up on restart. If it occurs before step two, then the operation never happened at all.

    Of course, on error, there's also rollback, as others have mentioned. I think that's been adequately covered in other posts, however.
  • Martin 2008-07-30 19:31
    A real problem that prevent using finalize(The java almost destructor method) as raii for java, is that finalize is not run on application shutdown.

    Why this matter, is that if you write to a file with a BufferedOutputStream and then stop the program then the content of the buffer will newer be flushed to the file, because the BufferedOutputStream is newer closed.

    This is not a problem with raii in c++, because there the normal stack unwinding would cause all destructors to be called.

    So relaying on the finalize method in java, to do needed cleanup and buffer flushing is not working. (Been there, done that, lost the data, patched the system, still looking for a reason that java don't run all finalize methods, when the cod reach the end of the normal Main method.

  • Edward Royce 2008-07-30 19:36
    Hmmmm.

    Reminds me of a Senior Visual C++ Developer who asked me in a whisper "how do I compile a program in Visual C++?".
  • lokey 2008-07-30 19:37
    Saaid:
    Franz Kafka:
    real_aardvark:

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?


    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.

    Flush() is broken, then what do you do?


    If the Flush() doesn't work, you call a plumber! I R A programmer now!
  • Leak 2008-07-30 19:42
    AcidBlues:
    Sorry, this does not seem right. My understanding is that the list could contain a reference like a->next == a, in which case neither the slow nor the fast ever reach the end of the list, yet it contains a circular reference.

    You seem to be forgetting that the loop also terminates if both pointers point to the same object, which in this case will happen immediately, and at worst after two runs through the loop...

    np: µ-Ziq - Goodbye, Goodbye (Royal Astronomy)
  • Edward Royce 2008-07-30 19:43
    SomeCoder:
    morry:
    never put critical business transaction code in finally blocks.

    I put all my absolutely critical business transaction code on a piece of paper, photograph it on a wooden table, then post that picture next to my computer. that way when the power goes out, I can execute the code myself.

    where are you supposed to put the code? Magic fairy blocks?



    That's what I was wondering. If you want a guarantee that your code will be executed... well I guess there are no guarantees. Don't use computers to execute business critical code?

    I guess my point is, if the computer is suddenly shut off, it doesn't matter where your put your code*, finally or no. It's not going to be run if the machine is off.


    *Note: I know it matters where you put business critical in an app but my point is, Alex was being a tiny bit pedantic in my opinion.


    Perhaps a UPS or two would give the computer enough juice to complete the finally block?

    As for pulling the plug. Really. Who has the god-like talent to cover every possible permutation of stupid?
  • tgape 2008-07-30 19:55
    techie:
    Not to be picky, but as someone who was promoted from tech support to programmer I've got a question. Did you actually ask any technical questions or are you just blindly assuming (like the wtf in your first example) that she didn't know how to program since she lied to get into the interview?


    I'm a big proponent of using the tech support pool as a breeding ground for new developers. I believe that the biggest cost of outsourcing helpdesk services is that it generally loses this method of acquiring new developers.

    That having been said, I would certainly not have hired Min - they weren't looking for a tech support person, but a developer. While the helpdesk does expose one to coding opportunities, and the best helpdesk workers will demonstrate a bit of coding expertise, which indicates they have developer potential, it does not strictly require coding capabilities.

    The helpdesk is also a unique environment, in that it generally does not provide a required programming language - so the tech can learn whatever language they are most comfortable with, and knowing that also tells you something about what the person would be good at. Of course, I don't know this from personal experience, having never worked on a helpdesk. But I've worked with a lot of people who have (many of them while they were working on a helpdesk.)

    In every programming environment I've worked in, there are always three things a new employee needs to learn: the culture, the management quirks, and the coding practices. Adding to this 'how to code', and 'how to better communicate with the rest of the team' is basically a non-starter. This was true even in the job where their requirements included "at least three programming languages - we don't care which ones". (Almost everything was written in a proprietary, in house language, which inherited concepts from C++, LiSP, Forth, ML, sed, awk, Ada, TCL, LPC, and COBOL. And that's just the ones I recognized.)

    If the candidate does know how to program in at least one language, just not one that is relevant to your group, it's still probably a non-starter. If the candidate speaks the group's preferred language natively *and* knows how to code in a couple of non-relevant languages, that's getting close to something that might possibly work, but it's still a huge amount to pick up.

    If I were interviewing Min, I would have continued the interview. If the company had an internal helpdesk, I probably would have recommended her for it. However, I would not have hired her myself. (If the company did not have an internal helpdesk, but she seemed like she had a lot of potential otherwise, I'd have recommended her to one of the various helpdesks I'm aware of.)

    Note: the team I'm on at work consists of six people (including myself). Of those six people, only one has not worked on a helpdesk. He's the one with the most seniority on the team, and got a say in the hiring or selecting of everyone else on the team. So far, out of about 30 candidates considered, he's vetoed all but two of the candidates with no helpdesk background, and not vetoed any of the candidates with helpdesk background.)
  • Sutherlands 2008-07-30 20:06
    AcidBlues:
    Sorry, this does not seem right. My understanding is that the list could contain a reference like a->next == a, in which case neither the slow nor the fast ever reach the end of the list, yet it contains a circular reference.

    Oh, way to go Google interviewers.
    Yes, go Google interviewers, because you successfully weeded out someone who didn't realize that a circular list has no end.
  • Sutherlands 2008-07-30 20:13
    real_aardvark:
    hamsandwich:
    You're stating a bunch of opinions in a neatly-ordered list, not any real reasons to not use finally.
    I'll save my breath and just shout at the top of my voice, then.

    Ignoring, for a moment, that fact that you just said you would save your breath by shouting, your post has no substance.

    If someone made the following post:
    A car is just like an orange:
    A car can transport people very quickly
    A car can be many colors
    A car has multiple seats

    An orange can trasport people very quickly
    An orange can be many colors
    An orange has multiple seats

    We wouldn't believe them, just like we didn't believe you. I can say "In 99.9999% of circumstances where static is used, it is a mistake." and then list off a bunch of hamball reasons why it's the same as goto, but that doesn't make it true. You're right that you were asked to justify the correlation, and yet, you failed to do that.

    Then, you finally come back and repeat a bunch of stuff that doesn't make any sense, bolding words for no real reason, and try to pretend that you know more than everyone else. There are lots of things, like closing transactions, that should not be done in object cleanup. That would make absolutely no sense. When we come to your "one true reason" not use finally, you say because C++ doesn't have it? Wow, you sure know your stuff.
  • tgape 2008-07-30 20:14
    Contractor Khan:
    Min is the reason why you should keep files on people that applied, as you are allowed to, for 6 months, with NOTES on what they admitted lying about.

    VB isn't that hard I suppose, what's the worst that could happen.

    VB life support machines. *Shudder*.


    Min isn't that bad - she admitted fairly quickly that she'd lied on the resume. The ones I like to keep notes on are the ones who fail even the most basic language questions, yet insist that they're masters of it. Like the 'unix guru' who supposedly doesn't know any unix commands because he's aliased them to their dos equivalent and promptly forgotten about it - but he also doesn't know 'fdisk'. (Of course, if the guy otherwise knew how unix worked, he could recover even from that - I tend to be fairly thorough before I decide to try to ban someone from working in my company.)

    However, that having been said, the real problem is that the people who do interviews assuming all of the assertions on the resume are true (or, worse, assuming that the fact that HR approved the interview means that the candidate's resume matches the requirements one sent to HR) are the same people who don't check the list of candidates to never hire.

    That having been said, I'm still chuckling about the time one of these managers hired a guy who had put '20 years experience with Java' on his resume (and this was years ago, even!) For the curious, said individual apparently did not know Java - unless there's a dialect that looks strangely like poorly written BASIC. I know because I'd asked him write a Java function to do some silly task. Oh, and for what it's worth, when I interviewed him, his resume said '25 years experience with Java', but I'd advised him Java wasn't quite that old.

    Note: chuckling was all I ever had to do about it, because the guy managed to totally wash out, very quickly, in a manner that made said manager look rather incompetent, and created no work for myself.
  • Jeff Grigg 2008-07-30 20:27
    Re: "never put critical business transaction code in finally blocks."

    Well, yes...
    I would suggest that really important code is better placed in the "try" block. And really important business code should probably be within the scope of a database transaction too.

    (As a practical matter, exceptions thrown /from/ a finally block can be problematic. Be Careful!)
  • Euler Enthusiast 2008-07-30 20:38
    WhiskeyJack:
    I'm not grokking this. Is there an explanation somewhere of how that would work?


    There.
  • danixdefcon5 2008-07-30 20:48
    anon:
    My Tales:
    Easy now. If that's how it works when the library re-throws, they're not really re-throwing, they're creating a new exception.

    It sounds like you're using .NET, so you should use:
    try {...} catch (Exception) { ...; throw; }

    Not:
    try {...} catch (Exception e) { ...; throw e; }


    You are correct that it's bad form to throw (instead of rethrow) a caught exception, but you're incorrect in assuming that would change the exception type. The "custom" library must be doing:

    try {...} catch (Exception e) { ...; throw new Exception(); }

    I'd question, however, if the InnerException is properly set from the "custom" library. If so, I'd say they picked the wrong exception type to throw, but the original poster is making a mountain out of a molehill. If not, then yeah, that library should be dropped immediately.
    Heh. The problem is that the method itself is defined as, say

    public void setConnection(String dataSourceName) throws Exception {
    ...
    }

    so even if I know the inner exception might be an SQLException, I still have to check for the general java.lang.Exception case (ok, I'm also answering which language I'm using). Given the state of other code I've found, I almost expect the "re-throw" to be something like this:

    catch (Exception e) {
    throw new Exception("Couldn't connect to the DB! :(");
    }

    Some calls are nice enough to include e.getMessage(), but no stack trace at all. My solution? I give that function its own try/catch block, then re-throw it as a new SQLException.
  • Edward Royce 2008-07-30 20:51
    Sutherlands:
    WhiskeyJack:
    Sutherlands:
    The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference. If you encounter the end, you don't. However... that only works when you're not trying to find the beginning of the list... which my interviewer decided to add on to the question. (The actual question is from what Google made up for one of their interviews when they were hiring, btw)


    I'm not grokking this. Is there an explanation somewhere of how that would work?

    Someone posted a solution already, but here's a simplified one.

    boolean isCycle(*head)
    {
    slow = fast = head;
    try
    {
    do
    {
    slow = slow->next;
    fast = fast->next->next;
    }while(slow != fast)
    return true
    }
    catch(NPE)
    {
    return false
    }
    }

    so if the fast one gets to the end of the list, there's no cycle. If the slow one meets the fast one, you know the fast one looped around at least once.


    But if there's no circular reference isn't that an infinite loop?

    Uhhh. Forget me. I'm on beer #3 so I'm probably talking out my rear end.
  • Chris 2008-07-30 21:38
    Actual the reason it doesn't work in java is that there are no guarantees when the finalize will be run. It could take quite a long time for it to run and for all that time the database connect, file, or whatever is still open.

    Finalizers are still useful for a failsafe but the prefered way should be explicit methods for closing (or rollback/commit, etc) in a final block.

    You can solve the problem you mentioned by calling System.runFinalizersOnExit(true) someplace in the program.
  • Optimus Prime 2008-07-30 21:43
    Maybe she finally fixed her resume (no more Microsoft Solaris). And that might be the reason why she was hired by the other company XD
  • ysth 2008-07-30 22:30
    morry:
    where are you supposed to put the code? Magic fairy blocks?
    Well, in Perl, you could put it in the DESTROY method of an object stored in a positronic variable, and it would execute when the object goes out of scope at the beginning of your program, before the plug was pulled.
  • Noel 2008-07-30 22:46
    kswanton:
    I've only had one bad interview experience. The lead was called in to handle the technical portion of the interview, which was made up of a few questions.

    One of the questions was 'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.

    The interviewer kinda smirked at me and said something along the lines of 'Well that is not efficient - is there a more efficient way to do it' to which I responded 'Not that I can think of...'

    In a condescending way he suggested that there was a much better way to check, that was quicker, less memory intensive, etc etc, and gave me the hint 'What about the first item in the list??? - what can you do with it that would make this easier?' I should have seen that the solution he was driving at, even though I thought it was wrong. After a while he gave me his answer which was to just compare the first element to each additional element in the list, if you ever get back to it you have a circular reference, still smirking like he was the smartest guy that I'd ever meet.

    At this point, I suggested that his solution was flawed - what if the circular reference did not point back to the first element, it would fail to detect it, such as:

    A points to B which Points to C which points back to B. In this case you'll never get back to 'A'.

    He ended the interview at this point and I never heard from them. Not sure if this was the reason why they did not call back or if it was just due to other reasons... or my solution *was* shitty... I guess I don't really care, the job was downtown, which I try to avoid like the plague.


    I was asked this same question at the interview for my current job. The answer I thought up was to have a compare the size of traversing the list with the known number of elements, if you can traverse through more elements than you have something is obviously wrong.

    They found that acceptable, but then described their own answer (which was pretty obvious as soon as they said it - I guess thats the pressure of interviews) which is to have a flag indicating whether an element has been visited or not, if you are traversing the list and come to which which has already been visited then it has a circular reference. (this technique is known as colouring)
  • Noel 2008-07-30 22:53
    [quote user="bcharr2"][quote user="shepd"]
    There is no hard and fast rule to the "Who is better, the college taught or self taught programmer?", because no 2 job candidates are exactly alike.

    I've seen individuals with degrees and without who could program. I've seen individuals with degrees and without who couldn't program.
    [/quote]

    Stupid people will be bad programmers whether they are self taught or have gone through thorough training, and likewise smart people will be good whether they have gone through training or are self taught.

    In my experience, there are a lot of people who fall somewhere in between the stupid & smart boundaries, and where these people are self taught they usually know all the different libraries and API well, they know technical details to the most intricate detail, yet they will still use bubble sort to organise a list of 1million elements.

    languages and technologies are very easy to learn, theory not so much.
  • Noel 2008-07-30 23:29
    real_aardvark:
    There is no finally in C++. This doesn't make me think that C++ is an inherently better language than any other (far from it) -- but it does make me wonder what the fuck other languages really need a finally clause for.


    Fortran is not object oriented. This doesn't make me think that Fortran is an inherently better language than any other (far from it) -- but it does make me wonder what the fuck other languages really need to be object oriented for.

    Q.E.D.

    See.. here's how the proof works. If an old language doesn't have the exact same features as a newer language, then the newer language is wrong. Right? Right?
  • PhysicsPhil 2008-07-31 02:39
    Saaid:
    Franz Kafka:
    real_aardvark:

    In a more realistic scenario, you'are asking an awful lot of the disk hardware. Let's assume that the db/OS in question conscientiously flushes through cache and RAM and paging system to the actual storage. What guarantee do you have that bits of your transaction log aren't stuck in the disk controller logic, and haven't yet reached metal oxide?


    Flush() guarantees this. Of course, in the catastrophic case, that fails and you use backups. You can't be perfect, but you can get close.

    Flush() is broken, then what do you do?
    Call a plumber.
  • sirGustav 2008-07-31 04:35
    anon:
    try
    
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }

    What's wrong with

    if( IsZero(b) ) // handle divide by 0
    else return a/b
  • Ragnax 2008-07-31 05:22
    diaphanein:
    Ok:


    System.Diagnostics.Process.GetCurrentProcess().Kill();


    Is that 1.0 enough for ya? Point is, unless you write it, you can't be sure what your call will do.

    And special case(s) or not, it still invalidates the assertion that the final block always executes.


    Process.Kill() came with .NET 1.1, afaict. It also requires full trust, which by design you should never give to code you haven't written yourself (and probably shouldn't even give it to all your own code as well.)

    While it does invalidate the assertion that the finally block always executes, it does so on the same level as all the variations on 'pulling the plug' do. Actually, it's an even weaker statment: An outage (if you're not using a UPS on a critical system, which is a WTF in and of itself) is atleast unpredictable, but killing a process through code has to be done explicitly.



    Btw. for all the people discussing what the proper 'form' of a try-catch-finally is, in C# it's something like this:


    using (Transaction t = new Transaction())
    {
    DoStuff();
    t.Commit();
    }


    Dispose() will be called on the transaction object as soon as the running program leaves the scope of the using clause (which includes situations where an exception occurs). Dispose() then takes care of rolling back the transaction, etc. if it wasn't committed.

    The IDisposable interface in combination with the using() statement is C#'s version of RAII. Use it!
  • Casey 2008-07-31 05:26
    The real WTF is people using Java for anything critical enough where you would even need a finally to ensure something was done.
  • henke37 2008-07-31 06:01
    For the linked list question, I would just itterate forward through the list, and checking if the back pointer really points at the node we came from. If it doesn't, we got a loop. It is an O(n) complex algorithm that is guaranteed to stop.
  • SQB 2008-07-31 06:09
    real_aardvark:
    (2a) A better alternative to finally is almost always available.
    (2b) In severely restricted and well-controlled circumstances, finally is still the best solution.
    (2c) In 99.999% of circumstances where finally is used, it is a mistake. It may represent bad design, sloppy code, lack of attention to future maintenance issues, general ignorance, or simply a desire to sabotage the project. In summary, in the vast preponderance of usages, using finally is a mistake.

    Counter-propositions welcome.

    Use RAII instead. This even works, in the usual half-assed way, with languages that have garbage collectors.

    However, in languages without garbage collection, I find the use of 'finally' especially well suited for cleaning up in the presence of exceptions. Take this Delphi / Object Pascal example:
      foo := TFoo.Create();
    
    try
    foo.doStuff(); //may throw an exception
    foo.doSomeMoreStuff(); // may throw an exception as well
    finally
    FreeAndNil(foo);
    end;
    Voila! Exception gets propagated while foo is still disposed off. Surely you don't suggest catching the exception, cleaning up both in there as well as in the main flow (violating DRY!) and rethrowing? This example is such a common practice in Delphi that I wouldn't call that "severely restricted" or "0.001%".

    In summary, "finally" is just a regular construct to ensure some piece of code always runs in the presence of exceptions. RAII has its place, but in some languages you have no control over when a destructor runs, which may leave you tying up a resource for too long.

    Disclaimer: I'm well aware of the fact that using Delphi is TRWTF. Get over it.
  • tgape 2008-07-31 06:41
    anon:
    (2a) A better alternative to finally is almost always available.


    Such as? The only one that comes to mind doesn't exist in most languages: desctructors and RAII.


    Any object-oriented language which lacks destructors is pure FAIL. Use it, and you FAIL, sooner or later.

    The reason for this is that object cleanup is fundamentally necessary for certain types of objects. One must ensure that they get cleaned up when they go out of scope, or the program may not be able to run twice in succession.

    When the program crashes, these sorts of errors are expected - but very annoying, so it's preferred if the solution can do something to minimize the amount of trauma caused by a crash. However, normal executions should never have that issue.

    'Finally' blocks may work most of the time, but there's normal situations where they don't run. Also, using 'finally' blocks to simulate a destructor requires one to remember them for every block in which an object requiring a destructor is used. That's basically the exact same situation which motivated nearly all programmers to seek languages which had some form of automatic garbage collection: people couldn't remember to free all the memory they allocated.

    Incidentally, in my experience, languages which push exception handling rather than error handling also have a certain amount of fundamental fail. None have shown this to me more clearly than Java and Python - supposedly the languages with the best exception handling (at least, according to their adherents), yet over 95% of the Java and Python programs I've run have an incredible propensity to dump with a stack trace on any unexpected input. That stack trace may be useful to a developer, but when a normal user sees it, there's a good chance you're losing a user.

    Note: I have not run any Db programs directly, so I do not know if they have this propensity or not.

    (Just for comparison: using a combination of options intended for developer use, one can get the same behavior out of perl. But it's a simple matter to turn those off before shipping the product, which causes perl to go back to its normal unhandled exception response: attempt to do what the programmer most likely intended. (And it's generally quite successful at doing that.))

    I'm uncertain what RAII means, but the Wikipedia entry to me sounds like it's "programming". If you're using any programming language which doesn't have programming, I think you fail.
  • RQ 2008-07-31 07:32
    Quite some years ago, my group interviewed a guy for a development position in my group. Despite a good-looking resume, we didn't feel that he all that qualified, and so didn't take him. He eventually was hired in another department, and eventually, I wound up inheriting his position. Looking at his code confirmed that our first group assessment was correct.
  • Hans 2008-07-31 08:15
    Markp:

    Does it matter? From my perspective, lying to a potential employer is a show-stopper, hands down.


    And yet... In this situation HR had already filtered out everybody else; presumably that included at least a few people who were sufficiently competent for the job. It appears that the only way to get past that filter is to brazenly lie about everything, and it worked for Min.

  • Doesn't matter 2008-07-31 08:22
    henke37:
    For the linked list question, I would just itterate forward through the list, and checking if the back pointer really points at the node we came from. If it doesn't, we got a loop. It is an O(n) complex algorithm that is guaranteed to stop.


    That will only work for a doubly-linked list.
  • PG 2008-07-31 08:47
    Anyone that accesses the backend files for a real database over NFS is just asking for trouble. And I'm not talking about the performance hit you are going to take.

    In terms of the UNIX bufer cache. Well, mount that file system with the correct options. I also know that Oracle when it opens at least it's redo log files it uses with the DSYNC option, that forces the writes to be flushed and not hang around forever.

    Over the years, going back to version 5.1, I've seen people do tons of stupid things to machines running Oracle. Killing processes at random, hard power fails, disk storage going down, etc. I can count only two cases where the normal startup recovery in teh database didn't fix things. One was when some moved files around from E: to F: while the database was running. The other was many disk failures, not noticing that the RAID set had been degraded, and also no types of backups, ever.
  • fbjon 2008-07-31 08:54
    Technical Thug:
    Flush() guarantees that you've pushed the data as far out as the OS can push it, but you still don't know where it's sitting. Is this an NFS connection? Are you inside a blade machine where all the blades are using each other's hard drives?

    It's really hard to really make sure the bits are on metal without violating a whole big pile of abstraction barriers.


    If the transaction log indicates an incomplete transaction, roll it back. If the transaction log is damaged, roll it back. If there's anything wrong at all, roll back. Only if everything is peachy do you not do anything. This means that the data could be consistent and complete, but the transaction log still says it's incomplete, or it's damaged and so it gets rolled back, but that's ok. The only scenario where I can see this fail is where the hard drive spreads random bits all over the place just before losing power.
  • anon 2008-07-31 09:36
    Wow, you're an arrogant S.O.B.

    RAII is nearly 100% equivalent to try/finally. The difference is that RAII relies on rules of the C++ language to implicitly release the resources IN THE DEFAULT CASE, while try/finally requires explicit code. That's nice and all, but hardly a necessity, and certainly not enough to make RAII so vastly superior as to warrant a "try/finally considered harmful" proclamation.

    Worse, you seem to not understand your own beloved C++ and RAII. Destructors are NOT guaranteed to run. I can list numerous scenarios in which they won't. Yes, these are mostly the same scenarios in which finally blocks won't run either, but you sure seemed to think destructors were superior in this arena ("'Finally' blocks may work most of the time, but there's normal situations where they don't run.").

    You also go on and on about "RAII" just being programming, and how every language has it. This shows your ignorance. "RAII" isn't "just programming", it's a specific pattern. And like all patterns, it has different implications in different languages. In this case, the pattern CAN'T be applied in all languages. If you think that RAII _just_ means (from Wikipedia) "The technique combines acquisition and release of resources with initialization and uninitialization of objects", then what I just said sounds ludicrous. But that's only PART of RAII. RAII relies upon the scoped nature of the initialization and uninitialization, and not all languages have such support. That's precisely WHY finally (and using, which is syntactic sugar for try/finally) exists in those languages. Looked at from that perspective (the correct one), try/finally *IS* RAII by your definition, and thus you're arguing in circles (try/finally considered harmful, RAII is the superior solution that proves that, but try/finally is RAII, making the argument fail... my head hurts).

    OK, you've got a preference to C++. Good for you. Don't disguise this religious debate with a mask of superior technical knowledge, because doing so you FAIL.
  • krupa 2008-07-31 09:54
    tgape:
    None have shown this to me more clearly than Java and Python - supposedly the languages with the best exception handling (at least, according to their adherents), yet over 95% of the Java and Python programs I've run have an incredible propensity to dump with a stack trace on any unexpected input. That stack trace may be useful to a developer, but when a normal user sees it, there's a good chance you're losing a user.


    Sounds like you're blaming the language for short-comings in the programmer. Unexpected input is not an exceptional case and should not be treated as such. If your program is dumping a stack trace because the user entered a letter where a number was expected (for example), the program was written poorly regardless of the language used.
  • Enric Naval 2008-07-31 10:19
    henke37:
    For the linked list question, I would just itterate forward through the list, and checking if the back pointer really points at the node we came from. If it doesn't, we got a loop. It is an O(n) complex algorithm that is guaranteed to stop.


    This would fail if the back pointer happens to be incorrectly set.
  • tgape 2008-07-31 10:41
    krupa:
    tgape:
    None have shown this to me more clearly than Java and Python - supposedly the languages with the best exception handling (at least, according to their adherents), yet over 95% of the Java and Python programs I've run have an incredible propensity to dump with a stack trace on any unexpected input. That stack trace may be useful to a developer, but when a normal user sees it, there's a good chance you're losing a user.


    Sounds like you're blaming the language for short-comings in the programmer. Unexpected input is not an exceptional case and should not be treated as such. If your program is dumping a stack trace because the user entered a letter where a number was expected (for example), the program was written poorly regardless of the language used.


    I agree that the programmer is more at fault than the language. However, when 95% of the applications in use using one language are this sort of crap, and only 50% of the applications in use using another language are this sort of crap, I'll prefer the second language. It's not the language's fault, but that of the people the language attracts. (I realize 95% of everything is crap. But generally, the crap doesn't get used nearly as much as the 5% that's not necessarily crap.)

    Incidentally, an example of one of these python programs was the Gentoo emerge (it could be fixed now - it's been three years since I used it) program: give it certain combinations of bad options, and it'd stack trace, instead of giving proper usage. Clearly a Gentoo problem - but when you can't find an example to point the said maintainer to of how one does it correctly in Python, because the first 50 examples found by Google all have the same problem, I start wanting to avoid that language.
  • tgape 2008-07-31 10:42
    Doesn't matter:
    henke37:
    For the linked list question, I would just itterate forward through the list, and checking if the back pointer really points at the node we came from. If it doesn't, we got a loop. It is an O(n) complex algorithm that is guaranteed to stop.


    That will only work for a doubly-linked list.


    ITYM a doubly-linked list which had the a null back pointer for the first link.
  • lillyOfTheValley 2008-07-31 11:28
    sirGustav:
    anon:
    try
    
    {
    result = a/b
    }
    catch (exception)
    {
    //handle divide by 0
    }
    finally
    {
    return result
    }

    What's wrong with

    if( IsZero(b) ) // handle divide by 0
    else return a/b


    Nothing. Sure, have you programmed in LIPS all these years?
    Try simplifying code like this in C++ and go back to your code in 6 months and tell me if you understand what it's doing! (and comments whatsoever)
  • Pfhreak 2008-07-31 13:05
    Edward Royce:
    Sutherlands:

    boolean isCycle(*head)
    {
    slow = fast = head;
    try
    {
    do
    {
    slow = slow->next;
    fast = fast->next->next;
    }while(slow != fast)
    return true
    }
    catch(NPE)
    {
    return false
    }
    }


    But if there's no circular reference isn't that an infinite loop?

    Uhhh. Forget me. I'm on beer #3 so I'm probably talking out my rear end.


    Nope, because eventually fast->next->next will throw a null pointer exception (NPE), which will be caught, and false will be returned. Note, however, that using exceptions in this was is a bad idea, and considerably slower than just checking for null at each step.
  • Thief^ 2008-07-31 13:09
    Noel:
    kswanton:
    [...]
    'How would you detect if you had a circular reference in a linked list?' I responded that you'd have to use some type of a hash table and iterate over the list - at each element, you'd need to check the hash table to see if you'd ever seen that element before - if you had, there is a circular reference, if not, add it to the hash and continue.

    The interviewer kinda smirked at me and said something along the lines of 'Well that is not efficient - is there a more efficient way to do it' to which I responded 'Not that I can think of...'
    [...]


    [...]
    The answer I thought up was to have a compare the size of traversing the list with the known number of elements, if you can traverse through more elements than you have something is obviously wrong.

    They found that acceptable, but then described their own answer (which was pretty obvious as soon as they said it - I guess thats the pressure of interviews) which is to have a flag indicating whether an element has been visited or not, if you are traversing the list and come to which which has already been visited then it has a circular reference. (this technique is known as colouring)

    There is a solution which is reasonably fast and doesn't require you to know the size of the list or colour the elements:
    Use two iterators, one and two. Step one by one element at a time and two by two elements at a time. If the "two" iterator hits the end of the list, no loop. If the one and two iterators ever point at the same element, loop!

    Addendum (2008-07-31 13:24):
    EDIT: And works on a singly linked list, obviously.
    For a doubly linked list, just check if ( this->next->prev == this )

    Addendum (2008-07-31 13:33):
    Obviously testing that this->next isn't NULL first, to avoid crashing the poor thing.
  • Pfhreak 2008-07-31 15:15
    Thief^:

    There is a solution which is reasonably fast and doesn't require you to know the size of the list or colour the elements:
    Use two iterators, one and two. Step one by one element at a time and two by two elements at a time. If the "two" iterator hits the end of the list, no loop. If the one and two iterators ever point at the same element, loop!

    Addendum (2008-07-31 13:24):
    EDIT: And works on a singly linked list, obviously.
    For a doubly linked list, just check if ( this->next->prev == this )

    Addendum (2008-07-31 13:33):
    Obviously testing that this->next isn't NULL first, to avoid crashing the poor thing.


    Addendum (2008-07-31 13:14 PST):
    You should read the comments before posting your own, this solution has been posted MANY times already.
  • DKO 2008-07-31 15:21
    Sutherlands:
    The correct answer to the question you were asked is: Create 2 pointers, one that traverses the list one at a time, and one that traverses the list two at a time. If they are ever equal, you have a circular reference.


    Google didn't made up that one, it's Floyd's cycle-finding algorithm, a classical one. See [url]http://en.wikipedia.org/wiki/Cycle_detection.[url].

    But it can't find the beginning of the cycle.
  • real_aardvark 2008-07-31 17:37
    anon:
    Wow, you're an arrogant S.O.B.
    Arrogant, yes. SOB, no. At least I'm not anonymous.

    anon:
    RAII is nearly 100% equivalent to try/finally. The difference is that RAII relies on rules of the C++ language to implicitly release the resources IN THE DEFAULT CASE, while try/finally requires explicit code.
    If by "nearly 100% equivalent" you mean "diametrically opposed to," you're right. If you mean that both the construct and the pattern tackle the same issue, you are also right. Hardly the same thing though, is it? By "IN THE DEFAULT CASE," I assume you also mean "automatically," which isn't quite the same thing and doesn't feature the same boo-words and capitalisation. And I have no problem with try/catch; only with "finally." Read what I said again, and you'll see that my main issue is that it requires "explicit code." Over and over again. Rather than just once, for RAII. Code can be a pattern too, you know -- in this case a bad one.

    anon:
    Worse, you seem to not understand your own beloved C++ and RAII. Destructors are NOT guaranteed to run. I can list numerous scenarios in which they won't. Yes, these are mostly the same scenarios in which finally blocks won't run either, but you sure seemed to think destructors were superior in this arena ("'Finally' blocks may work most of the time, but there's normal situations where they don't run.").
    I think you'll find that quote under tgape. He's probably arrogant as well. He just isn't, y'know, me.

    anon:
    You also go on and on about "RAII" just being programming, and how every language has it. This shows your ignorance. "RAII" isn't "just programming", it's a specific pattern. And like all patterns, it has different implications in different languages. In this case, the pattern CAN'T be applied in all languages.
    Name one.

    Just because you can't guarantee that automatic destruction happens the moment that an object goes out of scope doesn't mean that you can't apply RAII. (I'd love to know how the use of "finally" helps in this regard.) Perl has DESTROY (it also has Scope::Guard, which I haven't looked into); Python has __del__; I can't, off-hand, think of another OO language that doesn't have a hook into the underlying mechanism for object destruction.

    It was, once again, tgape who made the tentative assertion that "RAII" <is> "just programming," although I seem to recall that he claimed that he'd never heard of it, had just looked it up, and it "seemed" to be that way.

    Good for you, anon. You're arrogant and guilty both of misattribution and misquotation. I make no comment on your parents, however.

    anon:
    OK, you've got a preference to C++. Good for you. Don't disguise this religious debate with a mask of superior technical knowledge, because doing so you FAIL.
    I've got a preference for C++, yes, but it's hardly religious. I'd be far happier spending the rest of my life programming in Python. (Better libraries, and better organised, too, required; and with a bit of luck the GIL will disappear. I'm looking forward to 3.0 for the first two and checking out alternatives to the third.) Scheme looks fun, too. I'm pretty language-agnostic, with the exception of those that I would expect to act as personal ball-and-chains, such as Java and VB.Net ... but I've got no objection whatsoever to other people using those languages. Just so long as they don't abuse ill-advised language constructs such as "finally."

    Did I mention religion? I might have done once, but I think I got away with it. I suspect that you're confusing my juxtaposition of goto and finally with (non-existent) evidence that I regard both as equivalently evil, or that I have dogmatic views on the subject.

    I don't. Not with regard to either, as it happens.

    I've seen too many projects burned by goto (thankfully in the dim, distant past), and, judging by many comments defending the use of finally, I'm going to see a -- probably smaller -- number of projects burned by the use of finally. Either one is a deceptively powerful tool, and therefore dangerous in the hands of a depressingly large number of programmers.

    Not you, obviously, because you are anonymous and not arrogant and therefore know what you're doing, even if what you do is by definition not attributable.

    Hier steh' ich, Ich kann nicht anders. Finally is the modern goto. Just an observation. Not a gospel. (Sorry, Martin. I'll get around to the other 94 when I have some spare time.)

  • real_aardvark 2008-07-31 18:02
    Noel:
    real_aardvark:
    There is no finally in C++. This doesn't make me think that C++ is an inherently better language than any other (far from it) -- but it does make me wonder what the fuck other languages really need a finally clause for.


    Fortran is not object oriented. This doesn't make me think that Fortran is an inherently better language than any other (far from it) -- but it does make me wonder what the fuck other languages really need to be object oriented for.

    Q.E.D.

    See.. here's how the proof works. If an old language doesn't have the exact same features as a newer language, then the newer language is wrong. Right? Right?
    Let me boil this down for you.

    A (language C++) does not contain WTF' (finally).
    A (language C++) is not better than a member s of the set S (other languages).
    A (language C++) is Turing complete.
    For each s in S (other languages), s is Turing complete.
    s' (some member of set S) contains WTF' (finally).

    Since A does not contain WTF', what benefit does s' derive from containing WTF'?

    Let O represent <the set of> "object oriented" <languages>. Note, for the purposes of this proof, that neither O nor the term "object oriented" has yet been used or defined. Nor will be.

    Your argument therefore goes as follows:

    F (language Fortran) is not a member of set O.
    F (language Fortran) is not better than a member o of the set O ("object oriented" languages)
    I don't need to bother explaining what o' means, because I've just sprinkled pixie dust and used the magic abbreviation "Q.E.D."

    quod, I think, non est demonstrandum.

    Neither "old" nor "new" feature in this abstraction. Your (pitifully cretinous) argument would make C++ the superior language had Stroustrup invented it yesterday, complete with RAII.

    Your (pitifully cretinous) argument also introduces the entirely irrelevant issue of whether a language is "object oriented" or not. As you know, Fortran is not. It is not, therefore, amenable to the RAII pattern. I'm not au courant with the latest Fortran standard, but I'd assume that it's also lacking in support for exceptions -- which makes the use of a "finally" clause a bit problematic.

    We were talking about "finally," weren't we?

    As opposed to some completely random and possibly massively destructive language construct that hasn't been invented yet, but will be in the near future?
  • JJ 2008-07-31 18:51
    A better example of never executing a finally is when calling System.exit().
  • Rhialto 2008-07-31 21:46
    kswanton:
    One of the questions was 'How would you detect if you had a circular reference in a linked list?'
    A common method to do this is to use two pointers stepping through the list, once at twice the speed as the other. If the fast one ever catches up with the slow one (i.e. ends up pointing at the same list member), you have a loop in your list.http://en.wikipedia.org

    See http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
  • immibis 2008-07-31 23:48
    Jabmist:
    stack overflows will STILL call the finally

    package test;
    public class miscTest {
    public int loop(int x){
    return (loop(x+1));
    }
    public static void main(String[] args) {
    try{
    int x=0;int y=5; miscTest test = new miscTest();
    test.loop(1);
    double t = y/x;

    }catch(Exception e){
    System.out.println("catch start");
    int x=0;int y=5;
    double t = y/x;
    System.out.println("catch end");
    }finally{
    System.out.println("finally");
    }
    }
    }


    finally
    java.lang.StackOverflowError
    at test.miscTest.loop(miscTest.java:8)
    at test.miscTest.loop(miscTest.java:8)
    at test.miscTest.loop(miscTest.java:8)


    There's a reason it never reaches the catch statement. StackOverflowError is obviously an Error not an Exception.
  • ClaudeSuck.de 2008-08-01 05:53
    JonC:
    Surely TRWTF is giving someone who has 'Oracle T-SQL' and 'Microsoft Solaris' on their CV the benefit of the doubt.

    That would have been setting alarm bells ringing immediately for me.


    You could still hire him/her as a clown or other who keeps company moral up by showing that there is always a person who is doing less good than you.
  • Colin S. Miller 2008-08-01 08:00

    What's wrong with

    if( IsZero(b) ) // handle divide by 0
    else return a/b


    Except that won't work if a=10^20, b=10^-20

    The result is 10^40 which is out of the range of [+/1] 1 * 10^[+/-] 38 of single-precision floating point numbers.
  • atz 2008-08-01 16:25
    Jeff S:
    real_aardvark:
    Ah yes, the finally block: the goto of the modern world. An impression that many of the comments above reinforce.


    Huh? So what are you saying? You believe that using Finally is a bad practice? I have no idea what correlation you are drawing between finally() and goto...


    In opposite to other readers I can see a correlation between goto and finally:


    int f()
    {
    FILE* f = NULL;
    int error = 0;

    f = fopen("foo", "r");
    /* do stuff */
    if(error) {
    goto cleanup;
    }
    /* do stuff */
    if(error) {
    goto cleanup;
    }
    ...
    cleanup:
    if(f != NULL) {
    fclose(f);
    }
    return error;
    }


    Isn't this a poor man's finally?

    I've made this often in my first C programs and I've seen it in programs made by other programmers. And that's the only excusable use of goto I know. Anyway I prefer other ways of error handling (in C) today.

    BTW, what's about a finally for C++?


    #define finally(code) catch(...) {code throw;} code

    f()
    {
    try {
    try {
    // do stuff
    }
    catch(whatever) {
    // exception handling
    }
    }
    finally(fclose(f);); //example cleanup stuff
    }


    I assume this would be a source of many WTF's ;)

    ... if it works at all, didn't tried it!
  • real_aardvark 2008-08-02 15:49
    Noel:
    kswanton:
    I've only had one bad interview experience. The lead was called in to handle the technical portion of the interview, which was made up of a few questions.

    One of the questions was 'How would you detect if you had a circular reference in a linked list?'<snip/>


    I was asked this same question at the interview for my current job. The answer I thought up was to have a compare the size of traversing the list with the known number of elements,<snip/> (this technique is known as colouring)
    There may well be better ways, and for all I know they involve the use of "finally," but the simplest effective way I know is to use two iterators: one goes through the list/whatever with an increment of 1 and the other goes through the list/whatever with an increment of 2. If, at any stage, they are comparable, then you have a circular linked list.

    It was the only question that I outright failed on my interview for a Dot Bomb. "Well, you'll remember the answer next time, won't you?" said Michael, the Jewish Ukrainian American who turned out to be an utterly excellent boss.

    Yes, I will. I will also remember to spit poison in the face of some retarded quasi-superior prick of an interviewer who actually takes puzzle-solving seriously, without being prepared to have the same crap thrown back in their face.

    Addendum (2008-08-02 15:59):
    DKO:
    Google didn't made up that one, it's Floyd's cycle-finding algorithm, a classical one. See [url]http://en.wikipedia.org/wiki/Cycle_detection.[url].

    But it can't find the beginning of the cycle.
    Oops, sorry. An interesting Zen question, however: What is the beginning of the cycle?
  • real_aardvark 2008-08-02 16:09
    atz:
    BTW, what's about a finally for C++?


    #define finally(code) catch(...) {code throw;} code


    I assume this would be a source of many WTF's ;)

    ... if it works at all, didn't try it!
    Excellent example, and my thanks.

    res ipsa loquitor.
  • George 2008-08-04 12:32
    It feels awkward when you realize that you know more than your interviewer.
  • shazam 2008-08-05 01:57
    The code in the following finally is unlikely to ever execute:

    try {
    while ( true ) ;
    } finally {
    veryImportant();
    }
  • sirGustav 2008-08-05 05:57
    sirGustav (me):
    What's wrong with

    if( IsZero(b) ) // handle divide by 0
    else return a/b


    lillyOfTheValley:
    Nothing. Sure, have you programmed in LIPS all these years?
    Try simplifying code like this in C++ and go back to your code in 6 months and tell me if you understand what it's doing! (and comments whatsoever)
    never heard of LIPS, never used LISP, or any other functional languages for that matter, but I plan to(just gotta find some time). I mostly code in C++ and C# at home/work, and AFAIK C++ doesn't throw divided-by-zero exceptions. Personally I think C# and java throw to many exceptions and if you providing a specialized case on such a low level, you shouldn't be catching exception, you should stop it from being thrown, espesially in C++.

    Colin S. Miller:
    Except that won't work if a=10^20, b=10^-20

    The result is 10^40 which is out of the range of [+/1] 1 * 10^[+/-] 38 of single-precision floating point numbers
    true, but given that the original code only handled divided by zero (catching all exceptions?) I'd say my code didn't introduce any more bugs :)
  • R 2008-08-06 23:17
    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLine(Something().ToString());
    }

    static int Something()
    {
    int val = 0;

    try
    {
    val = 2;
    return val;
    }
    finally
    {
    val = 1;
    }
    }
    }

    Guys, seriously. Be careful with finally blocks. This shows right here, in a very contrived case, why. This caught a _lot_ of very intelligent developers in various groups here at my company.

    Just because finally executes last, doesn't mean that it's doing what you may intuitively think it should do.
  • Kuba 2008-08-07 12:23
    sirGustav:
    never used LISP, or any other functional languages for that matter, but I plan to(just gotta find some time). I mostly code in C++ and C# at home/work, and AFAIK C++ doesn't throw divided-by-zero exceptions


    The "exceptions" aren't thrown by C++, they are thrown by the CPU, and on most OSen there are APIs to enable those "exceptions". This applies, then, to almost any language (assembly, C, C++). Some language runtimes (Java, .net) enable those by default.

    It is actually very useful to enable math exceptions in C++ when you write numerical code. This lets you avoid hand-coding (at a HUGE performance penalty) wrappers for almost every operator and math function out there, just to handle those. I know of at least one open source (and somewhat abandoned now) open source project, very numerically-intensive (solves multibody dynamics) where the author had gone that route. You could probably remove 10-20% of the code just by enabling some more exceptions and doing exception handling properly.

    Cheers, Kuba
  • insta 2008-08-10 16:24
    A more complete answer (in addition to this) is that proper database servers have batteries slathered all over them (including the drive controllers), and they pick up where they left off when power is restored.
  • Phillip Rhodes 2008-08-10 17:19
    From my perspective, lying to a potential employer is a show-stopper, hands down.


    I can't imagine why... after all, employers lie to employees all the time. All's fair in love and war...
  • snubbe 2008-08-31 19:07
    Awesome! I'll put my whole application within that block!
  • Learn to Read! 2008-10-13 17:37
    They're discussing .Net, not Java.
  • Serge 2010-04-11 03:25
    He was talking about the .NET environment where running a thread within "try, catch, finally" doesn't bubble up any exceptions which occur within that thread. The exception has to be caught within the actual thread, not the parent thread which spawned it.
  • Dave Black 2011-03-23 10:34
    Uh...maybe I missed something, but aren't we talking about .NET - I'm sure that other languages have different implementations (i.e. your example is in Java)
  • Kendall F. 2011-05-13 17:59
    I have been burned by that one. I discovered the hard way that pressing the 'X' close button on a console window is equivalent to killing the process. I thought surely it would die gracefully, but, no.
  • David 2013-07-08 03:47
    If you read the original post, the author mentioned .Net 1.0 - not Java. So while Java will fire off the finally event, that does not mean .Net will.
  • John tan 2013-09-27 08:02
    Alex Papadimoulis, you sucks
  • Alex Papadimoulis 2014-09-08 07:36
    John tan:
    Alex Papadimoulis, you sucks
    John tan, you blows goats