September, 2008

  • The Old New Thing

    Tales from the interview: Can you rotate this two-dimensional array?


    My colleague jeffdav told me about one job interview with a graduating college senior that didn't go well because the candidate simply gave up.

    He offered a simple programming task: Write a function that takes a 4×4 two-dimensional array and rotates it clockwise by 90 degrees. For example, the entry in the upper left corner of the array goes to the upper right corner.

    The interview candidate simply gave up without even writing so much as a function prototype. "I can't do it."

    — Okay, well, let's take it a step at a time. Maybe take a specific example and see what we can learn from it.

    "It's some sort of matrix multiplication."

    — All right, well how would you start working that out?

    "I don't know. I can't do it."

    That's really not a good way to demonstrate your problem-solving skills: By responding to a problem with a simple "I can't do it." All of us are faced with things we can't do. The important thing is that we are willing to learn what we need in order to be able to do them.

    I wonder if this particular person thought that attitude would fly at a real job. If your boss gives you a difficult job, would you just say, "I can't do it"? Heck, how do you even graduate from college with that attitude? Your professor gives you an assignment, and you just say, "I can't do it"?

    (The punch line for people who actually know matrix algebra: Matrix multiplication doesn't solve the problem anyway.)

    Bonus commentary: I reprint JeffDav's comment which he posted below, since it is after all his story.

    This was a question reserved for intern candidates and fresh out of college hires. I was usually the first one on the loop and used this as a warm-up question. Once they got it, we'd move on to something more interesting. This one guy just refused to believe it was even possible.

    Also, I would phrase it as "rotate an N x N matrix where N >= 1, and you are given N along with the matrix A." This makes it super easy. If you allow an N x M matrix (i.e. non-square) the question gets much harder.

    I don't ask this question as often anymore. I get bored with asking the same questions over and over. Furthermore, I think after about the 100th time you ask a question you have lost perspective on it. Once you can write the answer on the whiteboard by heart without even thinking, you get annoyed by anyone who takes more than a few seconds thinking about it. It may not be a conscious annoyance but it's there if you think about it, and I think it gives you a bit of a negative bias at times. At least it does for me. It's good to find new questions so you have to solve them yourself and you have that feeling of approaching the problem for the first time fresh in your memory.

  • The Old New Thing

    Suggestion Box 3, short answers (part 2 of who knows how many)


    Another round of short answers to questions in the suggestion box.

    How does Windows choose the monitor a window maximizes to?

    The window maximizes to the monitor selected by MonitorFromWindow. The algorithm the MonitorFromWindow uses to select the monitor is documented in MSDN.

    How do you make your Win32 application safe from keyloggers?

    You can't. In the battle between kernel mode and user mode, user mode loses. That's why we have a distinction between kernel mode and user mode in the first place.

    Why should you ever call MessageBox from inside a message handler that is re-entrant? "I'm having a hard time explaining to people that it isn't a blocking call."

    I don't even understand the question. And it is a blocking call. The function doesn't return until the user responds to the message box.

    What happens when you pass NULL to ShellExecute, like you did in one of your articles? "Is UI suppressed if I pass NULL?"

    The window handle is used as the parent for any dialogs or messages that the ShellExecute function may need to display. If you pass NULL, then you get the same effect as if you had passed NULL to, say, MessageBox. In the article, the thread has no UI active, so any error messages displayed by the ShellExecute function will appear as top-level unowned windows. I discussed this issue in detail a few years ago. If you want to suppress UI, then pass the SEE_MASK_FLAG_NO_UI flag to ShellExecuteEx.

    Is there some way to use Explorer's filename sort function?

    It's called StrCmpLogical. Michael Kaplan discussed this function two years ago with a follow-up last year. Of course, if you want to mimic Explorer exactly, you also need to respect the REST_NOSTRCMPLOGICAL policy.

    Is there a way to sleep for less than one millisecond?

    I don't know either. I've never needed to do that. (I try to get eight hours each night.)

    Why are notification icons limited to 16 colors in Windows 95 and 2000?

    They were limited to 16 colors on Windows 95 to conserve memory. Windows 2000 inherited that code and by default, each version of Windows works the same as the previous one. There are millions of lines of code in the shell. It's not like somebody goes through every single one of them and says, "Gosh, should we change this line in the next version of Windows?"

    Does Raymond use _alloca?

    Nope. It wasn't in K&R C, so it's not part of my world view. And incautious use of _alloca can result in security vulnerabilities.

    Windows can only handle 64 threads.

    This statement is patently false. We've seen that even without taking any special precautions, we were able to pack about 2000 threads into a process before running out of address space. What the person probably meant to write is that 32-bit Windows supports a maximum of 32 processors. The reason is that the functions that manage sets of processors (such as SetThreadAffinity) use a 32-bit value to represent processor masks. Note that for 64-bit Windows, these masks were expanded to 64-bit integers, so 64-bit Windows supports up to 64 processors in principle.

    How does that Temporary Internet Files thing work?

    It's a shell namespace extension junction point.

    Why are some count parameters declared as signed integers?

    I don't think there's a profound reason for it. Each API designer is empowered to decide how their functions will work. After all, the original strlen function returned a signed integer, too. You might want to ask Brian Kernighan; he was doing it before Windows. (Signed integers do have the slight advantage of being resilient to integer underflow. If a and b are both non-negative integers, then a - b will never underflow.)

    Why does the desktop lose track of icons, so it has to refresh them?

    I'm not sure what you mean by "lose track of icons". Maybe you're asking about lost change notifications (in which case redirected folders can cause problems with lost network notifications). Or maybe you're talking about icon repositioning (maybe the previous icon locations weren't saved).

    Questions about DLL imports, exports, and cross-module memory

    I inadvertently answered this question in a rather long series of articles on DLL imports and exports, and a discussion of cross-module memory allocation.

    I want to see your blog stats.

    I thought that too, until I saw them. When you get over a million hits a month, a list of all the referrals is just a giant pile of noise. I haven't bothered analyzing the referrals because I have other things to do in my spare time that are more interesting.

    I'd love to see a series of things that are obvious to you but not obvious to everyone.

    How do I know what is obvious to me and not obvious to everyone?

    The next category is, of course, the people who ask questions on things that I listed as topics I am not inclined to cover.

    I have a problem (describes problem).

    I don't think your problem really is of general interest. But it's clear that you're not respecting the modality of the window.

    I'm trying to improve the performance of my specific scenario.

    This doesn't strike me as a topic of general interest.

    What are your thoughts on this research project? What are your thoughts on this Microsoft product?

    I think you confused me with Robert Scoble.

    I have a problem (describes problem).

    This doesn't strike me as a topic of general interest.

    Why does Internet Explorer do X?

    Internet Explorer is explicitly on the list of things I am unlikely to cover.

    Or the people who ask questions I've already answered or questions I've chosen to answer elsewhere.

    Help me modify files that I didn't write.

    Doing this breaks servicing.

    What is the long pause after listing a directory the first time?
    Answered in A brief and incomplete history of FAT32.

    And then there are the questions I can't or choose not to answer.

    Why does the window manager force windows fully on-screen when the workstation is unlocked?

    I don't know either. It makes sense to force windows on-screen after a change in resolution, but if the resolution didn't change between the lock and the unlock, there's really no need to go around "fixing up" window positions.

    What did Apple copy from Microsoft and vice versa?

    I'm not going to touch this one. I don't see any upside to my answering it, only downside, and I don't welcome the flamewar that will doubtless ensue.

    Do you know anything about this?


    Something about defragmenting.

    I have no special knowledge about defragmentation. Try The Filing Cabinet. They answered a few questions in one blog entry and even have a Defrag FAQ. Personally, I've been happy with Dave Whitney's defragmenter to defragment specifically-targeted files. (I don't defragment my entire drive because it seems like a waste of time.)

    A question about Aero glass

    I have no special knowledge about Aero glass.

    How about an under-the-hood look at the Windows Vista Start menu?

    I didn't work on the Windows Vista Start menu, so I don't know how it works.

    Do you have any insights into the evolution of WinHelp?

    Sorry, I'm an outsider just like you when it comes to help technologies.

    Long rambling question about ACCESS_DENIED

    I quickly lost interest.

    Please explain the subtleties of the ScrollWindowEx function when scrolling child windows.

    I don't know the answer and I don't feel like doing the research necessary to find out. Sorry. The fact that I left it unanswered from the previous suggestion box should have been a clue.

    That's all for this year.

  • The Old New Thing

    I've seen why people steal the foreground window for their dialog box


    Now, it may very well be true that many people who use GetForegroundWindow() as the owner for a dialog box because they don't know any better, but I'm not convinced that everyone who does so did it out of ignorance; I'm sure there's some malice in there, too. Here's how it may have gone down:

    Bug: I start the product setup, and then I go and work on something else, and then setup hits a problem, but the error message can't be seen because it's hidden behind another window.

    Result: Setup fails to complete.

    Expected: Error dialog is visible so user can address the problem and allow setup to complete.

    The programmer who is told to fix the bug, of course, tries to figure out how to fix the bug, and since the bug report said that the error dialog needs to be visible even when other programs are running, the programmer gives a shrug and does what the bug report says should happen.

    And that's how the installation program ends up disabling Task Manager.

    (Commenter Jamie has another very plausible scenario.)

  • The Old New Thing

    Tales from the interview: Lunch is not a competition


    One thing that many interview candidates fail to comprehend is that lunch is not a competition. You're not auditioning for Fear Factor. No matter how many times we explain this, candidates don't believe it.

    One of my colleagues took a candidate to lunch. As is typical, the candidate is asked whether there was any particular preference or phobia, and as is also typical, the candidate expressed no preference (trying not to look difficult). My colleague explained, "Okay, well, I like sushi, but please, if you don't like sushi, please just say so, and we can go to an Italian or Mexican place or even just grab a burger."

    — No, sushi is fine was the response.

    My colleague hesitantly took the candidate to a local sushi place. The two were seated and the wait staff came to take their order. From the way the candidate nervously read the menu, my colleague began to suspect that the candidate had never had sushi before.

    "Okay, now remember, you can order whatever you want. You don't have to order the sushi. They have all sorts of cooked food on the menu, too. Just order whatever you would like to have for lunch. I'm going to have (among other things) the salmon roe with raw quail egg, but please, that's just my personal preference."

    — Um, okay, yeah, I'll have the same thing.

    "Are you sure?"

    — Yeah.

    The food was delivered, and the interview candidate sort of started at it suspiciously.

    Fortunately, my colleague realized that without remedial action, somebody at the lunch table was going to starve and convinced the candidate to order some veggie yakisoba.

    Disclaimer: This story is a reconstruction from a conversation from over two years ago. Some details may be incorrect. I can't believe I had to write this, but apparently some people carefully deconstruct every word of these stories in order to call out any flaws or weaknesses.

  • The Old New Thing

    If you use an absurd signature, I might end up sending it back to you


    Despite my previous rant, absurdly elaborate email signatures are still common at Microsoft, and I'm not just talking about the ones that contain information that may be required by department policy. I'm talking about signatures that use bright colors, large fonts, maybe a bitmap or two, sometimes even a photo of the sender! I will sometimes mention in my reply, "Please consider making your signature less eye-catching. It distracts from the text of your message." But other times, I just incorporate it in to the reply more directly:

    From: John Doe

    Blah blah blah question blah blah blah.

    John Doe
    Technical Liaison

    telephone: 425-555-1212
    mobile: [available upon request]
    Make sure to visit my blog!

    My reply might go like this:

    To: John Doe

    Hi, John Doe.

    Blah blah blah answer blah blah blah.

  • The Old New Thing

    Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow


    If the documentation says that you have to call a function, then you have to call it. It may be that the function doesn't do anything, but that doesn't prevent it from doing something in the future.

    Today's example is the function GetEnvironmentStrings, which returns you all the environment variables of the current process in a single block, which you can then study at your leisure. When you're finished, you're supposed to call FreeEnvironmentStrings. That's what the documentation says, and if you did that, then you're in good shape.

    However, some people noticed that on Windows NT 4, the Unicode version of the FreeEnvironmentStrings function didn't do anything. In other words, the Unicode environment block didn't need to be freed. When you called GetEnvironmentStrings, the kernel just returned you a raw pointer to the real live environment strings (which, since this is Windows NT, are kept in Unicode internally). Since nothing was allocated, there was nothing to free.

    The problem with this technique was that if somebody called SetEnvironmentVariable in the meantime, the environment block changed out from under the caller of GetEnvironmentStrings.


    To fix this, the GetEnvironmentStrings function was changed to return a copy of the environment block even if you call the Unicode version. The corresponding Unicode FreeEnvironmentStrings function frees that environment copy.

    Programs that followed the specification and called FreeEnvironmentStrings (even though it didn't do anything up until now) were in good shape. Their call to FreeEnvironmentStrings now frees the memory, and all is right with the world.

    Programs that coded to the implementation rather than the specification are now in a world of hurt. If they simply skipped the "useless" call to FreeEnvironmentStrings, they will now find themselves leaking memory. On the other hand, if they gave lip service to FreeEnvironmentStrings by calling it, but using the memory anyway, they will find themselves accessing invalid heap memory, and all sorts of havoc can ensue.

    There's sometimes a reason for the rules that seem stupid at first glance. ("Call this function that doesn't do anything.") Changes to the implementation may make them less stupid in the future.

    (Credit goes to my colleague Neill Clift for providing the information that led to today's article.)

  • The Old New Thing

    Tales from the interview: Anticipating your own incompetence is not a good interview strategy


    Some years ago, there was a candidate who was interviewing for a programming position in my group. The first interviewer asked the candidate about career plans with that old standby, "Where do you see yourself in five years?"

    — In five years, I see myself in program management.

    This is a fair answer. Many people see programming as a stepping stone to management. It doesn't have to be, but it's certainly a career path more than one person has taken.

    My colleague decided to probe further. "What is it about program management that appeals to you?"

    — Well, after five years, all the kids graduating from college will be so much smarter than me, and they'll know all about the latest technologies, so I won't be able to cut it as a programmer any more. I'd have to go into management.

    It's bad enough that your career plan includes never developing any new skills and "failing upward" into management. It's another thing to anticipate it in your interview.

  • The Old New Thing

    The terms of service you have to accept before you can see them


    I had a few hours to kill at the airport a few years ago before my flight was ready for boarding, so I turned on my laptop and connected to the airport's wireless network. Like most pay services, they way you sign up is to fire up a web browser and go to any web site. Regardless of what site you go to, you are redirected to the "Here's how to buy a day's worth of wireless networking" site.

    So far so good.

    At the sign-up page, they asked for the usual information and also had a reminder that signing up for the service implies that you have read and accepted their terms of service. There was a link to their terms of service.

    Except that when you clicked the link, you were redirected to the sign-up page since you haven't signed up yet.

    In order to sign up, you have to accept the terms of service that you can't see until you sign up.

    I didn't sign up.

    Apparently I'm not the only person who's run into this Catch-22.

    Pre-emptive snarky comment: "Microsoft's license agreement for a bloated, inefficient and unreliable operating system is evil, anti-competitive, and offensive." When the legal department asks me to write a product license agreement, I'll keep your feedback in mind.

  • The Old New Thing

    Well at least that's one fewer program that relies on window handles being even numbers


    Earlier this year I received a piece of email from a programmer at a major software firm, reprinted below (suitably redacted) with permission. It was a sort of a mea culpa. (Remember: no guessing allowed.)

    Hi, Raymond.

    I'm a dev on Product X and recently we were sitting around having a beer after work, discussing the long and sordid history of our code base, and an interesting factoid came up that you might be interested in. Apparently, when we were writing Version 1 of our program many years ago when buffalo roamed the earth, window handles were always even numbers for whatever reason. We relied on that when we created our user interface library and interpreted any handle that was odd as coming from our library and even ones as belonging to Windows. This "functionality" has been sitting in our code base through all our releases.

    Just letting you know that we finally got rid of this dependency. You can finally use those odd handles once the next version of Product X comes out and the current version falls out of support. Should only take five years, ten tops.

    Sorry about all the trouble this caused. I'm surprised (and grateful) that you guys keep working as hard as you do on what I'll call Stupid-Dependencies-On-Undocumented-Features.

    One down, who-knows-how-many to go.

  • The Old New Thing

    QueryPerformanceCounter counts elapsed time, not CPU cycles


    An anonymous coward asks whether the QueryPerformanceCounter function counts elapsed time or CPU cycles.

    It counts elapsed time. It has to, since its value is governed by the QueryPerformanceFrequency function, which returns a number specifying the number of units per second, and the frequency is spec'd as not changing while the system is running.

    For CPUs that can run at variable speed, this means that the HAL cannot use an instruction like RDTSC, since that does not correlate with elapsed time. Commenter "A" appears to have found a buggy HAL that failed to take this into account and returns values that do not correlate with elapsed time.

    What would it take to create a counter that was tied to CPU cycles? Well, first, you'd have to come up with some definition of "CPU cycles" that is architecture-neutral. Maybe you'd say that it's a 64-bit value that increments at a rate proportional to the amount of work the CPU has done. And then you have to come up with some sort of definition of what should happen on multi-processor machines. What if you have two CPUs, one of which has gone into a HLT state (not running), while the other is busy doing work? Should the "cycle counter" run at half speed, since only half of the CPUs are running at full speed? What about hyperthreaded processors? It's all so confusing.

    As a final remark, commenter Ulric wanted to know what I meant when I wrote, "Throw in a handful of workarounds for known buggy hardware." What I meant was that the people who write HALs are aware of various types of buggy hardware and added code to detect that buggy hardware and work around the problems.

Page 1 of 4 (33 items) 1234