April 19, 2003 interview

My Interview At Microsoft

I had an interesting two days interviewing at Microsoft. Bottom line: I didn't say whether I accepted their offer.
April 18, 2003

Blog Entries as “Flair”

April 18, 2003

Brian Valentine talks Windows Server 2003

From Keith Wedinger: Interview with Brian Valentine, Senior Vice President of the Windows team at Microsoft regarding the development of Windows Server 2003. What's interesting is Brian's comment about the possible use of managed code within Windows itself.
April 18, 2003 interview

My Interview

Fri, Apr 18, 2003

After never thinking that I would, I had two days of interviews at Microsoft in the middle of March, 2003. The first day was with the MSDN content group. They’re the folks responsible for all of the technical articles at http://msdn.microsoft.com and the ones at Microsoft with the job most closely related to what I already do. It’s their job to tell developers how Microsoft technologies really work through articles, talks, samples, online chats and whatever other means they think will be effective.

My first interview of day #1 sticks freshly in my mind even two weeks later. It was a guy that I’d most closely describe as a human molecule. I’ve been told that he’s big into coffee and it’s not hard to see the effects the guy never stops moving! Likewise, his brain was constantly moving. He had all kinds of interesting questions about how I would turn my product ideas (created on the spot) into compelling educational materials of Microsoft technologies. Very fun.

I had several other fun interviews that day, all with smart people asking really great questions. However, after a few interviews, I was disappointed that nobody was asking me to write any code on the board. Apparently I had enough street cred that this wasn’t necessary for me, but one interviewer laughed and said I could write whatever code I wanted on his board if it would make me happy. Another had a strongly negative reaction to the idea that anyone would be asked to write code on a whiteboard, which he considered a supremely unnatural act. In fact, all day long, I had questions that dove into my motivations and my ideas, but none of them tested my technical knowledge at all until the very last interview w/ my potential boss’s boss (or my boss’s boss’s boss I lost track). She asked me to solve one thought question, one visual riddle and to write some code on the board. The thought question we talked through, but she threw out leading questions faster than I could come up with my own conclusions (although it was a very interesting discussion). The visual riddle seemed impossible at first, but I solved it in a few minutes. When I showed it to Don Box, he also declared it impossible, then solved it faster than I did (bastard). The coding question showed me just how unnatural it is to write code on a write board (even my simple linked list code had three bugs in it doh!). I am *totally* addicted to incremental code-compile-test and at one point even suggested using a goto to avoid erasing half of my code to insert a loop (truly the low point of the day).

Even so, at the end of day #1, I was energized. I’m one of those sick people that loves to be tested, especially if I’m confident that I know the answers. My last interviewer told me that I had done well and we talked about what would happen if I was offered both jobs from the two teams that I was interviewing with. She needn’t have worried day #2 did not go nearly as well.

The day #1 position was a highly technical position, which I’ve trained for since I was 12. The day #2 position was a <gasp> marketing position. But is was *so* cool. The job is to take whatever technology MS comes up with that day and make a business out of it. It was so diverse and so different than things I’d done before that I was drawn to it like a moth to a flame. Unfortunately, my answers made it clear that I didn’t have anywhere near the background needed for the job. I felt like a new college graduate, trying desperately to match something from my background to what they were asking.

As a measure of the kinds of questions I got on day #2, at one point, I was asked to develop a marketing plan for packaged ice to native Alaskans. “Did you just ask me to sell ice cubes to Eskimos?” I asked. “Uh, yeah,” he agreed. This was during lunch. And it wasn’t the hardest question I got! By my last interview, I was so scared that they might actually offer me the job and that my brain would explode trying to do it that I confessed that I was definitely not the man for the job. However, that didn’t stop my potential boss from drilling me on how to make a business on one of my sons’ hobbies (about which I know almost nothing).

Of course, I never clicked with anyone on the team from day #2 (you can’t click with someone that thinks you’re ignorant). However, the experience was amazing. One of the interviewers had a fabulous technique that I just had to appreciate — he had me role-playing in various real-world Microsoft-related situations over and over again til I swear my ears were bleeding. I’m a big fan of behavioral interviewing instead of role-playing as an indicator of someone’s real skills, but watching him put me through the ringer was a thing of beauty.

Speaking now from experience, I’d have to say that the Microsoft interview process is all about finding the right fit. That’s the case with all interviews, of course, but Microsoft seems to be very good at it. The fit includes both technical savvy (which they seemed to assume in me) and personality relative to the team. I fit very well into one group and not at all well into another. Working with the day #1 group would make me a successful part of the Microsoft machine, whereas if I had mistakenly gotten the job associated with day #2, I would have been set up to fail. So, if you are turned away from Microsoft, it means that you wouldn’t do well there. That’s a good thing to know; you certainly don’t want to take a job at which can’t possibly be successful. I know I don’t.

April 17, 2003 .net

WinForms Design-Time Integration, Part 2

"This is the second of two articles discussing the extremely rich design-time features of the .NET Framework. Part 2 continues the journey by concentrating on design-time functionality that you can implement beyond your components and controls, including TypeConverters, UITypeEditors, and Designers."
April 17, 2003

Printer Margins, Part 2

In this 2nd part of my discussion on printer margins, I show how to get real margin bounds taking the physical limitations of the printer into account.
April 17, 2003 colophon

Major Retrofit for ASP.NET 1.0

This site, the logo, business cards and t-shirts were designed by guonan. She’s got an amazing style and she’s very easy to work with.

The initial version of this site was implemented by Jon Flanders. The way he was able to make conflicting requirements work for this site was inspirational. Most of what I know about ASP.NET, I learned from this site and Jon.

Continuous grammar checking is provided by Craig Andera (whether I want it or not : ).

