• The DOg (unregistered) in reply to stupid old me

    The answer was boring and unimaginative...no elan in the delivery...drone-like repetition of something memorised. Who wants a geek like that working for them...

  • AdT (unregistered) in reply to Zygo

    Zygo, you are conflating parameterized with prepared queries. To my knowledge, points 1 and 2 apply only to prepared queries, not all parameterized queries. Not that I would think they were particularily relevant in any case. I only use command preparation when I have good reason to believe the command will be used numerous times. In this case, the extra work required for the one-time preparation is outweighed by the time saved on every single execution.

    Zygo:
    3. Some client toolkits implement parameterized queries in O(n^2) time on the number of parameters. String concatenation, if done correctly, runs in O(n) time.

    This is tantamount to saying that some ways to handle query parameters are broken, while some ways to concatenate strings are not. It's an irrelevant tautology.

    My suggestion would be to use parameterized queries and a sane client library. It is possible.

    Zygo:
    4. Some (evil or broken) client toolkits implement parameterized queries by client-side escaping and concatenation. If you can't upgrade the client toolkit, and you're not trying to be portable, it's probably going to be faster to do the escaping and concatenation yourself.

    Faster maybe, but less maintainable, less reusable and more error prone. Even if performance considerations should override all these objections, you should rather use a better client library.

  • Pidgeot (unregistered) in reply to Zygo
    Zygo:
    Cloak:
    Why not use a decent program in VB or Delphi which has quite good GUI editors (again: Java, aarrrrgh!!!) and the final exe is just less than 5 MB.

    Holy shit...

    puts("Hello, World!\n") in C (GCC 4.1, default compile options): 7021 bytes.

    Same source code compiled with C++: 7486 bytes.

    std::cout << "Hello, World!\n" in C++: 8477 bytes.

    Statically linked: 495K, 557K, and 1186K, respectively.

    Recompile in C++ with coverage analysis, profiling, debugging, inline functions, exceptions, RTTI, and unrolled loops: 1234K.

    Delphi produces a 5MB executable. Presumably you're not building Delphi apps with options intentionally chosen to produce the largest possible exe, so we're comparing the 8K executable with a just-less-than-5MB one.

    WTF is the just less than 5 MB for?

    C:\tmp>type hello.dpr program Hello;

    begin Writeln('Hello, World!'); end.

    C:\tmp>dcc32 hello.dpr Borland Delphi for Win32 compiler version 17.0 Copyright (c) 1983,2004 Borland Software Corporation hello.dpr(6) 7 lines, 0.08 seconds, 10476 bytes code, 1797 bytes data.

    C:\tmp>dir hello.exe (...) 23-08-2007 21:47 15.360 hello.exe

    Native Win32, no need for any kind of libraries. So we're really comparing your 495K+ to 15K. ;)

    The point is that you might want to review what a GUI is, because your example isn't. (Even so, 5MB gets you quite far in Delphi - I think the minimal GUI app that doesn't rely on Win32 is 3-400KB, depending on version)

  • Molly (unregistered)

    What she said is legally actionable. Peter can sue for damages.

    If he can prove that his blurb on concatenation was original, he can get that company (or at least its HR department) in ALOT of trouble. Essentially what they did was to assume fraud when there was none.

  • gus, the (unregistered) in reply to Jesse

    that's boneheaded! what - you can anticipate the exact wording of all your sql queries? if you don't know how to filter data before putting it in a sql query, you probably should be asking people if they want fries with the products you deliver.

    and my captcha was bathe - what, do Labtec webcams have odor analyzers now?

  • Zygo (unregistered) in reply to AdT
    AdT:
    Zygo, you are conflating parameterized with prepared queries. To my knowledge, points 1 and 2 apply only to prepared queries, not all parameterized queries.

    Thanks, I forgot about those...

    1. You could be using an (evil or broken) toolkit where the only way to bind variables to a parameterized query is to create a temporary prepared query object, then call bindValue() on the prepared query object.

    2. You could also be using an embedded SQL system which can't avoid preparing any queries that aren't of the form "execute(string_variable)". "Embedded" here means the old-school technique of writing "SELECT INTO cVar * FROM FOO;" in the middle of C code, then running the source through some kind of preprocessor which replaces the SQL statements with machine-generated C code.

    AdT:
    My suggestion would be to use parameterized queries and a sane client library.

    Yes. Often it's possible to make your program go faster or be more maintainable by avoiding utterly lame technology in your dependencies. But that's an irrelevant tautology too.

  • quake (unregistered)

    My Real Experience.

    Along with my diploma thesis, I have another task to translate a lengthy article, actually I realized afterwards that it was a big chapter from a book, from English to my native language, I worked very hard on it.

    And when I submitted my work, the guy said that he suspect the translation was from internet. i.e., plagiarized.

    That guy was a professor I didn't know him before that, immediately, my respect to him went away, down to the hell.

  • Turtle (unregistered)

    The problem with the dude wasn't his answer. Following most methodology used by interviewers, the proper way to test for plagiarism is to do a follow-up interview.

    I believe the root of the dude not getting the job was because the employer already had their heart on hiring someone else. The excuse that they used to justify their means of not "wasting their time" interviewing someone they don't want to hire is to say that his answer was plagiarized. By saying that, other's involved in knowing about the interview will believe that the their manager is weeding out loser "plagiarists". Obviously the manager doesn't want to be seen by people around him/her as "unfair" and not giving everyone "an equal chance" because that can cause tension. The most beneficial way, from the manager's perspective, is to simply make a false excuse of "plagiarism".

  • EllisGL (unregistered) in reply to Erik

    What's wrong with doing it this way? (I can read it just fine. =))

    if(!is_int($_POST['pid'])) { die('How dare you stick a non interger in there!); }

    $sql = 'SELECT id, var, text FROM table WHERE whatever = ''.mysql_real_escape_string($_POST['monkey']).'' AND pid = ''.$_POST['pid'].'' LIMIT 1';

    captcha: burned

  • (cs) in reply to Molly
    Molly:
    What she said is legally actionable. Peter can sue for damages.
    Only if there were damages. Slander and libel tend to get under that "no harm, no foul" category. If they never told anyone other than him (i.e., never told another hiring manager or wrote it on his resume) then it's not slander in the first place. OTOH, if they have a website where they make their evaluations available (can you say "idiots?), they could be hosed.
  • JohnFx (unregistered) in reply to Molly
    Molly:
    What she said is legally actionable. Peter can sue for damages.

    If he can prove that his blurb on concatenation was original, he can get that company (or at least its HR department) in ALOT of trouble. Essentially what they did was to assume fraud when there was none.

    Uhh. No. Just no. Go back to programming and leave the legal advice to the professionals.

  • JohnFx (unregistered)

    You might have been better off using the SCIgen Automatic CS Paper Generator. (http://pdos.csail.mit.edu/scigen/) for the lazy reader, these are pretty convincing!

  • David (unregistered)

    I always thought the best way to avoid SQL injection in PHP was to write in Perl :-) Not forgetting to set -t (taint).

  • Greg (unregistered)

    I would've been soooooo pissed. WTFFF

  • Peter B. (unregistered)

    Hey guys, it's me again. Back here because of the Digg attention.

    First of all, you have to understand that this specific event took place early in March of 2005. It's a new story to all of you, but until a buddy emailed me yesterday, I had forgotten I even submitted the story to wtf (which was done many months ago when this was still thedailywtf).

    Regarding libel. Technically it never could have been libel, I was told this over the phone, so slander would have been my option. But with no decent way to prove it, there was no point in going to that much hassle. Our culture is too trigger-happy with lawsuits as it is.

    I'm now the Sr. Software Engineer at a top marketing agency, so don't worry about my employment status as a result of this tale =P

    Also, some of you may remember me as the developer of fValidate, a now long-defunct javascript library for "validating" forms.

    Anyway, carry on =)

    captcha: waffles. mmmmm, yum!

  • KhAoZ (unregistered) in reply to Jesse

    Well I definetly wouldn't hire you if you made such a stupid comment. Just because your using dynamic data in sql queries does not mean sql injection 100%. If you code your program safely (ie escaping characters), then your sql queries with dynamic data will be fine.

  • Mikey (unregistered)

    Well I think Peter deserved the job, I think next time just answer the question without expanding on it.

    You can come work for me at www.WhichWebsite.com

  • Q Wang (unregistered)

    I think he did a better job demonstrating his ability to write clearly and cohesively. That's a fine piece of writing of a caliber you don't normally see in many programming tutorials.

  • Franz Kafka (unregistered) in reply to Random832
    Random832:
    Franz Kafka:
    The common solution is to implement a default deny policy - decide what's allowed and reject anything else. For instance, userID could be checked against (^[0-9]+$) and username against ^[a-zA-Z_-@ ]+$ and you'd be proof against sql injection.

    right, and useremailaddr can be checked against

    <bigass regex>

    fail. user email address can't be represented with a regex. you could parse them with a grammar if you like, or just remove anything potentially hazardous.

  • Paul (unregistered)

    Sounds like it would have been a boring job anyway

  • V (unregistered)

    English is not my native language so bear with me here...

    I think it actually sound more like a text book answer than a response to a job interview question. The answer sounds like someone teaching someone else something.

    Not going into the technical details, there are just too many "you" used in the write-up.

    The question asked for a demo of your skill, hence instead of being sounding like a teacher, he should have sound like a demo. First round of review of this answer would likely be HR staff who won't really understand PHP anyway, might as well make the write up sound soooo difficult hence discouraging them from even reading pass the 2nd line.

  • Josh (unregistered)

    HR people are the worst to do interviews, especially concerning IT

  • Professional (unregistered)

    I would have hired the guy.... Based on his answer I can tell that he seeks a challenge and would be the type of developer that work well in a team. The simple fact that he went beyond a simple answers tells me that he would go above and beyond simple tasks that would be assigned to him.

    And as far as the preventing against the whole sql injection thing.... I would have just used Coldfusion.

  • Khushi (unregistered)

    :) i love the last line........

  • ub (unregistered) in reply to M Diamond
    M Diamond:
    The second-most ridiculous aspect is that if they choose not to trust the results from the screening question in a case like this, then a moment's thought would have revealed to them that they need a new pre-screening process. The old one is unable to distinguish between someone ignorant but unscrupulous and someone extremely knowledgeable. That's about as broken as you can get.

    +5 on that one! I couldn't agree more.

  • Kuba (unregistered) in reply to rbowes
    rbowes:
    The next year, my friend took the course. Apparently, when given the paper, they were told "No more than 10 pages. Last year, we had an issue with some plagiarism." Apparently, although she couldn't prove it, the prof thought my paper had been plagiarized!

    That prof needs attitude adjustment. What sort of a scientist/researcher is she if she'll believe her own precoceived ideas more than hard facts? You have a bright student, get over it, idiot...

    Sighs in disbelief...

  • Kuba (unregistered) in reply to Martin Ritchie
    Martin Ritchie:
    Oddly similar to a question I used to ask during interviews: Please write a C# function to concatenate 3 strings.

    For example the function would be passed "Martin", "Donald", "Ritchie" and should return "MartinDonaldRitchie".

    I would ask them to write the answer on a piece of paper. Only about one third of the interviewees were able to answer it. Even after saying that I accepted answers in vb c++ or any other language if they were not familiar with c#.

    Thank $DEITY there's someone else who thinks (like me) that programming recruits are actually supposed, to, you know, have a clue about programming.

    Thank you again.

  • (cs)

    The issue with PHP and parametrised queries isn't that you could always do them, it's that the setup that came bundled with PHP couldn't until PHP5.

    If you bundle one particular module and not another, Joe User is gonna use the one you bundled. It'll improve portability by eliminating an "unnecessary" dependency, and many would assume that you, as the maintainer of your project, are knowledgeable enough about it to pick the best module for the task.

    And "oh, it's fine, we're bundling the functionality now" doesn't magically fix everything. There's a lot of legacy projects, and PHP programmers who've learnt bad habits, and they're not gonna disappear overnight.

  • Nathan (unregistered) in reply to EllisGL
    EllisGL:
    What's wrong with doing it this way? (I can read it just fine. =))

    if(!is_int($_POST['pid'])) { die('How dare you stick a non interger in there!); }

    is_int() tests the internal variable type; it doesn't actually check the value to see if it's an integer:

    is_int("10") // returns false; "10" is a string. is_int( (int)"foo" ) // returns true; typecast converts to int value 0

    To actually test, you have to do a regex, i.e.:

    if( preg_match('/[^0-9]/', $_POST['pid']) ) die('PID must be an integer.');

    Nathan

  • (cs) in reply to Kuba
    Kuba:
    Thank $DEITY there's someone else who thinks (like me) that programming recruits are actually supposed, to, you know, have a clue about programming.
    Shortly after I was hired at my present position, I watched as the manager of another development team hired two totally worthless posers in rapid succession. The first one was sent packing after two weeks (he asked a teammate why his VBScript code rendered as text rather than executing in his ASP web page; it was because he had used an .htm extension). The second one was kept for a year, during which time he produced one (count it... one) completed project, which consisted of a single web page which accepted user input and emailed it to a specified address. Even this one app was so terrible that we scrapped his work and started over from scratch after they finally fired him. We all knew that the reason he was kept for a year was so that the manager who hired him would not look incompetent for having hired two losers in a row.

    I knew how those guys got hired. It was the same way I did; the interviewer sat and chatted with them for an hour trying to "get a feel for their skills".

    Eventually I became an interviewer, and the first thing I did was put together a test consisting of simple questions that would allow the interviewee to demonstrate elementary skills in C#, ADO.Net, SQL, Javascript and HTML. A couple of examples:

    Table Customer has 3 fields (CustID, FirstName, LastName). Table Order has 4 fields (OrderID, CustID, PartNo, Qty) There is a foreign key constraint in place between the Customer and Order tables on the CustID field. Write a query that returns all the Order records for customers with a last name of "Jones".
    And...
    Can you open a new browser window from within server-side code? How would you do this, or if no, why not?
  • AdT (unregistered) in reply to Zygo
    Zygo:
    Thanks, I forgot about those...
    1. You could be using an (evil or broken) toolkit where the only way to bind variables to a parameterized query is to create a temporary prepared query object, then call bindValue() on the prepared query object.

    2. You could also be using an embedded SQL system which can't avoid preparing any queries that aren't of the form "execute(string_variable)". "Embedded" here means the old-school technique of writing "SELECT INTO cVar * FROM FOO;" in the middle of C code, then running the source through some kind of preprocessor which replaces the SQL statements with machine-generated C code.

    You still forgot

    1. You could get lost in handwaving and speculation as you try to argue against parameterized queries in futility.
    Zygo:
    Yes. Often it's possible to make your program go faster or be more maintainable by avoiding utterly lame technology in your dependencies. But that's an irrelevant tautology too.

    Too bad it's not lame technology. Parameterized queries are conceptually sound. That there are some lame implementations (not that you actually named any, but I won't base my objections on that) doesn't disprove this in any way.

  • IHaveNoName:-( (unregistered) in reply to Michael McRorey
    Michael McRorey:
    you can use the following: <?php $sql = sprintf ( "SELECT article_id, article_body FROM Articles WHERE author_id = '%s' ORDER BY article_date DESC", addslashes($User->getID()) ); ?>

    you can also use the following if it is a MySQL db: mysql_real_escape_string($User->getID())

    sure, the above aren't the standard "." method of concatenation, but it is concatenation AND a cure for SQL injection.

    That's all pointless, everyone of you who is thinking that there is a possible source of sql injection assumes, that getID retrieves tainted data. But there is absolutely no clue that this is tainted data. If you use untainted data for sql generation you don't need to escape it...

  • dpk (unregistered) in reply to Jesse

    You serious? You've never had to take user input and generate a query based on it? I am picturing Jesse's code including tables and tables of millions or billions of queries, one for every possible user input. Heh.

    There's no reason to believe that dynamic data absolutely leads to SQL injection. It would make a good follow-up question, though.

  • Ren (unregistered)

    Heh. I seriously feel for whoever they pick out for the job. Anyone who's even tried programming beyond "Hello world" level can answer that. I guess you could say that this is a very advanced screening question: You're looking for someone to do a trained monkey's job for $5 an hour. It's not that you want your "coders" to be stupid, but they shouldn't be too bright, right?

    It never occurred to me before, but yes, screening questions can apparently have a lowpass filter as well.

  • Akira (unregistered) in reply to Jesse
    Jesse:
    WTF:
    SQL queries are rarely generated without some sort of dynamic data to alter their structure, so this is a very common task that I've used in just about every web application I've written.

    Can I say SQL injection? That would be why I wouldn't have hired him..

    umm.. that's what escaping is for. If you can't enter new data, your application is pretty useless.

  • Mason (unregistered)

    That's the issue with:

    A) Managers who aren't programmers and B) Recruiters with English majors.

    A programmer with his weight in salt/gold/silver/RAM will have good communication skills, and be able to explain a concept thoroughly and clearly.

    This response had little jargon apart from the expected technologies associated with PHP... "query", "SQL", etc. Problem is, if a recruiter/screener/manager was told that concatenation is "the joining of two sequences of characters", his response looks like an encyclopedia.

    That's just crazy.

    http://www.vazav.com

  • Per (unregistered) in reply to Jesse

    Well his code is fine. Let me quote from php.net:

    "The PHP directive magic_quotes_gpc is on by default, and it essentially runs addslashes() on all GET, POST, and COOKIE data. Do not use addslashes() on strings that have already been escaped with magic_quotes_gpc as you'll then do double escaping. The function get_magic_quotes_gpc() may come in handy for checking this."

  • ATC (unregistered)

    yea thats how it is. because if u are too good, you gonna make others look dumb and probably desire for a higher salary when you realize that your co-workers are idiots.

  • Ron (unregistered)

    With only 30 seconds...he did plagurize it. He may have known the answer. As a programmer, myself, concat is a very easy thing to describe. But i don't know anyone that could give that detail in 30 seconds. Cut and Paste he did. he should have just said, 'using an concat operator to combine two strings.

  • andr3w (unregistered)

    It is easy to check if the answer has been plagiarized - just take a phrase from the text you suspect and google it. In this case "sequentially join multiple pieces" is enough. I regularly check my student's work. A phrase of four uncommon words is normally sufficient to find the source.

  • Cloak (unregistered) in reply to Zygo
    Zygo:
    Cloak:
    Why not use a decent program in VB or Delphi which has quite good GUI editors (again: Java, aarrrrgh!!!) and the final exe is just less than 5 MB.

    Holy shit...

    puts("Hello, World!\n") in C (GCC 4.1, default compile options): 7021 bytes.

    Same source code compiled with C++: 7486 bytes.

    std::cout << "Hello, World!\n" in C++: 8477 bytes.

    Statically linked: 495K, 557K, and 1186K, respectively.

    Recompile in C++ with coverage analysis, profiling, debugging, inline functions, exceptions, RTTI, and unrolled loops: 1234K.

    Delphi produces a 5MB executable. Presumably you're not building Delphi apps with options intentionally chosen to produce the largest possible exe, so we're comparing the 8K executable with a just-less-than-5MB one.

    WTF is the just less than 5 MB for?

    This post was to critisize Java, not a reasonable language. Delphi will for sure not produce a 5MB .exe to output "Hello World". I was talking/writing about an entire application and how much memory this will approximately need. A Java executable might "need" less but the fact that you have to run at least 100MB of Java engine stuff, that was the point. And, of course, using C++ should consume even less than 5MB as you tried to point out (though >1MB for "Hello World" is a WTF on its own) but it is less comfortable to write this in 10 seconds.

    QED

  • Cloak (unregistered) in reply to Zygo
    Zygo:
    ratsbane:
    And you will be mingling SQL with data whether you like it or not - it's just a question whether you should use a magical black box of parameterization (which likely will be slightly faster) or concatenation.

    Parameterization can be slower than concatenation:

    1. Sometimes an extra round-trip to the server is required to generate the parameterized query handle, so if you are only going to execute the query once it is probably faster to concatenate strings (unless the string is huge and full of escape characters, or your RDBMS's query parser is extremely slow).

    2. Some RDBMS query optimizers only optimize the parameterized query, and lose opportunities to optimize for specific constant values. For example if a CHECK constraint on a table makes a particular parameter value impossible, then the optimizer may figure out that specific parameter values are impossible and optimize the entire query out of existence--but it can't do that if it doesn't know what the parameter value is.

    3. Some client toolkits implement parameterized queries in O(n^2) time on the number of parameters. String concatenation, if done correctly, runs in O(n) time. If there are many parameters and they're mostly small integer or short strings, the parameterization and data marshalling cost can exceed the benefit, especially in cases like multi-row INSERTs.

    4. Some (evil or broken) client toolkits implement parameterized queries by client-side escaping and concatenation. If you can't upgrade the client toolkit, and you're not trying to be portable, it's probably going to be faster to do the escaping and concatenation yourself.

    Use stored procs for f***s sake. 6 pages of comments, all about parametrized queries. But no one of you high-level-top-gurus ever thought of stored procedures. It's a shame.

  • http://resh.im (unregistered)

    Thanks for this cool peace of info.

  • bahodir (unregistered)

    don't worry Peter, i'll give you a job (lol)

  • Rahul (unregistered)

    A recuiter rejected me because I fell short of bits in my programming experience. She asked me how many bits of programming experience I had. When I asked what she meant, she asked whether I had programmed in more than 16 bits. Thinking that this was a hopeless place, I joked that I had programmed in 23 bits max and was trying to get my 24th bit. She didn't understand the joke and said the minimum bits required for the job was 32.

  • apos (unregistered)

    Hmmmm nice fake story

    a) rejections always comes through emails b) Even if the HR person called, she wouldn't have mentioned the real reason why he didnt get the job because they can never be 100% sure so it would be highly offensive for the applicant in the case of a wrong accusation.

  • tieTYT (unregistered) in reply to Cloak
    Cloak:
    Use stored procs for f***s sake. 6 pages of comments, all about parametrized queries. But no one of you high-level-top-gurus ever thought of stored procedures. It's a shame.

    Every guru (and I don't consider myself one) knows that this is a religious debate. Some say use them, some say don't. I personally don't like to use stored procs if I don't have to. First of all, the store proc languages of database X usually sucks. Second, the code will almost never be portable to database Y. Third, it's yet-another-language-to-learn which makes your app harder to grok.

  • Elliotte Rusty Harold (unregistered)

    What most folks are missing here is that it's not merely that the answer is correct and complete; it's that it's well-written. Relatively few programmers have this level of facility with the written language. Written communication skills are severely undervalued in our profession, but they're very important.

    If I received this answer from a job applicant, I would Google a few phrases to see if it seemed to be plagiarized from somewhere. However, assuming it wasn't, that candidate would be rated much more highly than one who merely knew the correct answer.

  • omfg. (unregistered)

    I'm in the wrong industry. I hate computers.

  • Dallas Freeman (unregistered)

    OMG, bad luck buddy. I didn't see that one coming.

Leave a comment on “Good Answer... Perhaps TOO Good”

Log In or post as a guest

Replying to comment #:

« Return to Article