The site itself is hosted at SecureWebs.

The implementation is a mixture of ASP.NET as the navigation and layout framework and HTML for the content. My goals for the site were simple: look nice, easy to maintain. I didn’t want to give up FrontPage for my HTML editor (’cuz it has the Word key bindings that are hard-coded into my brain : ), but I wanted to be able to get the functionality of ASP.NET. So, the main content comes for an ascx file that reads in the index.htm and strips off the head section. Except for the home page, which is laid out specially, each default.aspx on my site just pulls in a single pageLayout.ascx file that does all of the layout using content from the target of the URL. By separating content from layout, I get the best of both FrontPage and ASP.NET, making both content and site maintenance easy.

April 17, 2003 tools

Hello IDispatch Lovers

I’m probably jumping into this topic a bit late but it doesn’t seem to end. I admit I haven’t read all article in this thread but I think I have an implementation solution for multiple dual interfaces on one class. And I would like opinions on it from others as well, and as to whether or not it displays proper COM implementation.

The implementation is very much like one that has been posted earlier, which I’ve seen different variations of many times before. However, I feel the one I am presenting allows all dual interfaces to be on one object and accessible via scripting without explicitly asking for a piece. No new interface definitions will be necessary with this technique. However, there may be one flaw. It will work ideally when none of the dispid’s of any of the dual interfaces collide, and when none of the named functions collide.

I consider a collision when the dispids,or names are equal, but the parameter list/type are not. Even still, when they do collide, the implementers using this technique can choose which should take priority.

Using ATL, I defined a templated class which should be derived by the class that exposes multiple dual interfaces.

template<UINT t_uiNum, class tihclass = CComTypeInfoHolder>
class XMultiDualImpl : public IDispatch
{
public :
typedef tihclass _tihclass;
    void Add( UINT uiIndex, LPDISPATCH pDisp, _tihclass & tih)
    {
        ASSERT( t_uiNum > uiIndex-1 && uiIndex>0 );
        m_arrDispImpls[uiIndex-1] = pDisp; //no need to addref, pDisp==this
        m_arrpTih[uiIndex-1] = &tih;
    };

    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) {*pctinfo = 1; return S_OK;}
    STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
    {return m_arrpTih[0]->GetTypeInfo(itinfo, lcid, pptinfo);}
    STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
        LCID lcid, DISPID* rgdispid)
    {
        /*perhaps the loop should check for a succeeded hresult instead*/
        HRESULT hr = DISP_E_UNKNOWNNAME;
        for ( UINT i=0; i < t_uiNum && hr == DISP_E_UNKNOWNNAME; i++ )
        {
            hr = m_arrpTih[i]->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
        }
        return hr;
    };

    STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
    {
        HRESULT hr = DISP_E_MEMBERNOTFOUND;
        for ( int i=0; i < t_uiNum && hr == DISP_E_MEMBERNOTFOUND ; i++ )
        {
            hr = m_arrpTih[i]->Invoke( m_arrDispImpls[i], dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
        }
        return hr;
    } ;

    LPDISPATCH m_arrDispImpls[t_uiNum];
    _tihclass * m_arrpTih[t_uiNum];

};

As an example, if we were to implement an object with 3 dual interfaces we would do the following

typedef XMultiDualImpl<3> XTriDualImpl ;

class DispTest3 : public XTriDualImpl,
    public IDispatchImpl<IDispTest1, &IID_IDispTest1, &LIBID_FirstLib>,
    public IDispatchImpl<IDispTest2, &IID_IDispTest2, &LIBID_SecondLib>,
    public IDispatchImpl<IThirdIntfTest, &IID_IThirdIntfTest, &LIBID_ThridLib>,
    public CComObjectRoot,
    public CComCoClass<DispTest3,&CLSID_DispTest3>
{
public:
    DispTest3()
    {
        Add( 1,(IDispTest1*)this, IDispatchImpl<IDispTest1, &IID_IDispTest1, &LIBID_FirstLib>::_tih );
        Add( 2,(IDispTest2*)this, IDispatchImpl<IDispTest2, &IID_IDispTest2, &LIBID_SecondLib>::_tih );
        Add( 3,(IThirdIntfTest*)this, IDispatchImpl<IThirdIntfTest, &IID_IThirdIntfTest, &LIBID_ThridLib>::_tih );
}

BEGIN_COM_MAP(DispTest3)
    COM_INTERFACE_ENTRY2(IDispatch, XTriDualImpl)
    COM_INTERFACE_ENTRY(IDispTest1)
    COM_INTERFACE_ENTRY(IDispTest2)
    COM_INTERFACE_ENTRY(IThirdIntfTest)
END_COM_MAP()

//IDispTest1 methods [code omitted for brevity]
//IDispTest2 methods [code omitted for brevity]
//IThirdIntfTest methods [code omitted for brevity]
};

I admit the constructor of the derived class leaves room for elegance.

Basically, all QueryInterfaces for IDispatch will result in the XMultiDualImpl vtable. The IDispatch implementation for that vtable basically asks each IDispatch vtable (of the dual interface) in it’s array one by one if it can carry out the call. If it fails, it moves on to the next dual interface vtable.

One might point out the following however :

pUnk->QueryInterface( IID_IDispatch, (void**)&pIDispatch );
pUnk->QueryInteface( IID_IDispTest1, (void**)&pIDispTest1 );

pIDispatch->GetIDsOfNames does not have the same implementation as pIDispTest1->GetIDsOfNames. as well as the implementation differs for ->Invoke. I question whether or not that’s a problem. Since IDispTest1 derives from IDispatch, I could see why it may be.

-herb


← Newer Entries Older Entries →