Monday, November 09, 2015
I have a new Pluralsight course on Visual Studio called Visual Studio 2015: Essentials to the Power-User. It starts at the beginning, so if you're new to Visual Studio it will help you get started, but carries on "to 11" as it were, covering things many everyday users of Visual Studio don't know. Here are the modules, each with their length:
- Getting Started (42:08)
- Projects and Solutions (13:23)
- Namespaces, Folders, and Files(27:03)
- Understanding and Personalizing Visual Studio UI Components (26:57)
- Exploring Relationships in Your Code(36:41)
- Using Search and Find Effectively(28:15)
- Letting Visual Studio Help You (46:28)
- Basic Debugging Features (24:04)
- Additional Debugging Features (44:30)
- Working with Designers (39:37)
- Useful Extensions (39:54)
- IntelliTrace and Code Map (25:57)
If you don't have a Pluralsight subscription, click the Author link over on the right hand side of this blog - click Subscribe, then Start 10-Day trial. That should give you a good idea of how valuable the subscriptions can be. (My company buys subscriptions for my staff, and I use my free author one all the time. It's a great way to learn a new technology.)
My main goal in this course was to have Visual Studio make sense to the learner. There are so many ways to do any action that sometimes when you learn something it seems pointless, and you quickly get tired of learning an endless parade of similar features. I worked hard to put these into an order that would lead naturally through the capabilities of the tool, and put things in context. If you watch all 12 modules, you'll know more Visual Studio than most developers - and you'll have a productivity boost to show for it that should be pretty impressive! Please do give it a try.
Thursday, October 08, 2015
On the Pluralsight platform, subscribers can access a discussion area for each course. The traffic in mine is light enough that I have set up an alert to send me an email for each new comment. I just got one for my StackExchange course that brought a huge smile to my face:
I have actually tried not to use Stack Exchange and stick to other sites. I had several bad experiences and have not gained any reputation at all on any questions that I asked. I have even deleted questions due to downvotes or other negative activity. Well after watching this, I understand the problems that I have had in the past. I really enjoyed hearing this and knowing the mechanics of how this works [...] I now know more about it to help me find the answers that I need when I am head scratching my way through coding.
When I first started reading I was thinking "here's a comment about how StackExchange is horrible and why have a course on it" - something I hear from some of my friends. But then it took a sharp right turn to the exact reason why I wrote the course. I mean this is exactly the persona I had in mind - someone who needs answers, but because of not knowing the way the sites work, not only isn't getting them, but is having an unpleasant experience and ends up avoiding the sites.
When I decide to write a course I let myself imagine some possible outcomes. This comment is just the sort of outcome I was hoping for. It keeps me motivated to create more
Wednesday, December 24, 2014
In my Pluralsight course, Using StackOverflow and Other StackExchange Sites, I cover all the things you really need to know to use the sites effectively and get answers to your questions, or a chance to show your skills. In the last module I explain how to help run the sites yourself, and I suppose you don't actually need to know that to use them - but knowing how they're run can help you understand what happens and why, so I included that material. I didn't include things that are really just for fun.
Right now, Winter Bash is on and it's just for fun. I made a quick video to show what it's about - take a look and let me know what you think. I hope to keep adding more "almost-great" items throughout next year.
Monday, July 02, 2012
I'm headed to Australia tomorrow (I won't get there till Thursday though) and I'm going to be doing some C++ talks while I'm there. Both are aimed at folks who haven't been keeping up to date on all that's been happening in the world of C++ over the last few years.
On Tuesday, July 10th, I'll do a free Tech Breakfast on the new features of the C++ language in the standard once called C++0x and now called C++ 11. I'll demonstrate how a lot of these features are already in Visual Studio 2010 and some in Visual Studio 2012. It runs from 9am to 11 am in Sydney, and you do need to pre-register.
Then all day Wednesday, July 11th, I'll do a course on modern C++ development with Visual Studio 2010 and 2012. I'll cover language changes, tool changes, drill into my favourite feature - lambdas - and show some of the cool things they enable, and give you some advice on best practices for writing C++ today. This course costs $300 Australian and will be held in Sydney just once.
I realize many people who read my blog don't need to come and learn this material. But perhaps you know someone who does? There is room in both sessions for more people - and I want to reach as many people as possible, so please spread the word! Registration links for both session are on the SSW page announcing them
Thursday, May 31, 2012
Recently one of my staff went to a week-long conference - her first. I gave her some tips before she went and it occurred to me that others might like them too. I hope you'll apply them to a trip to Tech Ed or some other conference where you can hear me speak.
First, here are some links to some other good posts on the topic. Here's me a year ago
, pointing to John Bristowe's suggestions for going to a big conference. And here's me 18 months ago
, pointing to Joey deVilla's suggestions for meeting people and talking to them. And here's a great question
(with an answer from me) on Programmers.StackExchange about networking at conferences. (BTW I met the asker of that question in person at Tech Ed, which was great for both of us.) And here's me four years
ago with some details on choosing talks to attend.
Now, here's the super condensed version of my advice:
- Plan your sessions in advance, at least two per timeslot. Carry a paper list of session names and room numbers so if you decide to bail on one, you know exactly where to run to, even if your electronics are out of battery and there's no wifi.
- Wear comfortable shoes and clothes, but not so comfortable that you would feel underdressed when talking to a potential employer or other business contacts. You will walk a LOT so choose those shoes with special care. It will be both stinking hot (outside - many conferences are held in hot places at muggy times) and freezing cold (if you end up right under the AC that is set on stun) so have a layering approach.
- Bring your own bag so you can tell it apart from everyone else's, and know just where to find things you need. Leave as much as you possibly can in the hotel room, to save your back during all that walking and to minimize what you might lose if there's any kind of bag mishap.
- Eat at the conference - it's a great time to meet people and this is where I usually bump into people I know.
- Go to the trade show floor, the community area, and the like multiple times. Serendipity will happen but you have to give it a chance
- Pack a somewhat larger bag than you need to - there is a lot of swag at Tech Ed and first timers can't resist lining up for TShirts and the like. Don't be that person who stuffs it all in the conference bag and checks a second bag on the way home. For one thing, someone may accidentally pick up your conference bag thinking it is theirs. Your conference bag and all your other swag should fit in your main bag.
- Pack your days and evenings FULL. Don't you dare watch TV in your hotel room! Go to the labs and try something you always wanted to learn a little more about. Download something that was just released and try it. Go to a party. Write up your notes (or better yet, blog them.) Send your boss late night emails about what a great time you're having and how much you're learning. Watch one of the sessions you didn't get to that day and then figure out if the speaker is likely still at the conference and how you can arrange to find that speaker and say thanks for the talk or ask a question. Fill out the evals for the talks you went to. There is SO MUCH you can do while you're on site, so try very hard to do it all. Make the most of the week, make it intense, and you will get more out of it by fully engaging.
- Try to do at least a few hours of sightseeing - one afternoon or evening - with some friends if you can. Maybe the attendee party is being held in some iconic location? Go to that. Or there's a restaurant in the town that you've always wanted to eat at? Gather a few folks and arrange something. Twitter is great with the conference hashtag - "who wants to go to XYZ tonight?" - I've done this for going on tours too. Gives you fellow geeks to talk to while you sightsee and strengthens friendships if you go with people you only know professionally. But don't overdo the sightseeing - you're here for the conference, remember.
I hope I see you there! The better prepared you are, the more benefit you will get from the conference!
Thursday, March 22, 2012
A mentoring client of mine needs someone to take on a specific project that should be about 500 hours of work. That fits nicely into a summer, and the work would be suitable for a student or a junior programmer. Here's the job description we wrote up (the mentor is me by the way):
- Familiarity with one or more programming
languages and IDEs
- Careful attention to detail, especially for
visual design (form layouts and alignments, fonts etc)
- Willingness to learn a large and complex project
- Time management skills including estimating and
reporting effort and time for tasks and projects
Nice to have:
- .NET programming experience and familiarity with
- Experience developing a Windows Forms
- Background in software testing or user support
The job offers:
- Work onsite in Peterborough
- 40 hours a week as soon as the student’s
schedule will allow
- Important work improving a product that is
mission-critical to real customers
- Specific project to be tackled and completed;
more will likely follow if this one goes well
- Training on the tools to be used and the tasks to be done
- Regular access to a world expert mentor in
- Pleasant working environment with nice
coworkers, relaxed dress code, and an open office
It's worth mentioning that there is no C++ involved in this at all. So don't hold back if you don't have it, and don't rush to apply thinking it's a C++ job, because it's not. If you're interested, email me directly (please don't just comment here or tweet me or the like) and
I will pass along your resume and contact details. I may have another client
looking for someone soon as well, with similar requirements, so let me know if I can hang on to your info and pass it along twice.
Saturday, March 10, 2012
I've been working on another C++ course for Pluralsight to complement the C++ WinRT/Windows 8/Metro course I did as well as the two-part C++ Fundamentals course (part 1, part 2). It's finished and live!
The topics I cover are:
- Avoid Manual Memory Management
- Use Lambdas
- Use Standard Containers
- Use Standard Algorithms
- Embrace Move Semantics
- Follow Style Rules
- Consider the PImpl Idiom
- Stop Writing C With Classes
I had a real blast writing this - while I was editing it I could hear my own enjoyment of parts of it. I hope you enjoy it too. A Pluralsight subscription is such a bargain - buy one for the topics you simply MUST learn for work, then use it on your own time to learn all those other things that you think you might benefit from. (I recommend Annual Plus - $500 gets you the sample code and offline viewing, all you can learn for a year.) Whether C++ is "must learn for work" or "I hear it's different know, wonder if it could help me" for you, I hope you find it helpful. Please let me know!
Tuesday, February 07, 2012
The minute this was announced, I knew I had to go.
Two days of "C++ today and tomorrow" with the bright lights of C++ today? Just try and keep me away! I'm so glad I was there - it was AMAZING and FANTASTIC and just generally wonderful. For me, personally, seeing so many old friends was a big part of it. The C++ team, other C++ MVPs, people I went to university with, and so on. It was also wonderful to see so many young people - including speakers, but also attendees, who were clearly in their 20s (and a few who were obviously in their teens.) After Chandler's talk I told someone "we can retire now: the future of C++ is in good hands." The speakers were not "the usual suspects" at a Microsoft event either. At a panel at the end of the second day, someone asked about C++ and the cloud and one of the answers was to indicate three speakers sitting next to each other: "Microsoft guy, Facebook guy, Google guy. Where isn't C++ in the cloud?" While that was a great cloud answer, I think it also highlights how inclusive this was - it was a C++ conference held at Microsoft, not a Microsoft conference.
Some fun quotes I happened to write down:
- “if it’s that ugly, it must be good” - Bjarne, on why some newbies imitate horrible code written long ago by their heroes
- “write C-style code, expect C-style errors” - Bjarne again
- “we know where bugs hide” – Bjarne (they hide in large tracts of complicated code)
- "dot dot dot is where the fun begins" - Andrei
- "real code is not supposed to fit on slides" - Andrei
- "this is legal" - Andrei (we needed to be reassured since it rarely looked legal)
- "if you're using new or delete, you're doing it wrong" - Herb (it's true!)
And Chandler's talk was very much a 2012 talk, with lolcat-like interjections and Simpsons references and even a how-agile-is-this update with a picture of Oscar Wilde in reference to Andrei's earlier off-the-cuff description of some template error messages (aka template barf) as being "a small novel by Oscar Wilde." The humour level was very high, much of it self-deprecating - no-one, not even the coiners of the terms, thinks RAII or SFINAE are great names, but what the heck, they're the names we use.
Even the little things here were so well done. Herb opened the conference by dedicating it to Dennis Ritchie, which I found extraordinarily touching and appropriate. He opened day 2 by celebrating the 20 year anniversary of Microsoft C7 which was C++ 1 for them, with Visual C++ appearing in the next release. There on the podium was the two foot long, 44 pound box, with multicoloured plusses all over it, in which it shipped.
And what was inside? A lot of books, and a lot of 3.5" floppies (I took this picture earlier, before the box headed to campus):
There are 5 or 6 floppies in each bag and apparently each bag had a part number of its own.
This conference was far more than a trip down memory lane, of course. It was a two-day Valentine from Microsoft to the C++ community, a demonstration of the "new growth" in modern C++ and the power and capability that is there for those who are prepared to start using the new features, and a chance for all of us to accelerate the learning we have to do. I so hope you were able to be there, or to catch the energy by watching it live and following tweets from those of us who had to share the bon mots and the fun. But if not, the on-demand videos are almost all there now. Here are the links:
Threads and Shared Variables in C++11
T. Lavavej: STL11 – Magic && Secrets
Variadic Templates are FunadicPanel:
The Importance of Being Native (Bjarne,
Andrei, Herb, Hans)
Herb Sutter: C++11, VC++11 and Beyond
Clang - Defending C++ from Murphy's Million
Alexandrescu: Static If I Had a Hammer
Stroustrup and Andrew Sutton: A Concept Design for C++Panel:
Ask Us Anything! (all
Fair warning: both of Andrei's talks, and the Concepts talk, are hard. This is cool new stuff that we are all learning about. There is no shame in pausing, rewinding, and giving something a second listen. Look, Chandler was running through pitfalls and problems that Clang catches, and showed some code with a problem I couldn't spot. A few minutes later in the Q&A, Bjarne asked him to clarify just what the problem was. Made me feel better!
Chances are you won't be able to watch any of these on fast forward, or skip any of them. So I'm asking you to invest 12 hours of your life to watch all of them. Do it! You won't regret it!
PS: They gave us shirts (it's all about the shirts for developers) with real code on the back and this on the front:
Highly appropriate. Of course, it's not a comeback for those of us who never left. But still...
Thursday, January 12, 2012
Perhaps not a great surprise, but today the precons for Tech Ed North America
were announced and mine is there too. It's well described in the previous blog post
and I'll be doing the same material at both events. So if Orlando, June 10th works better for you than Amsterdam, June 25th, terrific and I'll see you there! Registration
is now open.
Monday, August 15, 2011
Months ago, I tweeted "Once you have a hammer, everything looks like a nail" with a link to an interesting article
about the times you shouldn't use System.DateTime.Now - sure, you know how to use it, but it's not always the right tool for the job. Keyvan Nayyeri provides a number of alternatives for .NET developers who want to know when something happened, or how long something took. Definitely worth a read.
Then just weeks after that, Susan Ibach gave the SQL side of the story with a blog post
about avoiding the DATETIME type if you're using SQL 2008. I saw the headline and thought "what? what else would I keep a date or a time in?". The answer is, either something smaller or something with more precision. Makes sense.
Goes to show, just because you've heard of System.DateTime in .NET or DATETIME in SQL doesn't mean there's no other way to solve your problem. Keep learning!
Thursday, August 11, 2011
I'm pleased to see that Kenny Kerr is writing his C++ column for MSDN
again. He's also blogging again and in a recent entry
, he provides some really plain-spoken advice to people looking for guidance:
- "You can of course still use MFC but I do not recommend it as modern C++ can do
a better job of supporting the Windows developer."
- "You should never again use auto_ptr for anything."
So there! I agree with these, especially the auto_ptr one. It was an attempt at a smart pointer that just wasn't smart enough. We have shared_ptr and unique_ptr now and they work in collections and are truly smart pointers. Use them and stop typing delete in your code entirely.
As for MFC, it does fill a need and I certainly wouldn't scrap a working MFC app just because the library is getting old (the facelift a few releases ago helped) but if I was starting a brand new application from File, New Project I would need a good reason to use MFC as my UI framework.
Tuesday, August 09, 2011
People often ask me what Visual Studio Ultimate offers that other versions do not. There's a handy chart on the Microsoft site:
The only problem is, if you don't know what "Architecture and Modeling" includes, it's easy to think there's probably nothing useful in there. So I was pleased to see a blog post by Susan Ibach from Microsoft Canada showing how easy it is to generate a sequence diagram from code, and how that can help you understand code you've inherited from a predecessor. That's one of the diagramming tools included in Visual Studio Ultimate.
Right click in some code, select Generate Sequence Diagram, set some options (does getting a property count? What about calls to methods of String or other .NET Framework classes?) and presto, you have a sequence diagram.
This sort of thing can save you a tremendous amount of time, and that means it can save your organization money. That's why some people buy Visual Studio Ultimate, after all. Having access to a tool like this is one of the ways I can "hit the ground running" when I join a project. If you need to do the same, make sure you're not ignoring a capability you already have.
Monday, August 01, 2011
I consider myself a pretty skilled debugger, and reasonably familiar with the things you can do in Visual Studio (My Visual Studio course Part 1
and Part 2
, for example.) Conditional breakpoints
in C++ and in C#
, breakpoints that only break every 10th time
they're reached, customizing the data tip
that shows when hovering over one of your own types, making data tips transparent
, and plenty more
have all been covered here in the blog over the years. But I still come across things I didn't know before, or didn't try before.
Take this blog post
by "Daan-Nijs" about the abilities of the watch window. I knew the first one, but the rest are new to me:
- Changing a value in the watch window
- Changing a type in the watch window
- Inspecting an array in the watch window
Then there's re-running or skipping code by dragging the instruction pointer - I only knew I could right click somewhere and say Set Next Instruction. Finally he includes a reminder of how to enable Edit and Continue. All this is for C++, but you're welcome to give some of the techniques a try in other languages and see what happens. Being a faster and more productive debugger will rocket you up the overall productivity leagues like nothing else.
Friday, July 29, 2011
Since Tech Ed came and went during my blogging hiatus, I didn't get around to providing links to some of the sessions you might want to see. It's time to correct that omission:
There were other sessions I attended, including a great interactive session that was not recorded called "C++ Renaissance at Microsoft: How the C++ Developers Can Get Involved" with plenty of conversation between Microsoft people and native developers. You might want to do a little searching on the main Tech Ed Video site
to see what interests you.
Wednesday, July 27, 2011
Today saw the release of the first episode (naturally, Episode 0) of GoingNative on Channel 9. As the introduction says:
GoingNative is a new, monthly show on C9 dedicated to native development and native developers, with an emphasis on modern C++.
You know there's been a lot of talk about the C++ Renaissance. I'm happy to see that phrase get picked up, and I've got another one for you: Modern C++. Or as some folks like to say "not your father's C++". If you think C++ means manual memory management, strings as arrays of characters and a strange cast of global functions, and longing for a library or framework that might rival what .NET has to offer, then you haven't been keeping up with C++. The good news is that it won't take you long to catch up - shared_ptr and unique_ptr, the Standard Library, lambdas and other Modern C++ goodies are easy for both managed developers and longtime native developers to learn.
In Episode 0, Charles Torre (longtime C++ friend) and Diego Dagum (C++ Community lead, blogger, and Tweeter) lay some groundwork and, of course, show code. It's always about the code, right? Then, they ask you to get involved. Whether you're someone who wants to learn about C++, or someone who wants to make sure something about C++ gets taught to others, speak up! And yes, that includes topics on non-Microsoft platforms. Email C9GoingNative - they're using hotmail - or on twitter, follow or talk to @C9GoingNative. (There's a Facebook group, too - whatever way you like to interact is welcome.)
But wait, did that sound like a whole episode? Nope, they grab the camera and head over to see Ale Contenti - one of my favourite team members and one I've done interviews and sessions with before. His talk gets technical fast, which is one of the things I like about him! I too have a soft spot for 6502 assembler and find template meta-programming a bit of a write-only technique. I, too, like "the power the language gives you to make the language bigger with libraries" and think that's part of the appeal of C++ for me. Well, that and the power and performance and control, of course. Are there downsides? Well, there's what Joni Mitchell called "the crazy you get from too much choice" - C++ gives you many ways to do everything, according to your circumstances, and having to decide how to do it, or having to connect two components that made different choices about something as simple as how to represent a string, can be frustating. As well, it's great to be in control, but that does mean that nobody is looking after you. If you're inexperienced (and sometimes, even when you're not) you can make dangerous choices and, as we like to say, shoot your foot off. Security holes and vulnerabilities are important and C++ will let you write bad code, so you need to be aware of best practices. Both Ale and Diego address these points, and you can expect to see more of that in time to come - especially if you ask for it!
Looking forward to next month's show already,
Thursday, March 31, 2011
You go to Tech Ed to learn about technology - developer tools, sysadmin tools, platforms like SharePoint or Windows Phone. But there's more to your work than the nuts and bolts of how to solve a technical problem. Do you use social media effectively? What would an effective use of Twitter or Facebook look like, anyway? Are jobs shifting because of technology? How important is cross-platform development? How important are new platforms? How do you react to big changes in your technical world and direct your own career?
Well, there's a Tech Ed precon Sunday evening
that covers that exact topic. And look who's involved: Stephen Rose
(Windows Community Manager), Zeus Kerravala
(Distinguished Research Fellow and Senior VP, Yankee Group), Richard Campbell
(Co-founder of Strangeloop Networks, co-host of .NET Rocks!, host of RunAsRadio, Microsoft MVP, Microsoft Regional Director),
(Senior Technical Director for Penton Media’s IT & developer publications, author of SQL Server Developer’s Guide series from Osborne-McGraw-Hill),
(Microsoft Regional Director, Founder of InterKnowlogy),
Michele Leroux Bustamante
(Chief Architect with iDesign, Microsoft Regional Director, Microsoft MVP, author of Learning WCF (O’Reilly)),
(Principal Developer Evangelist for Microsoft, Central Region),
(Microsoft Academic Developer Evangelist), Sean Deuby
(Technical Director, Penton Media’s Windows IT Pro Magazine, Microsoft MVP),
(Senior Industry Analyst, Penton Media’s Windows IT Pro and Supersite for Windows; author of Windows Phone Secrets), John Willis
(VP of Training & Services, Opscode), Laura Hunter
(Principal Technology Architect for Microsoft IT’s Identity & Access Management team), Yung Chou
(Microsoft Senior IT Pro Evangelist, East Region) and Barbara Yamauchi
(Microsoft IT program manager for developer tools and IT lifecycle management). Wow! And this is an interactive panel discussion, so you can help to shape the conversation.
There is a small fee ($99) and you have to arrive Sunday afternoon so you'll be able to attend. But it looks like a heck of an evening! Glad to see so many RDs and MVPs on that list.
Thursday, January 20, 2011
One of the things C++ developers have had for ages is a way to see a function's return value in the debugger, even if it isn't kept in a local variable. For example, see tip 29 in this list of Visual C++ tips
for VC++ 6.0 - a product released 12 or 13 years ago! Managed developers would like this ability, too
. Jared Parsons, from Technical Strategy Incubation, points to a set of requests, and explains
why it appears that VB has it already. (And you thought VB6 legacy support wasn't going to help you!)
Take a look and see what you think. Would it be worth the possible performance hit?
Wednesday, January 12, 2011
Since midsummer I've been watching the "STL on STL" series accumulate on Channel 9. The lectures appeared as "part 1 of n", "part 2 of n" and so on until, in the bleak midwinter, part 10 of 10 appeared, so they must be done. Here are some links to them all:
There really isn't any universe in which the material this series covers can be called Introductory. When Stephan has finished introducing you to the STL, you will know an awful lot. And in this century, knowing the STL is a vital part of being a C++ developer. Many developers are scared of it: they think it's difficult and complicated. And to be honest, it can be. There's an awful lot going on and there is a lot to learn. Watching these videos, you can see how much Stephan LIKES this material, likes this library, and he's clearly not scared of it or trying to impress you with how difficult it is. He wants you to know all this. And if you follow along (and even do the homework!) you will catapult yourself forward in your STL knowledge and abilities. Take the time to do it, you won't regret it.
Friday, December 31, 2010
I was lucky enough to be part of a spirited email discussion recently on the topic of exceptions. And luckier still that Diego Dagum, the new C++ Community PM, has summarized it on the VC team blog
. You should enjoy reading the "best practices" we worked our way around to, like:
Most MVPs agreed that, despite not being illegal in C++, throwing primitive
types like int, long, etc., or similarly Windows-based
ones like HRESULT, etc. is a
coding horror as inabilities to catch those in the proper place will make the
application crash with a hard post-investigation to determine where they are
Of course, we ended up talking about checked exceptions, one of the things I really hated about Java personally, and RAII which is a critical way of thinking if there are exceptions flying around your app. STL joins in with a comment that could be worth gold to someone dealing with SEH:
I strongly recommend AGAINST using the /EHa compiler option. Either /EHs or
/EHsc should ALWAYS be used, with /EHsc being preferable (it's faster because it
assumes that extern "C" functions won't emit exceptions - while technically
permitted by the Standard, sane code should never attempt to do such a thing, so
giving up that ability is worth the performance gain).
And I am sure the comments will continue to grow and the conversation continue. This is how we all get better, by discussing and sharing and occasionally defending our practices. It's a must-read.
Thursday, December 23, 2010
It's the time of year where people set themselves goals - for the whole of 2011, for the next few months, or just in general. And you can read a lot about SMART goals and how great they are. Opinions vary
on exactly what the letters stand for but I'll go with Specific, Measurable, Attainable, Relevant, and Timely. So if I'm giving you a performance review and I say "you should be more helpful", that is not a SMART goal because we can't measure your helpiness and it's also not terribly specific and I haven't given you any kind of time frame for improvement. If you're not helpier tomorrow, have you failed your goal? What about next week? Next month? How long do you have to get more helpful? If I say "you should fill out your timesheet more often" it's still not a SMART goal because it's vague and doesn't have a time element and so on. I can make it a SMART goal by saying something like this: "over the next 6 weeks, at least 5 weeks' timesheets will be completed by 10am
of the next Monday morning." The relevance will have to come into play when I explain to you that late timesheets delay our billing of clients and mess up our cash flow. (Or whatever; we actually don't use timesheets here, but that's not the point.)
So OK, we have this concept. And it seems like a pretty good one. After all, if you write it like that, we can come back after 6 weeks (or whatever) and say "pass" or "fail". But let's look at the timesheet-laggard above. Let's say that person misses week 1 and week 2, then goes flawless after that. Still fail? If you feel that way, then as soon as the laggard misses week 2, why keep trying? You've blown the goal, right?
Then there's the matter of the consequences of blowing the goal. Am I going to fire you for messing up my invoicing and causing cash flow headaches and just generally not caring about the business? (I might.) But if you have a goal to pass a particular cert, and you fail it, is anyone going to fire you? Or you have a personal goal to run some distance under some time and you don't get to that time, will you give up running?
Here's I. M. Wright on why having a dozen year-long SMART goals is just wrong
- they take so long to write, if people meet 11 out of 12 they can still have a fail of a year, they're all about you when you're actually part of a team, and so on. Since they're unavoidable at some companies, he has some suggestions how to have 4 or 5 really good ones. He also doesn't like SMART for stretch goals, and I agree. Christophe is more about how things change over an entire year
, so the goal is probably not relevant by the time limit. The top answer to this StackOverflow question
says they're not good for developers, period.
In answering this StackOverflow question
I realized something. SMART goals are good for "shape up or else" goals, put on a person by someone else, that allow just a few weeks to achieve something really, well, specific, measurable, and relevant. Do your timesheets. Come to work on time. Include a decent comment when you check in your work. They're really not good for "be a better person", "lose weight", "make more money", or even "get a paid acting job". You just need a different way to express and measure progress on those kind of goals. If you're setting a goal for yourself, unless you think you're correcting a deficiency and have consequences lined up for failure, don't make it a SMART goal.
Sunday, December 19, 2010
Many people really don't understand where P/Invoke signatures come from, or what they mean. They head over to pinvoke.net
, which - don't get me wrong - is a hugely important resource, and then blindly paste in whatever they find and try compiling and running their code. Or they use the superbly helpful P/Invoke Interop Assistant
. Again, paste, build, run, works on my machine.
This is a great way to start. The problem is assuming that once one run worked, you're done. You need to read and understand the P/Invoke signature you are using. Especially when you are passing in a pointer, or getting a pointer back, you must know who owns that memory and who will clean it up. Are you handing it over to the native code to manage? Is there a risk your managed code will clean it up before the native code is done with it? Is there a risk the native code will clean it up, and then later the managed code will also try to clean it up? Don't think these things don't happen, they most certainly do.Here's an example
: a long running intermittent bug that was caused by a P/Invoke declaration that said the managed side would clean up, but that should have said the native side would (since the native side did.) And here's a nice summary
of ways to make sure that native resources (like handles) aren't cleaned up too soon by the managed side. Sorry, but you need to understand this stuff in order to interop successfully. That's where the phrase "head spinning interop" came from, after all.
Don't like it? Don't want to learn it? Then use an interop library like the Code Pack
that takes care of those sorts of things for you and exposes an entirely managed interface. Have to learn it whether you want to or not? Consider using the Code Pack as a reference for how to do interop properly. The full source code is available, and nicely commented too.
Friday, December 17, 2010
It's over 200 pages long, and over four years old, but I just heard about it recently. A long, dense discussion of whether certain C++ features (templates, namespaces, RTTI, etc) have a performance cost, and how to write code that incurs as little performance cost as possible. Its official name: ISO/IEC TR 18015:2006(E) Technical Report on C++ Performance
. In addition to runtime performance, it also touches on compile slowness, the "brittle base class" problem, and the different performance characteristics of various STL collections and algorithms. If you care about the speed of your C++ code, you should read this, even if some of it is already familiar to you.
I'd like to give some kind of "Restrained Understatement" award to this sentence:
Template meta-programming and expression templates are not techniques for novice programmers, but an advanced practitioner can use them to good effect.
To be clear about where these authors are placing the "advanced" bar, I don't use meta-programming, I consider it too advanced for me. And I have 20+ years of C++!
The whole report is platform independent (though embedded systems are discussed separately) and compiler independent, too. I wish it were updated for C++0x, but I guess that will have to wait until C++0x is settled
. There's a 14 page bibliography, and you would do well to read many of them, though my source
for the link winkily pointed out another possible paper
. That one is old enough to get a driver's license, but I think you might enjoy reading it anyway. As the introduction begins:
It is important to understand how your programming language is implemented. Such knowledge dispels the fear and wonder of “What on earth is the compiler doing here?”; imparts confidence to use the new features; and provides insight when debugging and learning other language features. It also gives a feel for the relative costs of different coding choices that is necessary to write the most efficient code day to day.
It's only 23 pages long, and concludes:
... we have considered many of the significant C++ run-time implementation issues. We see that some wonderful language features are almost free, and others can incur significant overhead. These implementation mechanisms are applied quietly for you, behind the curtains, so to speak, and it is often hard to tell what a piece of code costs when looking at it in isolation. The frugal coder is well advised to study the generated native code from time to time and question whether use of this or that particularly cool language feature is worth its overhead.
Good advice, in 1994 or 2010.
Wednesday, December 01, 2010
Lately there's been quite a lot of interest on programmers.se about interview questions
, and specifically the "coding at the whiteboard" part of the interview. It came up in a discussion of FizzBuzz
, in one about "testing" your whiteboard code
, and in one about question 11 of the Joel test
I ask candidates to code at the whiteboard. I ask an intensely simple question, because I am mostly testing for things other than the actual code the person writes. I know, however, that there are places that actually want you to tackle reasonably challenging problems. I came across this blog entry
by Diego Dagum
(who edits The Architecture Journal, writes architecture columns, and is committed to native C++big time) that walks you through a C++ whiteboard problem that is decidedly non-trivial. What I found interesting is that he starts his "thinking aloud" the same way I would, but then when I would start writing something that worked for valid input, he first started to set out examples of invalid input. And when he wrote the code, it starts by rejecting various categories of invalid input before processing anything. It's cool to see someone thinking differently from me.
One thing really struck me. He spends over a page on the signature of his method - why he called it rtoi, why it returns an unsigned int, why its argument is const, whether it should take a unicode string or not, why an STL string and not a char*. See how much these problems reveal about a person? That kind of care and precision is not something you can discover by asking a person "how important is it to you that a method signature is chosen with care? Can you give me some examples of naming methods you have done?" Coding in a job interview is about so much more than syntax. Are you prepared for the whiteboard?
Saturday, November 13, 2010
Wow, these things get up there fast! My sessions were very well received and I had such a great time doing them! In the order I delivered them, they are:
- Women In Technology Panel - Claudia Woods, Freena Eijffinger, Paula Januszkiewicz, and Rhonda
Layfield joined me to take questions from the audience and talk about what was on everyone's mind. There's really no video - just the title slide for the whole hour. Please listen!
- The Windows API Code Pack: Add Windows 7 Features to Your
Application - This one includes screen capture so you can follow along in the demos. You can also download the powerpoints from this page, and as I mention in the talk, the demo code is the samples that come with the Code Pack.
- Modern Programming with C++0x in Microsoft Visual C++
2010 - I had a great time delivering this talk even though it was the first time I delivered this version of it. The attendees responded by putting the talk in the top ten for the whole conference - thankyou! It, too captures the screen and slides, and you can download the powerpoints.
- Advanced Programming Patterns for Windows 7 - Another talk I was doing for the first time and I enjoyed it too. If you'd like the sample code, stay tuned - I will blog when the recipes are released. The slides are with the video of the screen and slides.
If you came in person, thank you! If you couldn't be there, please watch the videos and leave me a comment. Speaking on technical topics really is the most fun you can have standing up, and I can't do it without audiences.
Tuesday, November 09, 2010
is an amazing program. Startups (companies under 3 years old with revenue under a million dollars a year) that are making software can have full access to Microsoft developer tools (yes, MSDN Ultimate for every developer in the company) for FREE. There is a $100 exit fee, but it costs you nothing to get started. We are a Network Partner and have sponsored a number of our mentoring clients into the program.
Well now some firms are seeing the end of that three-year membership ahead of them and wondering, what's next? Soma has announced
a truly generous offer. Graduates from the program can have that exit fee (nominal as it was) waived, and can keep and continue to use all the software they acquired while in the program. For some, this will be all they need to keep on making great software with those tools. But some will want newer versions as they are released, or will want the Windows Azure subscriptions that come with an MSDN subscription. So for the (very low) price of about $1000 per developer, they can continue their subscriptions for another two years. That will take care of developer tools like Visual Studio. As well, they can buy Microsoft Software Assurance at half price, if they need production licenses of Windows or SQL Server.
If your startup has been in business three years, and you've been paying people and renting an office all that time, I'm sure these prices look delightfully affordable to you. If you've been hesitating about joining BizSpark because you weren't sure what would happen after the three years, well now you know, so don't hold back! For those who are eligible it really is the best deal in town.
Sunday, November 07, 2010
Let's say you've written a great client (that is, not web) application. Perhaps you've added some specific features to make it great on Windows 7. Certainly you've made sure it runs on Windows 7. Or perhaps on Windows Server 2008 R2. Or maybe your app runs on Windows Azure, or Windows Phone 7. Good work! You put time and effort into confirming that your app fits your chosen platform. Now, would you like to be able to prove it with a suite of automated tests and a logo that shows you passed them? Of course you would.
So head on over to Microsoft Platform Ready
and take a look around. You'll find training resources to help you build applications that target Windows 7, Windows Server 2008 R2, and Windows Azure. You can test your app and get logos like Powered by Windows Azure
and Works with Windows Server 2008 R2
.You can even showcase your application in a marketplace, and take advantage of special offers like extended trials of developer tools from various partners.
This is an obvious step for anyone building a client application, on any part of the Microsoft platform. Investigate, join, reap the rewards
Friday, November 05, 2010
You may have noticed that the fall tour I'm doing features morning talks that go till about 11:30, and evening talks that start at 6pm. I've decided that between those two, I'll spend the afternoon in a coffee shop and host an "on the road coffee and code". As I explain on the Coffee and Code page I keep for this purpose, this is really informal. Just stop by, say hi, we can talk about whatever you like. If you were at the morning session, you might want to just walk with me from the venue to the coffee shop and continue the conversation. Or if you're coming to the evening session, you might want to try to find me during the afternoon to ask something specific, then head to the venue together. Or maybe you have a topic to discuss that has nothing to do with Building Awesome Windows 7 Applications in managed code: a C++ question, or an extending Visual Studio 2010 question, or whatever. That's great, and the Coffee and Code format is just the place for us to have that chat.
If you live or work near the venues for the fall tour, I'd appreciate your suggestions (by email or twitter) for where to hold these. Obviously we need wifi, power, and a table we can hog for most of the day. My default choice is Starbucks, but if you know a better one that I can easily walk to, please tell me about it. Once I've chosen the location I can finalize the times.
Looking forward to meeting everyone,
Monday, November 01, 2010
Here's something that happens to me a lot. I'm working on a project that is mostly Technology A, but I need a little Technology B. I want a sample or two to show me what it can do. I search the web, but often find mostly things written by people who don't know what they're doing and are posting their (possibly flawed) code into question-and-answer forums. I search MSDN, but often the newest technologies don't have their samples yet. I also remember to check if the All-in-One Framework people (I blogged about their coding standards document earlier) have anything. And if I still get nowhere I start asking people I know if they have one.
Well, now those helpful folks at All-in-One are kicking it up a notch. And remember, they cover all technologies and languages related to Microsoft tools. (Want to know more about them? Here's a fun video.)
And this goes back to one of my earliest blog posts - what you want may be what I need to give. Imagine it's your job to decide what samples to write. How are you ever going to find out what developers out in the big wide world want samples of? You could come up with a great idea and then find out people already had all the samples they needed for that. So that person wants ideas for samples. And here you are needing a sample. See how that works?
Just visit the wiki page and follow their instructions. It's a tad more complex than "shoot me an email and tell me what you need" and for good reason. Give it a whirl if there's something you need!
Saturday, October 16, 2010
Jennifer Marsman has built a very nice list of Windows 7 developer resources
. Of course, she had me at Code Pack (the very first item she lists as a matter of fact), but she carries on, drilling into both native and managed scenarios, covering libraries, SDKs, training materials, UX guidelines, samples, blogs - even Twitter handles!
There is a LOT of material out there and it's a little bit fragmented. This is a great post to help you find your way around. Remember, if you have a Windows app, it should be a Windows 7 app!
Tuesday, October 12, 2010
I'm teaching OO design and UML again this term, and one of the things I emphasize to the class is the dangers of coupling. (Get your mind out of the gutter, I mean classes with dependencies on each other.) It's not about calling methods of each other necessarily; it's more about if-I-change-this-one, I'll-have-to-change-this-one-too. Changes that ripple through a system are expensive and dangerous.
When I am helping clients with interop, they are often surprised to learn how entire applications and libraries can depend on each other without ever calling each other's code. For example, App A writes a record to a database table. Service B checks the table regularly for new records (or records with a 0 in the Handled column, or whatever) and calls a web service (or whatever.) Those applications are now coupled - if a change in one necessitates a change in the format of that table (or its name, etc) then the other must be changed too. Thinking ahead and doing all you can to reduce this kind of coupling is part of the challenge of doing good application integration, even if there are no interop calls in the solution.
And then there's performance. So often left until last, it provides another consideration that you should ideally have in mind all the way along. And as Rico Mariani points out, it also couples applications and libraries you may have thought were independent:
Two subsystems that both (loosely) use 2/3 of the L2 cache are going to use 4/3
of a cache... that’s not good. There may be no lines between them in the
architecture diagram but they are going to destroy each others ability to
Sound advice as always. Please read the post, and keep one more "don't forget" floating around as you design and architect your systems and solutions.
Tuesday, September 28, 2010
I love this image:
I know this is true because in my role as friends-and-family help desk, I get people to read the error messages and then I repeat whatever they just told me and then they are like "oh, I get it! Thanks! I'm glad I know someone who understands these darn computers!" This works over the phone when I can't even see the message.
Now why am I mentioning this, besides the fact I love this dialog? Because it comes from a lovely blog entry by Chris Jackson on why app compat problems can't be fixed by talking to the user about them. You slave over a lovely dialog with a button which might as well say CLICK HERE TO GET A VERSION THAT DOESN'T HAVE THIS PROBLEM or a checkbox that might as well say CHECK THIS IF YOU DON'T THINK ITS A PROBLEM AND ARE SICK OF BEING REMINDED but instead the user clicks JUST THIS ONCE I WANT TO USE THE OLD ONE BUT BE SURE TO TELL ME ALL THIS AGAIN NEXT TIME.
Is there a solution? I don't know. But you need to know people are like this.
Wednesday, September 22, 2010
I came across this blog post of a farewell email from Philip Su
, written as he was leaving Microsoft after twelve years. You might expect that someone leaving a company would have some negative things to say about it, but not Philip. He sounds like a very nice person and one who's done pretty well by being nice. I thoroughly approve. It is full of specific and actionable advice as well as philosophy. I liked "Smart people understand why smart people disagree." and his thoughts on how people rank themselves, and what influences their ranking of others.
Well worth a read.
Saturday, September 18, 2010
A first glance, a book about social media
might seem to be "dancing about architecture." But of course the target audience for the book is people who are not yet fully fluent in social media and it makes perfect sense to talk to such people using a medium in which they are fully fluent. That means book form makes sense.
I was lucky enough to get a preview copy of Working the Crowd: Social Media Marketing for Business from Eileen Brown. She and I have been working together and bumping into each other for years, which is why I agreed to read it. But I'm recommending it simply because it's good. It's full of no-nonsense advice and useful anecdotes. Just a few pages in, for example, she says:
If you want to progress in business, don’t wait to be discovered. Make sure you have a great online profile and a positive brand.
I'm not saying that no-one has thought of that before. I am saying that clearly stated and useful advice is a good thing, and this book is full of such advice. She clearly tackles this "this is just a fad" crowd, explains about "influencers" (like me) and lays out specific actions steps you can follow to have a good social media experience. This includes how to measure what is happening, which most companies desparately need. She even covers specific sites and tools, guidelines for blogging and Twitter, and how to protect yourself from reputation damage or legal consequences.
It's a good book. If you don't have a social media strategy yet, then reading this one will take you a long way forward. I recommend it to any business wondering about "the twitter". You can pre-order on Amazon now and I suggest you do, though you may want to adjust this link to point to the Amazon nearest you.
Thursday, September 02, 2010
I'm having a Coffee and Code of my own in downtown Toronto on September 23rd all afternoon. Actually, I'll start at 11 and be there until 6 to catch the "stop by after work" folks. If you've heard of Coffee and Code at all, you know how this works. If you haven't, I've made a page on our web site about it
. Just drop in and ask me "Is it true that the C++ language is getting new keywords and stuff? How can that be? And does it really matter?" or "Do you have the Windows Phone 7 tools installed? Can you show me an app on the emulator?" or "Is Visual Studio 2010 really nicer than Visual Studio 2008?" or "What local user group meetings should I be coming to?" or whatever else is on your mind.
So stop by any time between 11 and 6 on the 23rd to the Starbucks at Yonge and King. I'll be at the big table at the back, just walk up and say hi. We'll talk about whatever is on your mind, maybe some of you will talk amongst yourselves, maybe you'll show me what you're working on. I'm looking forward to it!
Tuesday, August 31, 2010
Let's say you read the entry about data structure visualizers
and in addition to all the STL humour you got excited about being able to control the way the debugger shows your objects as you work at understanding your application at runtime. And then you were sad because you don't do native C++ work and you don't know how you could get the same behaviour in a managed application. Well, have I got a keyword for you - DebuggerDisplay
. Don't like that MSDN page about it? Here's another
. Quick and easy, at least for simple types with only a few member variables. Give it a whirl. There's a nice example
with screen shots at Dev102.
Friday, August 27, 2010
As a new school year starts to roll around I naturally pay a little more attention to articles about undergraduate education. I'm once again teaching a one-term course on Object Oriented Design and UML at Trent University in Peterborough. This is of course just one piece of the curriculum. Trent is an interdisciplinary place and its graduates are expected to understand the concepts that underpin what they're learning. In fact this is what I see as the main difference between those with a university education and those without (though there are exceptions on both sides.) It's one thing to learn, perhaps by rote, the steps required to make a certain kind of application, and it's another to understand what you are doing and why. The latter kind of person generally finds it easier and easier to learn new things, connecting them to things already known, while the former finds it harder and harder as a mass of seemingly-unconnected facts moil around in an overly-crammed head that feels ready to explode.
I approve of valuing concepts over specific how-to's. It's hard work keeping up with the very latest technology when all you're doing is using it. It's even harder when you're also working on concepts and trying to teach. I don't expect a university to teach students how to use a specific user interface framework (MFC, Winforms, WPF, whatever) -- I expect it to teach them user interface concepts, illustrated with some framework the prof happens to know that's generally available. The students can then learn a variety of UI frameworks over their careers. But that doesn't mean I approve of all the ways in which programming as part of undergraduate education varies from programming in real life. Two specific variations I have a problem with are team size and problem size.
In real life, it's rare to work all alone, all the more so when you've only just graduated. Most university computer science grads will join a team of 2-10 developers reporting to a lead of some sort, with various people from QA, user reps, the business people and so on having various positions of semi-authority, semi-teammate in relation to them. Yet undergrads are generally expected to work alone on all projects and never discuss them with anyone until handing them in.
In real life, problems are not well specified, certainly not as tightly as undergrad assignments are. Most importantly, in real life user input is bizarrely ill formed. Users type letters where numbers belong, leave mandatory fields blank, even deliberately construct complicated bad input as part of hacking attempts. Yet most undergrad assignments do little or no input validation or error handling unless those are the point of the assignment. And of course, most undergrad assignments can be completed by an inexperienced programmer working alone a few hours a week (10 at most) in a week or two while most real problems take weeks and months of work by one or more dedicated resources to produce even a preliminary solution.
Trent (and I presume most other universities) addresses these issues with a fourth year course in which a team of students works on a real problem for an outside entity - usually a local firm or charity. They must gather requirements, code, test and implement a solution, and present to their peers and professors a summary of the project. Some students benefit immensely from this, though most take on far too big a challenge and struggle to complete it.
My contribution is to point out to my students where things are being simplified for them, where things would be vastly different in real life. Undergraduate courses simply cannot be the same as on the job training, and I don't want them to be. I want my students to be learning concepts and underpinnings as much as language syntax and how to work particular tools. But I want them to understand that when they start to put all this to use, things will feel very different than they did during class time. An assignment from your boss and an assignment from me are very different. (I've blogged before that in real life, you don't get 7/10
, you have to keep doing it until it is right.)
I don't have all the answers. Lots of people muse about this stuff. Here's the inventor of C++ on the same issues
. Easy to complain, hard to do anything about it, but we can all do our bit.
Monday, August 23, 2010
Have you ever heard of the All-in-One Framework? Well I hadn't. They've been around for about 18 months. Back in February, on their first anniversary, they described themselves like this:
...this initiative [has been] developed by the CodeFx Project Group to an "all-in-one code framework" that includes
more than 300 code samples, covers almost all Microsoft development
technologies, ranks 18th among 13000 open source projects on CodePlex,
received numerous kudos from customers, proved its values in real support
incidents, and created a lot of win-win opportunities within the corporation.
It looks like the participants are all Microsoft employees and they're collecting pieces of code for any language and platform that can be used to solve real world problems. On the CodePlex site, they elaborate:
Code Framework delineates the
framework and skeleton of Microsoft development techniques through typical
sample codes in three popular programming languages (Visual C#, VB.NET, Visual
C++). Each sample is elaborately selected, composed, and documented to
demonstrate one frequently-asked, tested or used coding scenario based on our
support experience in MSDN newsgroups and forums. If you are a software developer, you can
fill the skeleton with blood, muscle and soul. If you are a software tester or a
support engineer like us, you may extend the sample codes a little to fit your
specific test scenario or refer your customer to this project if the customer's
question coincides with what we collected.
For example, they've written a summary of the ways to call native C++ code from managed code. You can find the pieces elsewhere, but having them all together makes it easier for you to compare and contrast. They often blog additions as they are completed.
Now as you can imagine, a big team creating hundreds of samples needs some sort of vision and structure to keep things consistent. That's where the style guide comes in. And now you can download it from CodePlex. It's an 87 page Word document that covers everything you might wonder about, for both native and managed code, including tabs-vs-spaces (no tabs, please), how much to comment (as I blogged recently and not so recently), Hungarian Notation (use it in native code if you must, but it's a relic; do not use it in managed code), smart pointers (yes, but don't bring in all of ATL for them - I look forward to this section being updated for C++0x), the right way to implement IDisposable, and an especially nice section on Interop at the end.
I don't care what language you work in - this is a document you should at least skim. It could settle some arguments at the office, improve your code, and spare you from some horrible bugs. Download it, won't you?
Friday, June 18, 2010
I was visiting a mentoring client today and we wanted to look at the config file for an application that is deployed with ClickOnce. So I needed to know where it was installed. I know that you can get to installation locations pretty quickly from the start menu:
So I took a look at the ClickOnce app in the start menu:
That's a problem - no Open File Location. I tried a little web searching but wasn't happy with what I found. Then I remembered.
Start the app - simple enough, since it's on your start menu. Then bring up task manager. If you right click the app on the Applications tab, there's no joy:
But ... if you choose Go To Process (or just switch to the process tab and look for the right EXE name) then we're in business:
The very first choice, Open File Location.
And when we get there, sure enough, there's a config file (among other things):
Completely obscure path, but who cares, I can confirm the config settings for the running app and that's all I needed.
Monday, June 14, 2010
Metaphors can be dangerous things. Just recently I got into a Twitter conversation with someone who was using the metaphor "it's like leaving your car unlocked, or your front door" - meaning something you would never do and would expect to be dangerous. But in my neck of the woods, that metaphor triggers different neurons, having a meaning more like something you regularly do and would never expect to be a problem. (I not only never lock my car in my or a neighbour's driveway, I also know many people who would leave their keys in their cars in someone else's driveway.) It doesn't really matter whether you think door locking is normal, the point is your metaphor needs to have the same meaning for your audience as it does for you.
For an example of a metaphor landing really badly, check out Scott Berkun's blog post
on the "periodic table of visualization techniques." Now unlike Scott (who thinks the periodic table is obscure, complex, and unfondly remembered) I really like the periodic table. I think it carries a tremendous amount of important information in a very compact way, and explains some relationships succinctly. But I think it makes a poor metaphor when trying to discuss all the different ways you can present information visually. Plus, their particular version of it doesn't seem to have any actual periodicity, anything that's the same in each column, anything that's the same in each row, or any reason for the lengths of the rows. Always understand a metaphor before you use it. Otherwise you're working against your own goal - helping someone else understand your point.
Saturday, May 29, 2010
It's no secret that I'm not in my twenties. After all, I'm in my fourth decade of being paid to program. (To be fair, you enter that decade as you pass the doing-it-for-30-years mark.) I have gained a lot of experience in all that time, and not all of it is programming experience. I am slowly gaining wisdom and judgment in general. But am I losing things? Am I perhaps closed off to new experiences, or stuck in the mud? Is there anything you can in general conclude about a person because of their age?
I have two problems with that line of thinking. The first is that differences between any two individuals in a group are always larger than the differences between groups. I can easily find two 20-somethings who differ from each other more than either differs from a 30-something or even an 80-something. Women in general may be shorter than men in general, but I'm sure we all know a man who is shorter than most women or a woman who is taller than most men. What you know about the group doesn't necessarily apply to the individual. My second problem is specific to age - some age related effects are actually related to "you went to university in the 70s" or "you learned to code in the age of GUIs" more than to how old you are, others are actually about your life experience, still others your work experience. Two 60-somethings may not have gone to university at the same time as each other or learned to code at the same time as each other. That makes it even harder to generalize based on a single piece of information - when you were born.
A few months back, 'Dave' posted a series of myths about older developers and then debunked them. Do you find yourself believing any of these?
- Older software developers are more expensive
- Older software developers are less flexible and less capable of learning new
- Older software developers are less able to perform the arduous tasks of
software development (read: work long, painful hours)
- Older software developers are less mentally agile
- Older software developers are more jaded and cynical
My only issue with this list of myths is that it doesn't contain positive ones. It's also a myth that older developers are wiser, more tuned to business issues, better at talking to others, and so on. Some are -- I strongly believe I am -- and it takes a while to get there, but time passing isn't the only thing that brings about that change in a person.
I have to work with people a lot younger than me every day. Perhaps some of them think less of me because of my age at first. I'm pretty confident that doesn't last. If you're not an "older programmer" yet, I hope you aspire to be one someday.
Tuesday, May 25, 2010
When I started out in this industry (and I'm in my fourth decade of being paid to program) there was a definite culture of rudeness within it. Smart people weren't just allowed to be rude to not-so-smart people, it was expected. Being rude to others was how you proved you were smart, whether it was with a cutting insult thought up on your feet, or with a cruel proof of just where they had gone wrong. As a group we were especially fond of insulting those who weren't developers with brilliantly disguised insults they couldn't understand, or so the theory went. Who hasn't heard someone refer to "error codes" like PEBCAK or ID-ten-T?
But over the last generation or so I've noticed a switch. I hear the chair, keyboard thing still, but only self-referentially. That is after someone has asked for help, perhaps with a starting position of "I have found a bug in Windows", and then sorted it all out and realized they were doing something wrong, they may say "well it turns out the problem was between the chair and the keyboard after all, eh?". When I interview developers for a job at my firm, I ask about working with non developers (testers, technical writers, users, project managers) and I need to see (not just be told about) respect and interest for those people and those jobs.
Now not everyone feels that way. Meredith Levinson
asks if there is a still a place for the "I'm smart, I don't need soft skills" geek pride of old. Commenters point out that speaking truth to power is important, and those who won't be rude sometimes don't do it. David Starr
talks about how to tell someone that a thoughtless habit, like always coming late to meetings, is bothering you. I would skip the praise sandwich
, but I support the idea of pointing out the consequences of something another person may have thought had none. Interestingly, Susanne Biro
points out how people who are actively interested in learning soft or social skills can still be blundering about doing very rude things, apparently unaware.
I think in the end it's not that our industry has changed much. It's that people who are just starting out in it are often a bit rude. OK, sometimes they're very rude. But as they gain technical skill, many of them also gain the ability to take others into account and to work in teams. Those people get promoted. So now, hanging out with decision makers, with people who are allowed to represent their companies in public, with people who get paid to help other people get better, I mostly meet polite and interesting geeks. The rude ones probably still exist -- I just don't run into them very often. Which group would you rather be in?
Wednesday, May 19, 2010
A colleague of mine who is not near Toronto has a client in Toronto who needs .NET developers. They would like to start out with a contract position and it could become permanent if it's a good fit for everyone. Here's the job description:
Position: Senior Programmer / Analyst
Pay: $7,500 per month contract (negotiable)
Applicant must be an expert or proficient in:
- .NET Framework / C#
- .NET Services
- Microsoft SQL Programming
Experience in the following areas would be helpful but not required:
- Visual SourceSafe
- Mechanical engineering experience
The primary responsibility is to modernize a legacy C++ distributed application. This may include a redesign and possible rearchitect of the application. The final application should be an n-tiered application. The tiers would ideally be:
- WPF/Silverlight as the presentation layer
- A business layer with business components (C#) exposed via WCF
- A data layer
Where necessary, COM components can be preserved.
Other responsibilities include:
- Move image files from file database to SQL database
- Document the application
- Handle ongoing change requests.
Someone who moved from C++ to C# but didn't forget their C++ would be perfect. They are looking for more than one person so it sounds like a fairly meaty project. This is strictly onsite work, no remote work, which is why I mentioned where they are (east of the DVP; west of Pickering.)
Anything you email to me about this I will forward to my colleague who will in turn forward it to the Toronto folks. Good luck!
Tuesday, May 11, 2010
Programming is not one skill - it's a large conglomeration of skills. Some people are not very good programmers because they aren't very good at imagining their way through an algorithm. Others have great ideas and imagination, but it's painful to watch them type and they can't be bothered to learn how to use their tools (editors, etc) so they just take twice as long as everyone else to create the code. Still others are doing fine until their code does something unexpected, and then things fall apart, because they can't figure out what's going on. They step too soon, spend ages stepping through code that couldn't possibly cause the problem, then get impatient and end up skipping right past the problem. Worse, they don't seem to understand the capabilities of the debugger. I've watched people spend over 5 minutes patiently stepping into so that when they reach a particular line, they know how control reached it. Then I show them the Call Stack window and they say "oh".
I've blogged before about conditional breakpoints and tracepoints, hit counts, and so on. There is so much to the Visual Studio debugger that it is very hard to know it all. But the more you know, the better you are. And what's more, being a great debugger has more value than some of the other programming skills, because so much debugging happens at urgent times, is unexpected, and needs to be done as quickly and efficiently as possible. The difference in impact between being good and great is very large.
So how to be a better debugger? Partly, it's practice, especially practice with someone who's really good. That person can say "hey, what are you doing? Here's a way easier way to get there!" Even practice alone can motivate you to learn how to do something and get you reading the documentation or searching the web. You could buy a book, if anyone even buys books any more. You could take a debugging course, and spend a day or a week with someone who really knows every speck of this enormous tool. Of course, that costs money, travel time, and so on. Some of you will do it, and benefit from it tremendously.
But ALL of you can benefit from watching John Robbins' latest set of videos on Channel 9. It's in three parts and they total about three and a half hours. It hits the ground running and just doesn't stop. It's all using Visual Studio 2010 but the vast majority of the features he shows are in earlier versions too. I knew a lot of it (even the Go To Find box and the file opening etc) but I learned new things in the first ten minutes and continued to learn new things as they continued - both actual capabilities of the tool and interesting ways of thinking, like using hit counts on a breakpoint not to stop, but just to count how much some code gets run. I wish I could get the slides and code, but I guess some things need to be saved for the folks who actually take the course.
If you're a .NET developer, watch these videos. Now.
Thursday, November 26, 2009
I teach a course at Trent University on Object Oriented Analysis and Design with UML, and have done since the last century. I teach my students how to make decisions about the systems they will some day build, and how to draw diagrams that communicate those decisions to others. We find as often as not that the act of trying to make the diagram leads us through the thought processes that are needed to make good decisions. That brings huge value even if you never show the diagram to anyone else and never update it.
I've never been a big fan of "technical documentation" in the form of a giant binder that some poor person has to keep up to date any time the code changes. If you want to know all the methods of the Employee class, why not use Intellisense or the Object Browser or the like? But that doesn't mean I don't like making those diagrams at the beginning, when they help me to do my thinking. I also make them when I have something to explain, including when I bring a new person onto a project. So how much do I love this quote?
the UML ... was to be a language for visualizing, specifying, constructing,
and documenting the artifacts of a software-intensive system—in short, a
graphical language to help reason about the design of a system as it unfolds.
Most diagrams should be thrown away, but there are a few that should be
preserved, and in all, one should only use a graphical notation for those things
that cannot easily be reasoned about in code.
It's in an interview I already linked to, but it took Patrick Smacchia to point our those sentences to me. As I wind up the last few weeks of the course, it's nice to know that my position on the point of the diagrams and deliverables is aligned with one of my heroes.
Saturday, October 03, 2009
I suppose using Source Safe is better than using no source control at all. But it's slow, it can't handle non-text files usefully, it totally doesn't work over a slow network, and it corrupts its database from time to time for no discernible reason. It can't handle multiple people having a file checked out at once, so that forgetting to check in a common file (especially a project or config file) can either completely keep others from working or can make people get in the habit of working outside of source control for long stretches of time. It has had its day and you should replace it.
But let's say you're an all-Microsoft shop and you don't really have the time and energy to go looking for products from other vendors. You like knowing all your stuff works together and you're not entirely sure how you would integrate some other product into Visual Studio and into your workflow. You know someone who works somewhere that doesn't integrate their source control into Visual Studio and it causes them a lot of trouble. You looked at Visual Studio Team System and Team Foundation Server briefly, but at first glance all you saw was Big! Complicated! Expensive! We Don't Need All That! and you've never looked again. Or you talked to a guy who paid someone thousands of dollars to install and it took weeks. You can't afford that and don't like installation nightmare stories.
Sound like you? Sounds like lots of folks I know, and some I mentor. Well I have good news. Word about Visual Studio 2010 is starting to come out and I am liking what I see so far. Take this article by Brian Harry, TFS 2010 for SourceSafe Users. He says that there will be a version of TFS in the 2010 product line that will be as cost effective as Source Safe, can be installed on a domain controller (for folks who really only have one server kicking around) or on your laptop (Vista or Windows 7) and can be installed in a simple Next, Next experience that can take as little as 20 minutes. Wow! He includes the screenshots of the install experience to show you how simple it is.
And you don't just get source control when you do this. You get work item tracking and integration, build automation, all integrated into Visual Studio. If you're using a Team SKU of VS, you're good to go, or if you're using a Pro SKU you just need a TFS CAL and to install Team Explorer and you're good to go. Integrated work item tracking and source control with automatic notifications on checkins and work item changes saves most developers an hour a day. Add that to what you lose swearing at Source Safe and you just HAVE to give this a try.
Thursday, October 01, 2009
I came across a very insightful post from Paul Graham. Many of us know a manager who literally has meetings booked all day back to back, sometimes double or even triple booked. These are people who book meetings with themselves in order to have a block of time show busy in their schedule so they can do some non-meeting work. They end up with a week like this:
But what I hadn't thought about was how that changes the way they think about time, and about using up someone else's. Paul says:
You can block off several hours for a single task if you need to, but by default
you change what you're doing every hour. When you use time that way, it's
merely a practical problem to meet with someone. Find an open slot in your
schedule, book them, and you're done.
Thing is, lots of us work on a completely different schedule - a maker's schedule. We need long chunks of time to get into flow and to take advantage of that state to produce. A scheduled interruption, in the form of a meeting, can ruin an entire morning or afternoon. It may not be logical and it may irritate other people, but it's still true. Read Paul's article to be convinced - he articulates this beautifully and he really crystallized the issue for me.
I find myself slowly moving into a manager's schedule these days. I'm typically juggling a lot of projects, I am a manager, I have a lot of meetings and conference calls, and I spend less and less time heads down creating. This has caused some conflict with other people in my company who are still on maker's schedules. It has also caused conflict for me - when I have a maker-style day, I don't take care of the usual zillion little things like returning phone calls, answering emails and so on, and when I have a manager-style day, I don't produce as much "stuff" - code, decks, demo scripts, proposals, or whatever - as I otherwise would. Having names for the concepts should let me understand what's going on a whole lot better. Thanks Paul!
Friday, September 25, 2009
Scott Ambler says a lot of "detailed specifications" are just "detailed speculations". You think people might need some particular feature, so you write some very detailed material that says "you could click this button to confirm it" and "there could be this grid that would show you all the pending requests" and so on, and that also says "we think that if we code everything the way we've just said, it will take X hours/days/weeks of effort over Y elapsed days/weeks/months/years." And tempting as it is to say that all this is some sort of binding contract signed in blood, the truth is we're all guessing. Guessing what users might need, guessing what might be a good way to give them that (both in terms of what it looks like and in terms of how it would be coded), and guessing how hard or easy it would turn out to be. We're speculating. And the users, they're speculating too, about how they would use that feature and how important it is to them. It's an interesting thought.
Don't get me wrong. We write specs. We also guess what things will cost. But we don't write the kind of super-detailed, prototype-heavy, let's-list-every-field-on-the-report stuff until that last responsible moment. Do you?
Friday, September 11, 2009
There's still time to plan a trip to Boston for the BizSpark incubation week, October 5th to 9th.
As Sanjay blogs, you don't need to be in BizSpark to come - it's an event to help startups learn about Windows 7, how it can make your product better, and how to be a successful entrepreneur. You need to be at least interested in building an app that will include touch, sensor and location, the new taskbar or the new ribbon. That covers a lot of ground!
It's a free five day event, though you have to get yourself to Boston and find a place to stay. Up to three people from your firm can attend. Nomination details are on Sanjay's blog, but if you have a BizSpark sponsor you should ask your sponsor to send your nomination to Sanjay.
My firm is a BizSpark network partner. Generally speaking, we sponsor our clients - folks we're mentoring - and not people who are contacting us only to get into BizSpark. If you think completely legal free developer software (Visual Studio Team System, SQL, Windows etc) is just the ticket to get your startup started up, you should definitely look into BizSpark. It's a tremendous opportunity.
Wednesday, August 26, 2009
It wasn't long ago everyone was talking about a whole new way of working. It started with telecommuting in the 90's, but spread in this century to something far bigger. Remote work as a way of life, virtual teams, outsourcing, offshoring ... the scale just kept growing and the savings for companies appeared to be at least partly met by happy staff, whether that was a guy in the city who didn't have to spend 90 minutes each way in traffic, or a guy who was able to keep living in his small town while working for the big city firm so far away, or even a guy in a developing country who was able to earn more than his neighbours and follow the lure of high tech and problem solving at a time when no firms in that country were offering those jobs. I know many people in the big cities and the developed countries lost their jobs to those people, and I know it wasn't always simple to find traditional employment once the world of work started to change. Still, the world and the way many people in it earn a living changed and will not be changing back.
That said, in the mid 90s everyone I knew who was associated with any of this "new way of working" had come to realize it wasn't just a fire and forget sort of thing. You had to communicate a lot
. And while technology made some ways of communication simple and cheap, so that video calls and conference calls and instant messenger and desktop sharing and so on are all vital, it couldn't do it all. You have to get face to face still, and you have to do it regularly. I recently finished a 10 month contract for clients three thousand miles away. I did the vast majority of the work from here, and had phone calls and livemeetings many times a week. But every 4 to 6 weeks I got on a plane and I went there. And wow, the work we got done in those few days! Mini hallway meetings, lunches, dinners -- I typically could "touch" half the project participants in just two or three days, and solve seemingly intractable problems by going to people's offices and listening to them and looking at their body language and telling them they could trust me or asking them what the real problem was. It made such a huge difference to the success of the project. I didn't get paid for the time I spent travelling to them, or the nights spent away from my family, but I gladly invested that time to make everything go smoothly and to be a successful remote worker.
Some other folks have noticed this too, and in a far more systematic way. How's this for a conclusion
: "... common workplace-relationship problems, such as broken commitments, mistrust
and misrepresentation of information, occur more than twice as often with
virtual teams, as opposed to teams located in the same building. " Yikes! Apparently it's partly because things we do when we're upset with people work well if you see if each other regularly, but make things worse if you're apart. Or this useful summary
: "teams are a lot more effective when they're working with their friends in
than when they're working with those stupid offshore idiots
who never understand our designs or requirements
." So in that context, what could be a worse way of saving money than lowering the travel budget to zero and not letting people visit each other any more?
Yet that is exactly what's happening in a lot of companies. If it's happening in yours, do something about it. You need to visit your colleagues. If not, when your projects go pear-shaped, you may find the whole concept of virtual teams gets thrown out with it. And that would be a real shame.
Thursday, August 20, 2009
Recently I came across an article suggesting how a good developer should comment their code. This was aimed at those writing SQL scripts, but that doesn't particularly matter. The rules were the same ones I lived by in the 70's and for a long time since then. For example, at the start of each file there should be a modification history, like this:
/* Title: 002 - Setup SQLCMS.sql
Purpose: Setup the various components for SQL CMS
04/30/2009 - Buck Woody - Initial Script Creation
05/15/2009 - Buck Woody - Added MAPS load scripts
I copied Buck's since I don't have any like this myself kicking around. And why not? Because VSTS and TFS take care of that for me. Who changed it, what they changed, and why is all available in the repository. Duplicating it in the file itself just gives you another task to forget, and another pair of locations that might get out of sync. So I don't do these any more.
There's another kind of comment that we all used in the 70's and 80's and that was the "explain your names" comment. When you only had 8 characters to work with, you needed a big block of comments that told everyone that NPPLINV was Number of People Invited and CIDMNEW was Calculate Interest, Daily Method, New or whatever. But we don't have name length restrictions any more. So why do I still see this sort of thing:
Dim ClientName as String ' Variable to hold name of client
Dim ClientBirthDate as Date ' Variable to hold birth date of client
Dim ClientRepID as Integer ' Variable to hold ID of client rep
(Don't believe me? I saw this very code yesterday in a VB6 app I was debugging.)
As Jon Torresdal points out, if you choose your function names and variables well, you don't even need those single lines that explain funky-looking calculations. Extract your weird stuff to a function, even if it's a single-line function, and it explains itself. You can see a similar approach, though comments are never mentioned, in Justin Etheredge's post about isolating logic into little functions.
So let's see, no comments at the top to explain what the file is, no comments after each variable to explain its strange and abbreviated name, no comments before funky calculations because they've been refactored into single line functions ... well what comments even remain, then? Well there's commented-out code - but I have a rule against that. There's this sort of thing:
'only update confirmed date the first time it's confirmed
If DateConfirmed = Nothing OrElse DateConfirmed = New Date() Then
DateConfirmed = Today
Sometimes these comments are there because the developer wrote the comments first, as pseudo-code, then filled in the code. Other times they are just an attempt to translate the code into English for the reader. Does it help? Well, maybe. But comments are becoming less and less important as time goes by. Interesting.
Tuesday, August 18, 2009
I've read a few articles lately that have no praise for the praise sandwich. If you haven't heard that name before, it refers to something like this:
Joe, I really like the confidence and energy you bring to your work. But yesterday's outburst was unprofessional and frankly unacceptable. It's the sort of thing that could get you fired. But you're such a smart guy that I'm confident you'll never do anything like that again. You're an important part of the team and we're all glad you work here.
You start out by saying something nice, then criticize, then say something nice again to end the meeting on a positive note. So what's wrong with that? Well partly it's all the "but" in there. I've talked about that before
. There's more to it, though. Esther Derby says
it "tends to erode trust in the feedback givers intentions, and once that's gone,
there's not much chance any useful information will get through" which is a very good point. Her advice about how to deliver criticism is very good, most especially "don't sell past the close." Art Petty says
it is "insulting to the receiver and borderline deceitful" and is really about making the criticizer feel better, not the recipient. Of his tips, I especially like "link the issue to business impact" - one of the real strengths the boss brings to any situation is the extra information about the consequences of errors. I have found over the years that people who write code all day really don't see a problem with broken links or bad images on live websites, because it still works and it's not like there was a code problem. That's just one example of course, but if you want to change someone's behaviour, it's important that they actually understand why it's truly a problem.
I couldn't count the number of times I've had to tell someone they really screwed up. I know there were times it was as little as two words. After establishing the facts of the matter, I once just sighed and said "Not cool." That was all that employee needed to be told. I've also had very long and heated conversations that did not result in changed behaviour. These days I go for shorter over longer. And I don't do sandwiches.
Friday, August 14, 2009
What language do you think this
post by Jeff Atwood refers to?
There are over 220 billion lines of <language> in existence, a figure which
equates to around 80% of the world's actively used code. There are estimated
to be over a million <language> programmers in the world today. Most impressive
perhaps, is that 200 times as many <language> transactions take place each day than
Google searches - a figure which puts the influence of Web 2.0 into stark
Wow. 220 billion-with-a-b? B as in Business? As in Business-Oriented-Language? You know, the only thing I like about COBOL (and I have written precisely one COBOL program in the three decades I've been paid to program) is that it made it possible to have a language called SNOBOL.
The comments are full of folks who are maintaining 30 year old apps with a million lines of code, but the thing about billion-with-a-b is that you need 220,000 such folks to hit that number, and what's more as Larry O'Brien points out
20 years ago folks said there were 30 billion lines, and while I can agree that existing apps are being maintained, I don't think there are 7 times as many lines of COBOL out there now as there were at its peak.
But that's not my point. My points is that when you live at the leading edge, the bleeding edge, you forget a really important rule: edges are thin. The handful of us who are moving our apps to 4.0 now, who are complaining about an incompatibility between our Visual Studio 2010 beta and our Office 2010 beta, who are using a language invented this century, are dwarfed by folks who have been using the same tools and the same languages throughout their entire career. These people are invisible because they don't come to conferences, attend user group meetings, buy programming books, or read blogs. Heck, at one of my clients, the AS/400 guys sat off to the side and behind a little wall of cubicle partitions that was double the height of everyone else's. Really. They also never came to all-hands meetings and were exempt from the company-wide .NET training I delivered.
So do these "dark matter" developers matter to the "bleeding edge" developers? I think they do. For one thing, when you have your shiny and exciting idea to change everything about the way some software works, these guys can cancel your whole project with one or two sentences. For another, they are likely the only ones who understand the data format, the business rules as actually coded, and the special cases that come up every 15 to 20 years. Not to mention they can work the text editor. If you find yourself in a situation with some COBOL (or equivalent) developers in it, don't ever tell them you didn't think they existed any more. That's my tip to you.
Monday, July 27, 2009
If you want to start talking to developers about your technology, you're hardly the first. Whether you want to talk about the tech your company builds, or just tech that you like to use, or something a little in between (I don't make Microsoft software, or sell it, but since it's the platform I consult and mentor on, I have a financial interest in people using the tech I talk about) there is someone out there who is in the same boat as you. Chris Heilmann
, a web developer evangelist working for the Yahoo
Developer Network, has written a handbook
for developer evangelists. Trust me, what this handbook has to say is not Yahoo-specific, or web-specific, at all. It is developer-specific in parts, since demos and such are vital to us. Definitely worth a read - and if you want to speak on our tech, start doing some of this.
Saturday, July 25, 2009
A client asked me to help recently with a small mystery. They had a database provided by a customer and they'd been asked to import the contents into the tables used by their own product. One of the tables had a BLOB column and from context they were quite sure it was used to hold scans of documents. There was even a "filename" column and a "filetype" column that suggested very strongly the scans were stored as TIFFs.
It had taken a while to find code to read the blobs, and when they ran it, the resulting file was rejected as not being a valid TIFF. They weren't sure if they were handling the blobs wrongly, if the data was encrypted, or if it was some other image format (they had tried PDF and GIF already.) In a highly enjoyable two hours, here's what I did:
- Found short (ten lines including initialization and cleanup) code to read one blob in VB6 and save it to disk.
- Found the TIFF format details, looked in the resulting file with notepad and confirmed it didn't start either II or MM and so wasn't a TIFF.
- Looked at a few other file formats but wasn't really gaining any knowledge, just ruling things out that you could rule out by renaming and double clicking, then having the file rejected by the app that tried to open it.
- Discovered Marco Pontello's absolutely cool File Identifier, TrID, and downloaded it
- Removed the extension from what had been test.tif, pointed TrID at it, and was told 100% it was a zip file. Duh, the file started PK, I might have guessed that one.
- Renamed it to test.zip, unzipped it by hand -- ooh, it IS a zip! -- and was rewarded with file.txt for my trouble
- Looked at file.txt in notepad and noticed that it was full of binary-looking gibberish, but it DID start with II
- Hand renamed file.txt to file.tif and double-clicked it
- Presto! A scan of a document!
I left my client to write the code that did all the blobs, including unzipping them and renaming (every single blog contained a zip which contained a TIFF renamed to file.txt and no, I don't know why) from within a quickly written importer application. The big mystery was solved. Thanks, Marco!
Wednesday, July 01, 2009
So I guess I am totally having a "get off my lawn" moment here. I read, on a blog I generally enjoy reading, the following rant about "bad customer service":
- Why am I still required to fill out my personal details (city, birth date, job title) while registering on web sites, when all they need to do is fetch that data from my LinkedIn page?
- Why does my new Internet provider give me a new email address (which I won't use), requiring me to read that mailbox regularly for service updates? Why not send me tweets?
- Why do I have to go to the web site of my vendor of contact lenses to re-order my monthly set of lenses? Why not enable me to send a "reorder" message through Facebook?
- Why does the agile 2009 conference require that I upload my presentation to their site, in PDF form with maximum size of 5 MB? Why not integrate with the much more advanced SlideShare where I already have an account?
- Why do I get offers for products that I clearly don't want or that I already own, which can be easily deduced from my reviews, ratings, and rantings on various social sites?
Prior to this bulleted list was a complaint that an ISP hadn't magically noticed that some emails weren't reaching the ranter, and didn't email about it, or didn't go figure out what @tag to use in a Tweet so that their customer would know there was a problem with some emails. I mean really, "send me a tweet"? Tweets are broadcast messages, not one-on-one communication, aren't they?
Good heaven. If I went to a random web site and on the registration page entered "Kate Gregory" (or "Barack Obama") and it trundled off to LinkedIn and filled in where I live, what I do, my birthday etc I would be majorly creeped out and want nothing to do with that web site. Maybe, just maybe, I would be ok with a button that said "go find this out on the public web" but I doubt it. I think OpenID is a better way to go, and I do appreciate that most Microsoft sites now just let me use my Live ID, but for sites with no business relationship to share what they know about me just creeps me right out. Reorder contact lenses on Facebook? What does Facebook have to do with buying stuff from completely unrelated third parties? Why would it be a good thing to put intermediaries (Facebook, Twitter etc) in all my transactions? The big excitement of Web 1.0 was that it took intermediaries out of the picture and let me interact directly with the producers of the things I wanted to buy. One of the major inconveniences of Web 2.0 is excited under-30's (sorry to generalize, a handful of over-30's are excited like this too) making me sign up for yet another account on yet another Social Networking Silver Bullet that they are going to use to manage their event/project/party/virtual team.
I disagree with the fourth bullet, too. I would much rather just be told where to upload my stuff and be done with it. I also have some empathy for folks who want to use the same way to communicate with everyone on a reasonably large list. Can you imagine the job (probably unpaid in his or her free time) of the conference organizer who says "everybody please put your slides somewhere, anywhere on the web that works for you, and send me the link, and here are links to free places you can put your slides in case you're not on SlideShare." And this organizer probably still has to run the upload-your-slides here site for everyone who doesn't have an account somewhere else. And has to accept and send not just emails about it (with or without links) but also tweets, blog posts, and comments on one speaker's YouTube channel and another speaker's CodePlex project home page, because why should they be obliged to look in more than one place for attempts to communicate? And then this poor organizer needs to know how to download from 10 or 20 different document sharing sites, and register for notifications if they're changed, because the speaker figures uploading new docs and not telling anyone will be fine, since after all the site sends notifications if they're changed.
The last bullet is hilarious. Dude, I get offers for things that I clearly don't want. The spammers can't be bothered to check my gender or what country I live in. You really think they're going to check your MySpace to see you already tried acai berry and whether it worked for you or not?
But under all that rankling and disagreeing is the germ of a really important truth. Just as David Platt likes to say "Know your Customer, for he is not you", I can see that I might not offer enough options to the millennials, and they might not offer enough options to my and my fellow post-boomers. It's an interesting culture clash considering we write software for each other, and one that's worth thinking about. If a customer service department doesn't offer service the way you want it, if the conference speaker wrangler doesn't wrangle speakers the way they want to be wrangled, if my software doesn't let you talk back to me the way you want to talk back to me and if I don't listen when you talk the way you want to, then that's a problem. Hmmm.
Friday, June 19, 2009
If you already know what NDepend is, all you really need to know is that you can now point CppDepend at some big legacy C++ codebase and start to get your arms around all that code a bit better. If you have vaguely heard about NDepend but weren't really listening because you're a C++ programmer, it's time to change that. You can start by reading an analysis of MFC that uses CppDepend to answer questions like what fraction of member variables have names that start m_ (answer: about half) or what kind of coupling the key classes tend to live with.
Beatiful visualizations and genuine insight. Sure, you're not going to refactor MFC yourself, but imagine pointing all this at your own library!
Monday, June 01, 2009
We have all worked with star developers. When I come into a client to mentor, occasionally they have one developer who is just a star. I can pretty much spot them in the first half hour these days. Other times they have a developer who would say "I am a star" but who wouldn't get that designation from me. Tim Stall has a nice list of things that make a developer a star. As I went through the list I was thinking "yes! yes!" and finally "hire! hire!" which is also what happens when I meet real stars. (Don't worry, I have never poached a dev from a client and never would, but "would you hire this person" is still an incredibly useful summary of someone's skills.) I especially like "22. Knows when the rules do not apply". It can't be taught, and dear heaven can people get this one wrong. When you meet someone who gets this right, it is such a relief.
The list doesn't tell you how to become that sort of person, but I am quite sure the rest of the Internet has some hints. So will I if I meet you in a mentoring context.
Tuesday, March 17, 2009
Women in Leadership & Technology, a subgroup of IAMCP Canada held their first Canadian “Meet & Mingle” on March 9th. It was a networking opportunity for women in technology and leadership both inside and outside Microsoft. This was a nice opportunity to meet some new people for me and to talk about the issue that seems never to go away ... why do so few other women want to be in this business? Maxine Chung from itbusiness.ca was there too and has posted a slideshow (I am not in any of the pictures though) that includes a summary, plus a longer article. Check it out!
Wednesday, March 04, 2009
Here's an interesting post from Rick Segal. Even if you don't want VC money, it's an intruiging exercise to see how you look from that point of view. Let's see how gregcons does:
- Google "Gregory Consulting" and "gregcons". Our site, some sites of other Gregory Consultings in the world (note to self - if I want VC funding, create a sub with a weirdo name with extra vowels or not enough vowels), and some folks linking to blog postings of mine. Not a soul who's actually discussing us as a company. Fine by me but probably an issue if I wanted investors.
- Google "Kate Gregory" and "Brian Gregory". You can see who the public face of this company is - not one of the Brian hits is the right Brian, and all the Kate hits are me speaking, writing, and general experting. Interestingly Google (which I never use for my own searches but am using in the spirit of Rick's blog) doesn't find the "other" Kate Gregorys that Live tends to return. I'm not actually the only one on the planet.
- The mission statement. Um. Well, we have a tag line on the website "Leading your developers forward" so I'll give that a try. Interesting way to discover who is mirroring your old content chrome and all, but you don't learn much about us from it.
I think we pass the test of being discoverable on the internet, but it's clear people don't talk about us as a company much (they do talk about me from time to time). Fun exercise. Try it yourself!
Tuesday, March 03, 2009
I've been accumulating some links that might be relevant to folks looking for work. I got a lot of traffic to a post last year about trick questions in a job interview, so I thought I'd share these as well.
These posts are very different, but they all have useful information for you.
Monday, March 02, 2009
Programmers make mistakes, we all know that. But some are worse than others. Say you hardcode a file name, and you make a typo in the name. When you do your own testing before passing it off to others, you'll discover the typo because it keeps the application from working. But if you fix the typo, there's a good chance no-one will notice the other mistake - hardcoding the file name - for a very long time. In fact, if the file never moves, under some circumstances you could claim it isn't even a mistake to hardcode the name. But if the file does move, hardcoding the name is a much worse mistake because it causes a bug that a customer discovers - and that is always bad. Writing your data access code so it brings back the wrong records (say, forgetting to filter by date) will show up the minute you hit F5, but writing your data access code so it's vulnerable to SQL injection is far worse - you'll think the application works, but when you put it into production you'll have opened a large hole into your database for bad guys.
The SANS Institute has created a list of what they consider to be the 25 most important programming errors of all time. There's a lot not to like in this list, to be honest. First, it's not so much a list of errors (John typed this line of code in that application) as it is kinds or categories of errors. Second, a lot of them look like the same error over and over (trusting stuff that people give you as input, for example). Third, the post spends pages and pages on credits, acknowledgements, explaining why they are important, predicting how the world will be made better by this list existing, and so on before finally getting to the errors. Fourth, the names are flat-out weird in a lot of cases. But with those disclaimers in mind, I still think the post is worth reading and the errors are worth thinking about. Here are the 25:
- Improper Input Validation
- Improper Encoding or Escaping of Output
- Failure to Preserve SQL Query Structure (aka 'SQL Injection')
- Failure to Preserve Web Page Structure (aka 'Cross-site Scripting')
- Failure to Preserve OS Command Structure (aka 'OS Command Injection')
- Cleartext Transmission of Sensitive Information
- Cross-Site Request Forgery (CSRF)
- Race Condition
- Error Message Information Leak
- Failure to Constrain Operations within the Bounds of a Memory Buffer
- External Control of Critical State Data
- External Control of File Name or Path
- Untrusted Search Path
- Failure to Control Generation of Code (aka 'Code Injection')
- Download of Code Without Integrity Check
- Improper Resource Shutdown or Release
- Improper Initialization
- Incorrect Calculation
- Improper Access Control (Authorization)
- Use of a Broken or Risky Cryptographic Algorithm
- Hard-Coded Password
- Insecure Permission Assignment for Critical Resource
- Use of Insufficiently Random Values
- Execution with Unnecessary Privileges
- Client-Side Enforcement of Server-Side Security
The full details are in the linked post and it won't take more than a few minutes to read the description of each error. Pat yourself on the back, or go do a quick code review so you can say you don't do any of these.
Thursday, February 26, 2009
Michael Feathers put together a list of ten papers that "every programmer should read". I've seen such lists before, and this one is pretty good. I've read Parnas and Cunningham and draw on that background pretty regularly. I'd heard of some of the rest. But the real fun begins in the comments. People suggest additions (Fred Brooks - definitely! Joel Spolsky - why not?) and then other people start saying that reading, especially reading stuff from 20 years ago, just makes you an academic and not useful. Oh my.
I'm useful. I've written a lot of code that's made people's jobs and working lives a lot easier. I've written systems that have transformed companies and enabled them to survive business model changes they thought would sink them. I've rescued projects and made developers better than they were time and time again. And I'm academic. I have a Ph. D. for heavens sake, I teach at a university (no, not full time, one course a year), and when someone uses the word "academic" or "intellectual" as an insult, and I object, they tell me "you're not that kind of academic, not the kind I meant." Well honey, to paraphrase Gloria Steinem, this is what academic looks like. Reading 20 year old white papers and thinking about concepts and theory is one of the things that makes me useful. Folks who just want to get started and type some code and not bother with that high falutin design stuff tend to write bad code.
Grrr. Read the list, maybe read a few of the papers (as the commenters mention, Michael's links are to a site that will charge you to read them, but if you have the author and the title your favourite search engine will undoubtedly help you find free copies lying around on the web) and think a little about why it would be an insult to say that someone cares about history and theory.
Wednesday, February 25, 2009
Steve McConnell has a training company, Construx, that is not like other training companies, mostly because Steve is not like other developers. As it says on his web site:
Steve is the author of Software Estimation: Demystifying the Black Art (2006), Code Complete (1993, 2004), Rapid Development (1996), Software Project Survival Guide (1998), and Professional Software Development (2004). His first two books won Software Development magazine's Jolt Excellence award for best programming books of their years.
Steve has worked in the desktop software industry since 1984 and has expertise in rapid development methodologies, project estimation, software construction practices, and third-party contract management. In 1998, readers of Software Development magazine named Steve one of the three most influential people in the software industry along with Bill Gates and Linus Torvalds. Steve was Editor in Chief of IEEE Software magazine from 1998-2002.
There are very few authors who have multiple books on my bookshelf that I paid for. Steve is in rare company there. And the courses they offer? We're not talking "Introduction to Silverlight" or "A First Look At Sharepoint" here. This stuff is more university-like: concepts, theory, the big picture. Some upcoming titles:
- Object-Oriented Requirements Analysis and Design Using the UML
- Professional Tester Boot Camp
- Enterprise Agile: Planning, Managing and Scaling Agile Projects Using Scrum
- Requirements Boot Camp
- Software Estimation in Depth
These are the kinds of courses that change the kind of developer you are, not just teach some new syntax or tool. And they cost thousands of dollars. But Steve has decided that fully one quarter of the seats in each class will now be available for free to people who have been laid off. If you can get to Bellevue WA, you should arrange to take one of these courses. No question about it.
Tuesday, February 17, 2009
I have a favourite piece of advice, and I give it even though it frustrates many recipients. If you want to write, write! If you want to get into public speaking, speak in public! If you want to start a user group, start a user group! If you want to be an MVP, do what MVPs do (advise others and solve problems and volunteer for stuff) and you'll start to get the benefit even before you get the award. I'm not quite saying Just Do It but the fact is the barriers to entry are very very small these days and possibly non existent. Technical writing especially - start a blog or get active on newsgroups and presto, you're writing! Listen to feedback (people telling you you're wrong is bad, people thanking you for your answer or quoting you elsewhere is good) and you will get better. Public speaking isn't much harder to crack because the world is full of user group leaders and similar folks who need someone to speak to them month after month. It's also full of Code Camps and other places to get started (they tend to come with coaching and encouragement too.)
Still some people don't like this advice. They feel held back from what they want to do, and they don't like to be told "nothing is holding you back, you can start whenever you want." Alternatively, they don't want to speak or write or lead for free, they want to be paid for it, and they don't like the idea of starting for free and working hard for years to get that overnight success. So here's a rephrasing that maybe you'll prefer: "80% of success is just showing up." It's attributed to Woody Allen, not a guy I would normally take advice from, but it sure is accurate. Go to the meeting, open the document you're supposed to be writing, be there when someone asks for volunteers, go to the whiteboard and draw as much as you know, put your shoes on and go outside, ... not all at once of course, but these are the "just showing up" tasks that get you on the road to success. Try it.
Sunday, February 15, 2009
Well perhaps not all the way to Considered Harmful but Allen Holub is willing to call them Evil. I came across this article because I'm teaching OO Analysis and Design again this year and my students have generally already heard that the way you do encapsulation is you make all your attributes private and then add a public get and set method for every attribute. What's more, they generally feel if you change the type of the attribute then you need to change the return type of the get and the parameter type of the set. This of course gets you pretty much nowhere, and this is what Allen is railing against.
Now I am OK with Get methods as long as you swear you will never change the return type. The example I give the students is a bank account class with a balance. In the original design you keep the balance as a floating point number, 12.34000000 for 12 dollars and 34 cents. You add a GetBalance() method that returns a float, and Deposit() and Withdraw() methods that take (among other things) floats to represent the amount being deposited or withdrawn. Now when implementation time rolls along you discover that floating point arithmetic is expensive computationally, and needs lots of rounding to stay accurate: add 1.00 to 1.00, then add another 1.00 and the time may come when your number ends .01 or .99 ... neither of which banks care for tremendously. So you decide to store the balance as an integer number of pennies. Everything is OK in my book as long as you DO NOT CHANGE the signature of GetBalance(), nor of Deposit and Withdraw. These methods don't need to know what you just did. When Deposit tells you the amount is 50.00 dollars, your code can multiply by 100 to get 5,000 pennies, and add that to the balance. GetBalance() can divide by 100 (and round) to change pennies to dollars. That's a good use of a Getter method.
I am less OK with Set methods. I sure don't want a SetBalance() method. Deposit(), Withdraw(), and their cousins will change the balance. But there's no business rule in which it becomes necessary to announce that account 123456 now has $183.27 in it, and set the balance to that number. Having the method just encourages some code outside the class to do things that belong in the class - calculating service charges, or giving interest perhaps. Locking up access to the value means that if your business rules change, you don't need to look outside the bank account class for code that implements those business rules.
So do I think Get and Set methods are Evil? No, but I do think they should not be your first reflex, one of each per attribute. Make them earn their place.
Wednesday, January 21, 2009
Continuing my theme of 2008 in review, the year was interesting because it featured the breaking of two rules I have long held to be utterly true. These rules are cynical and depressing and people generally do not want to believe them. I am known for my optimism and yet I assure you these rules are true and you cannot escape them:
- There is no such thing as a “slow yes”.
- You will never get paying work (or a sale) from that guy you sat next to on the airplane.
Let’s start with the mythical “slow yes.” All there really is in this world is the “fast yes”, the “fast no”, and the “slow no”. I am sure you have been asked to give somebody a donation, or to buy something, that you didn’t really want to give or buy, and so you said “can you send me a letter about that?” or “can you send me a proposal?” when what you really meant was “can I please get off the phone so I don’t have to face saying no to you?” It’s a “slow no.” We have all done this. Yet for some reason when we are trying to get the sales (or the donations, or to be hired) we get off the phone and tell our co-workers or family or whatever, “Success! He wants me to send a proposal!” or “Score! They’ve got nothing now, but he wants me to phone back in a month!”
I have been a consultant for over 20 years. When people want to hire our firm to help with a problem they’re experiencing, they hire us. Sometimes there’s an RFP to respond to, sometimes they need to show a written proposal to someone, but generally they say “I want you to do this” and then we talk about paperwork. When people don’t particularly want to hire us (and usually that’s because the conversation was my idea, and I am trying to sell work to people who were minding their own business) they ask for proposals, or they say “well, we would have to have a meeting about that but I’m really busy this week so how about I call you in two or three weeks?” This is the start of the “slow no”. They won’t ever say “no” or “go away” but they won’t ever give you work either. You can spend days and weeks and months thinking you are “working on sales” because you are emailing these people and asking if there’s been any change, you’re sending these people generic proposals (because you don’t know their specific problem, and that in turn is because they haven’t told you a problem they want you to solve, and you know why that is? They don’t have a problem they want you to solve), and you’re updating your tickle lists, all of which sure as hell feels like work, but is not in fact accomplishing anything.
So when I finally learned this lesson (and I believe I read it somewhere, and fought it for a while, and then came to know it was true) my life got simpler. I rarely phone or email strangers (or even former clients) and try to pester them into giving me work. If for some reason I do, and they’re not very interested in hiring us, I don’t put a lot of time and effort into trying to persuade them otherwise. I assume that people who want to hire us will make the effort to do so. This has lowered my stress tremendously.
But you know what they say about the exception that proves the rule? We got an RFP from some people we didn’t know, through a third party who felt we’d be good for it. It was highly specific about what technology to use – an Access application distributed as a single file to be installed on each workstation, a SQL backend to be shared by all these workstations, no offline story, a VB6 application to run in the system tray and notify you if another user added something to the shared repository you should know about, that sort of thing – and our first guess of effort doing it their way was well over (perhaps even double) what the third party believed was their budget. So we wrote back and declined to bid. Months later, we heard they were putting it out again. So we asked if it was ok to ignore all their tech specs and submit a solution to the underlying business problem, which was well described in their material. They said go ahead, so we did: suggesting a SharePoint store, some workflow to handle their special business rules, and some Reporting Services goodness for the managers. Total cost including buying all the SharePoint licenses at full retail was less than the whispered budget, and we were pulling in a raft of features that they had on their wishlist for v2 such as email notifications when things were changed. It was a great proposal.
Great or not, it got no response. After about 2 or 3 months I wrote to confirm that we didn’t get it. And was told “actually, we haven’t decided yet.” I imagined a conversation in a boardroom somewhere with one person saying “can she not read? We clearly said SYSTEM TRAY!” and another saying “look how much more solution to our problems we will get for the money!” Some more months went by and you know what? We got the gig. Well over a year from the first RFP to being hired for the project. It’s underway now. I will point out that although this was a slow yes, it didn’t get to yes as a result of pestering actions on my part. I patiently waited (while working on other stuff for real clients) and these guys came to me when their process had worked its way through to a decision.
The second rule that sales people need to learn is that those “hey cool your product sounds perfect for us why don’t you drop me an email” conversations on the plane just do not, in general, lead to sales. Again, the guy just wants to be nice and to go away in a pleasant and positive way. Pestering Mr 13B to see if he’s ready to pull the trigger on the order that will save your year may feel like work, but it isn’t getting you anywhere. If Mr 13B wanted your product, he would have taken your card, and he would have emailed you the minute he got his laptop on the network. That silence and absence of emails from Mr 13B is basically “he’s just not that into you” or in this case, your product.
That said, here’s the story that breaks the rule. Sasha, my MVP lead, spent some time last year in a customs lineup, and got chatting with the fellow next to him in line. That fellow needed some mentoring or consulting from a senior person with solid C++ and project management skills who could suggest a good architecture for his new product, and then help to get it built. Sasha took the guy’s card and sent me one of those “X, meet Y” emails. A conversation ensued, followed by meetings, and the end result: the product is very clever and I am delighted to be part of the team that is building it. We ended up with no C++ in the product, but that doesn’t worry me at all. It meets a genuine business need and supports the way people in that business need to do their jobs. And my client would not have found me if he wasn’t willing to chat to a complete stranger about the software he was trying to build.
I still say the rules are true, despite the specific exceptions I met this year. Or more accurately, that the smart way to live your life is as though these rules are true. Selling consulting services is not like selling timeshares or couches. You can’t bully people into it or catch them in a moment of weakness and trick them into saying yes. They have to want to choose you to solve their problems. That isn’t something you can persuade them to want by “following up” every two weeks. So I just plain do not do that. Some folks who I like and haven’t worked with for a while get a note sometimes (especially if I come across something that reminds me of them) but I don’t set out to make people buy our services. I don’t lose sales by spending less time “working on sales” and I certainly don’t lose sleep. If anything it frees my time to talk to people who genuinely want our help. That’s way more fun anyway.
Saturday, November 29, 2008
Whenever I go to a conference I run into people who make software so differently than I make it. I also run into people who do the same things I'm doing, but they have a name for it and I don't. Someone asked me recently if I "did Agile." I always answer that we're not "formally Agile" which frankly I find very funny. We do have a client though, for whom we ship a new release every month. They ask for things (typically with emails) we design and estimate, together we draw up a list of what will be in the next phase and when it will release, and then we mostly do that. I say mostly because sometimes over the month they change their minds, or their customers impose a business change on them, and we tweak the list a little, but just about every month they get a refresh and their software has evolved to meet their new needs.
So there are plenty of people who will tell me, since I ship every month, I'm Agile. I guess so. But we don't do scrum. We don't do burn lists. We don't do pair programming. We don't have a daily anything. We manage all this with TFS and with a Word document called "phase 13 as approved.doc" that has a table in it listing work items, their descriptions, and their status. We don't really use any of the deliverables or artifacts that are considered Agile today.
So, with that mindset (what makes you Agile) I have two links for you.
First, http://martinfowler.com/articles/newMethodology.html. This is Martin Fowler on agility, the essay he first wrote in 2000. It talks about how requirements change, how people are not all the same, how customers adapt, and so on. To my great surprise it lists the Rational Unified Process as an Agile technique. His conclusion is a damn good one:
So where should you not use an agile method? I think it primarily comes down the people. If the people involved aren't interested in the kind of intense collaboration that agile working requires, then it's going to be a big struggle to get them to work with it. In particular I think that this means you should never try to impose agile working on a team that doesn't want to try it.
Second, http://www.agilemanagement.net/Articles/Papers/CMMIandAgileWhynotembrace.html. Unfortunately the paper is only available as a PDF, but this page has a link to it. The abstract:
Agile development methods and CMMI (Capability Maturity Model® Integration) best practices are often perceived to be at odds with each other. This report clarifies why the discord need not exist and proposes that CMMI and Agile champions work toward deriving benefit from using both and exploit synergies that have the potential to dramatically improve business performance.
OK, so it isn't written in a conversational style, but you know, it makes some really good points. I've just started a project in which we're using the CMMI templates for TFS, just to see what it's like, and we're being our usual "get the detailed requirements and do the design at the last responsible moment" on it (we have sensible phases which makes this possible) and you know what? It's working pretty well.
So, you think you know your methodologies, but I recommend you read both of these papers and then see how you feel. You may be surprised. You may be pleased (I was.) And you may start working more effectively.
Friday, November 21, 2008
One very powerful question to ask yourself, if you run a business of any kind, is "what business are you in?" Another way to ask it is "what needs do I meet?". It's easy to say "I'm in the software business" or "I'm in the consulting business" but more people are saying "I hate the way we <something in their business>" than are saying "I wish I had new software" or "I wish I had a consultant."
This Harvard Business School article even says people don't really buy drills, or that isn't the need they are meeting when they go buy a drill - they buy holes. They want holes, and they buy a drill as a way of getting them. The only way you can sell them your drill is to relate it to holes. Being lightweight, for example, doesn't matter to someone who only plans to make a few holes at a time. But it's really important to someone who is going to make a lot of holes and has to slow down the pace because their arm aches from holding the heavy drill. Being cordless only matters if you can think to say "make holes anywhere!" to the purchaser. And so on. The rest of the article helps you try to understand what needs your product or service meets, and therefore how to adjust it or sell it so that you sell more of it.
I've said for years that we're in the problem solving business. We solve people's problems. We're more likely to use software to solve them than to come over to a client's house and build a shed in the backyard or mow the lawn - but we're not so much in the software business as in the problem solving business. If I write great software that doesn't help the problem, I've failed. Often our advice on process is as valuable as the software we write encapsulating that process. And of course when we're mentoring and advising other developers, we need deep technical chops but we need to remember that the mentee or advisee has a problem (our UI looks stale, we have to exchange information with a new business partner and don't know how, our application blows up under certain circumstances and we don't know why) and we are there to get that problem fixed.
As the economy worsens you are more likely to stay in business if you are sure what business you are in. It isn't obvious.
Wednesday, November 12, 2008
Check this out. If you go to DevTeach - and you certainly should - you will be getting more than you bargained for. First and foremost you'll be getting great sessions by great speakers. 136 sessions to be precise, plus a keynote by Ted Neward. Because of the small scale (8 simultaneous tracks instead of dozens) you will get a chance to meet and talk to many speakers and your fellow attendees during breaks and meals.
Now I happen to think that is well worth the $1250 attendance fee plus your travel and hotel. You would pay double to go to Tech Ed. Montreal the first week of December is a delightful trip, and you will learn the things you need to learn to stay current in this world, and get face time with a dazzling array of people who are not usually this accessible.
But, in case that's not enough, they've negotiated their way to giving you about a thousand dollars worth of software and learning. Seriously. I quote:
We believe that all developers need the right tool to be productive. This is what we will give you, free software, when you register to DevTeach or SQLTeach. Yes that right! We’re pleased to announce that we’re giving over a 1000$ of software when you register to DevTeach. You will find in your conference bag a version of Visual Studio 2008 Professional, ExpressionTM Web 2 and the Tech-Ed Conference DVD Set. Is this a good deal or what?
It's a very good deal. Oh, and one other thing. Did you go to TechDays? Did you get a $100 coupon? They've decided to retroactively make that a $350 dollar coupon. So you can attend for just $900.
Wednesday, November 05, 2008
Microsoft has announced BizSpark. If you know what DreamSpark is, then you might guess what BizSpark is. I was really surprised myself - essentially unlimited free licenses of developer software and hosting software such as Windows, SQL Server and SharePoint. Yes, free Team Suite for everyone in the company! You must meet three criteria:
- Be a startup, less than 3 years in business
- Have not much revenue, less than a million a year (stricter in some markets, mostly in Asia)
- Be software developers, not consultants or resellers
You prove that you meet these criteria, not to Microsoft, but to a network partner. Ideally your network partner is more than just your gateway to free software, but someone who can advise and help you on the path to success. Since the network partner has to know a bit about you, not many will just email you a key if you email them. You can look through the partners on the BizSpark site and see who would be a good match for you to establish a relationship with. Be sure to get the user guide and read the FAQ as well.
Plenty of coverage of this elsewhere on the web:
So, if you fit the description and want the free software, what should you do? Go to the BizSpark site's Find a Network Partner page. A lot of them are venture capitalists and investment companies. If you were hoping to find such a firm, this is a cool way to know one that is in favour of your using the Microsoft platform and won't try to make you change development tools to get funded. If you weren't planning to work with an investor, scroll through looking for a firm that offers consulting and mentoring. You can send an email and see about working together. If you can't find a firm in your geography that looks as if it could help you, try a nearby geography. For example, I'm only listed under Canada, but Americans could engage with our firm too.
Sunday, December 23, 2007
You know something is mainstream when it starts to get named. I've been talking about concurrency matters for over two years now. And now it seems almost every day somebody comes out with something you just have to read or watch on this matter. An attendee at Tech Ed Developers in Barcelona asked me "isn't it confusing and wrong that people are doing such different things in this space?" I don't think it is. Some folks are trying things with libraries, with compiler directives, with new language keywords, with whole new languages, with frameworks, with the operating system, with the hardware, ... with everything you can think of. And I don't know which things will work out and how the various things will work with each other. None of us do! But it sure is fun to watch it happen, and it's probably the only way to do it.
So, some links for you, accumulated over the fall:
Herb's advice is good. He says "Expect at least dozens of major product announcements and releases across the industry, before the toolset expansion phase is fully underway and approaching some maturity. We the industry have undertaken to bring concurrency to the mainstream, and as with OO and GUIs it will take multiple years, and multiple major releases, across the industry on all platforms." Bring it on!
Tuesday, December 11, 2007
At Tech Ed Developers Europe, one of my talks was on STL/CLR and the marshaling library. There are three super cool things about the marshaling library that all C++ developers need to know. The first is that the random boilerplate code we used to write to convert between two kinds of strings is now taken care of for us:
char* stringfromnativelibrary; //gets set somehow
The second is that it's just templates, meaning it is fast at runtime and intuitive for a C++ developer. The third is that because it's templates, we can write our own specializations, and convert between any two types we feel we will be using - typically on either side of the managed/native border, though that's not a requirement at all.
This last part is really exciting to me. Imagine you have some library you wrote ages ago that takes a RECT and does something with it related to your business logic. But you've replaced your UI and now you have a System::Drawing::Rectangle to represent what your user selected. Wouldn't it be cool to write:
oldfunction( marshal_as<RECT> RectangleFromWinForms);
That's not a problem as long as someone has written that specialization. You can do it, or you can try to find one someone else already wrote.
Date and time, arrays, anything related to screen position, these are going to be types everyone uses. Why not share the effort of writing these conversion functions? That's the thought that hit me at the end of my talk. So I came home and set up a site - www.marshal-as.net - to use for just this purpose. I've had a few submissions from Jason, who was at my talk and was there when I thought of it, and a wish list from a "little birdie". The C++ team knows what I'm up to and they are excited too. Now what I need is submissions and lots of them!
So, drop me an email, comment on this post, or (better) comment on the first post over at www.marshal-as.net. I'll post the specializations one per post and we'll build a library. I'm inspired by pinvoke.net and would like to see this as the destination for finding a specialization instead of writing one. Can you help?
Friday, August 03, 2007
Andrew Clifford has a slightly controversial blog post in which he makes this claim: real programmers don't test. Well, on further investigation, what he really says is that really good and experienced programmers don't have a separate testing step at the end. And even in that diluted form, I'm not sure I agree. My developers think of tests before they code, and they test as they go, but on large development projects (and some small tasks for that matter) I still have a tester take a run through the system to make sure there is nothing that we would cringe if the client were to find .
The Braidy Tester has a way of thinking that may scare you a bit and a huge list of tests that you need to run at the end in his "you are not done yet" lists for testers and developers. The first item on the developer list is the most important to me -- when you find a bug, ask yourself why it didn't turn up earlier. Why did we wait until we were 90% complete to test with their old data? Why did nobody print this before? Why has it been three months since anybody tried adding a customer record before using this screen? "Why" questions tend to hurt a bit, but they prevent pain in the future. And folks who test as they go, who test in their minds before they design or code, can fly through a "you are not done yet" list and say "yes I am!"
Saturday, July 21, 2007
I should have pointed this out before, but I wasn't blogging at the start of the month. Herb Sutter has a new column at DDJ on, of course, concurrency. In his first outing, he talks about all the different words and concepts that show up in a concurrency conversation, and presents an organization of those concepts that can give you a framework for deciding what you're going to do about the future.
Words like blocking, coupling, background, asynchronous, responsive, isolated, scalability, threads, locks, race, mutable shared objects, transactions, and so on are actually applicable to different parts of the concurrency space. If you try to think about all of it at once, it's too hard. And make no mistake, concurrency is hard today. Anything that makes it easier is welcome, and in this case it's rearranging your head a bit.
Friday, June 22, 2007
There is a lot of confusion about writing your own exception classes. I see far too much code out there that just catches "Exception" anyway, that I hate to complain about someone who has set themselves up to have different catch behaviour for "The server is probably offline" than for "you probably don't have permissions on that file you just told me to use". However those who write their own exceptions have generally derived them from ApplicationException. If you ask why, they say things like "well" and "er" and "um" a lot because there's no extra stuff in an ApplicationException compared to an Exception. It just made it possible for you to catch "ApplicationException" and know it would be one of yours and not from some framework code.
Only thing is, that didn't really work out -- some framework code throws exceptions that derive from ApplicationException. And really, catching ApplicationException is just as generic as catching Exception. What can you meaningfully decide to do when all you know is "some code I wrote is unhappy in a way that the built-in exceptions (invalid argument, access denied and so on) cannot properly express" ?
So the word is out. Don't inherit from ApplicationException. Got it.
Wednesday, June 20, 2007
Recently we took a large SharePoint project live at a company that is acquiring others quite fast, and having trouble keeping its Active Directory situation up to date as new domains are assimilated. When the project first went live, everyone had to authenticate to the server when they first browsed to it, and in some cases a second or even third time, depending on what kinds of files they opened, whether they followed links to other internal servers, and so on. As you might imagine there were plenty of complaints from folks who didn't like having to authenticate all the time.
We as the developers couldn't do a lot about this, but we worked hard with their IT folks and did a few clever things of our own until we achieved single sign on glory. Workers throughout this global firm would sign in to their own Windows desktops, and from then on everything in their whole intranet was theirs with no more authentication needed. Of course it was all strictly controlled - only HR people could see the HR files, only Finance people could see the Finance files, and so on. But it was perhaps a little too transparent. After we achieved this lovely state people stopped emailing to complain about authenticating, only to be supplanted by a new chorus of complaints from people we hadn't heard from before. The most poignant read simply "Everyone can see all my files!" and was accompanied by a screen shot of a browser opened to the HR area. Our correspondent hadn't been challenged for a password and was therefore sure all these files were completely unsecured. It took an in-person visit that included "why don't we go over to Bob's desk so you can see what the portal looks like for him?" to finally convince this user that invisible security is still security.
For all I know, there are scores or even hundreds of people in that firm who don't realize their sensitive information is protected. Typing in a password annoys many users, but it soothes others.
Tuesday, June 19, 2007
I got a real aha moment when I saw this graph:
The blog post where I saw it was talking about "management by ..." but I think it also applies to the motivation that individuals are moved by. That is, relative newbies to a job tend to do things a certain way because those are the rules. As they progress over time, most of them move on to "this is the method I use" and then to "my team's objectives are" and finally "this is what my team values." I think this is a hugely important progression to understand.
Let's take one little thing, say source control behaviour - do you check in too often, not often enough, are your comments any good, are your changesets too big or too little, and so on. If I want to direct your source control behaviour I need to know what zone you are in.
- If you're in the "rules" zone, I must tell you the rules for source control. I need to write a long document with lots of examples and if there are exceptions, or different rules for different projects, I need to elaborate them all. Whenever you do something "wrong" I will probably hear that you were just following the rules, and I will need to update the rules to attempt to prevent that problem in the future.
- If you're in the "methods" zone, I must cover source control in the documentation of my methodology, put it into context, show you why we use it and how things you type at step 17 will be used by someone else at step 35. The rules don't need to be so black and white or so detailed, but there may need to be different methodologies for different kinds of projects or circumstances. If I correct you I am still likely to hear that it's because the methodology is flawed.
- If you're in the "objectives" zone, I need only remind you that we need to be able to pick up projects again for a version 2 long after we shipped version 1, or that we need to be able to recover from two people editing a file at once, or that we need to be able to explain to clients which files are different in version 2.3.4 than they were in 2.3.3. The detailed rules can go; you will choose your changeset size and your comments knowing which of our objectives you are supporting when you do so. If you make an incorrect decision and I point it out to you, your response is most likely to be "oh" and then you will adjust your own internal set of rules and methodologies accordingly.
- If you're in the "values" zone, it's even simpler - we value making money on each project, and serving our clients well, and you know that, and you have the capability to make the right decisions in order to support those values. I barely have to manage you, just provide you from time to time with information.
In contrast to the blog where I found this graph, I don't see it as just being a matter of how managers choose to manage their projects and people. I see that some people cannot be motivated by values alone, or objectives alone. Either they lack the career maturity to recognize that supporting the team's objectives is always in their own self-interest, or they lack the skill and knowledge to choose correctly (should I check in now? or wait till I have tested? or wait till I do those other changes?) knowing only what outcomes are important to the team.
I personally don't care for the rules-oriented phase. Writing out exhaustive "if this happens do that" documents is not really fun work. Hearing that a flaw in the document is why something went wrong also doesn't really work for me. Yet it seems all team members (and by this I mean not just my own staff, but my clients and their staff, other vendors, and so on) need to go through this phase when adapting to a new process. Well, knowing it's going on makes it easier for me to cope with it.
Monday, June 18, 2007
Here is a neat thing i actually learned about from people complaining about Vista performance. I haven't been having performance problems to speak of (except for that darned copying thing) but I was intrigued to hear about a background process that keeps track of how stable your system is. The Reliability and Performance Monitor is tucked away under a zillion menu options (this blog post leads you there) but I just click the marble and type reli and there it is:
The first thing you get is a performance monitor-type view, to do with as you will:
But if you click reliability monitor, you get something really quite new:
Here you see things the system feels were instabilities in my system in late May and early June. Mind you, it has a very persnickety bar when it comes to those red Xs.
On June 1st, Visual Studio blew up on me. I bet I know what that was, too -- from time to time it blows up when I drop down a list of methods in those bars across the top of the code editor, especially if I try to scroll in the dropdown -- and not only was that recorded, but it contributed to a lower "stability index" for the day. As you can see, the system also records everything I installed (including updates through Windows Update) and everything that failed. It's a pretty neat way to remind yourself what you've been going through. You can also validate wild claims like "Project blows up at least once a week" by scrolling back and counting them. Ah, evidence
Sunday, June 17, 2007
I was helping a mentoring client translate some sample code from VB to C# - he has written a lovely library and a customer wanted to see C# code that called it. The original samples had been written by someone who wasn't in the room, so I could have a bit of a vent. They had made heavy use of the Microsoft.VisualBasic namespace (nothing wrong with that) so as to access familiar (to a VB6 programmer) string manipulation methods. The problem was, these methods were being used to do things like finding the extension given a file name, or extracting a file name from a long path. This work should never be done with Left, Right, and Mid - and using Substring doesn't make it better. There are all kinds of methods in System.IO that manipulate paths and file names in a more robust and localized way than you can possibly do by hand. For my client's code, I ripped out a whole pile of hand written code (including a loop that looked character by character at a string testing to see if each was '\' or not) and replaced it with calls to library methods.
Phil Haack lists a bunch of these (and his commenters even more) in a very useful post. Developers who know what's in System.IO and the other meat-and-potatoes parts of the .NET Framework will write code more quickly, and that code will be better. Never assume you're the first person who wanted to parse a file path, check if a string is a good date, or any of a thousand other general tasks. Trust me, what you want is in there ... look for it.
Wednesday, June 13, 2007
I like to let Hugh MacLeod's gapingvoid cartoons rattle around in my brain for a while before I decide if I like them or not. It's a fine line between pithy and banal, after all. This one is working for me:
Keeps my focus where it belongs, even when making custom software or mentoring the folks who are making the software. Forest and trees, don'tcha know.
Thursday, May 31, 2007
It's time to get serious about planning my Tech Ed time next week. So far I have these immovable rocks, some of which I hope will be a don't-miss for you too:
I will be spending time at the RD Booth too so if you miss me at one of my sessions, look for me there! I'm hoping to have a fantastic week meeting developers and talking about Vista, C++, and interop in my real world and in yours. I'm also hoping to stay INDOORS as much as I can. Here at home it's in the high 20s even low 30s (Celsius, in other words HOT) but the humidity is nice and low. I know that's not what I'll find once I get to Orlando.
Saturday, March 17, 2007
It's a strange thing about debugging under Vista that the one thing you really don't want to do is press F5. It's rather a long story as to why, but it's a good habit to go and find your executable and double-click it. And if you develop that habit, you may find that getting Visual Studio to build you a release or a debug version is not that simple. (Pressing F5 builds a debug version, and Ctrl-F5 builds a release version, before launching the application.) For many people, the dropdown that shows what configuration you're building has disappeared from the toolbar where it belongs. And even if you're brave enough to wade into the Customize dialog and put it back, it's disabled:
To get things back the way they once were, bring up Tools, Options, and go to the General section under Projects and Solutions. Find "Show advanced build configurations" and check it.
Presto! Debug is back!
Not what I'd call discoverable, so spread the word.
Sunday, February 25, 2007
One of the things that C++ can do that C# can't is MSIL linking from the IDE. Normally when you have a solution with two projects, a build creates two assemblies (one .exe and one .dll) for you to deploy. Sometimes you want to deploy only a single file, but you want two projects. Sometimes you want the advantages of static linking while you're creating MSIL and deploying onto the CLR. So how do you do it?
I created a tiny little solution with two projects, both in C++. One is a console application and the other is a library. I set the library to compile as /clr:safe and the console app as just plain /clr. In the console app I added a reference to the library.
At this point if I build and run I will have HelloWorld.exe and Library.dll.
Now I went to the Library project settings and made a few changes. First, on the Advanced tab of Linker options, I turned off assembly generation:
This gets the linker to make an assembly fragment called a .netmodule rather than an assembly. Next I changed my output file name:
Then I deleted the reference in the console application, and re-added it but this time to Library.netmodule instead of Library.dll. One more thing, the linker inputs in the console application need to include the .netmodule:
At this point I can build the solution, and delete Library.netmodule, Library.dll and the like and HelloWorld.exe will run just fine. I don't need to deploy Library because it's actually inside HelloWorld.exe - that's MSIL linking.
I have a mentoring client who is using this right now. They have an MFC application with a mix of native and managed code and it can't be compiled /clr:pure. They want to add some WinForms controls to that application, and the designer can only work with verifiable assemblies. So now one project is the user controls, and it's /clr:safe, and the the main exe is a mixed assembly. Yet they only deploy a single file in the end.
Tuesday, February 13, 2007
Here's another C++ video on Channel 9. And this one is about strategy and vision:
How will VC++ evolve? How has the advent of managed code affected the evolutionary trajectory of VC++? What's the VC++ team up to these days, anyway? How much time are they spending innovating C++, the native language?
Tune in and learn first hand from two people who know the answers to the above questions (and much more); Steve Teixeira, Group Program Manager, and Bill Dunlap, Program Manager.
If you want to know where Visual C++ is heading, then you definitely want to watch this interview. If you are a C++ developer, the message should be very loud and clear: Microsoft has not forgotten about you!
These guys know you don't want to throw your old code out and it isn't broken. You want to keep working with it. You want to extend it to pick up new shiny good stuff, but you don't want "step 1: port the whole thing to C#." They also know you love the language and you want Microsoft to love it and love you. And they realize that C++ doesn't need to be all things to all people, because most folks who have mastered C++ can pick up the C# or VB they need when necessary. So if you accept those two premises - that native code is super important, and that not every single UI wizard needs to support C++ - where do you think that leads? Watch and find out.
Saturday, January 20, 2007
I once had an opportunity to write one of those Teach Yourself <Something complicated> in 21 Days books, or it might have been 24 Hours, or A Weekend, I forget. I was overloaded with work at the time and didn't write it. One of the things about writing those books is that nobody actually expects the reader to learn what they need in 21 days or 24 hours or whatever. It's basically the number of chapters. And if you processed one chapter a day, I guess you would cover the book in three weeks, but you wouldn't be a <Something complicated> programmer at the end of that, would you? Some folks might do 5 chapters a day, others might do a chapter a week. It depends on where you're starting from.
I came across a few interesting blog posts on this topic. Peter Norvig found hundreds of such books on programming languages or frameworks, and proposes instead Teach Yourself Programming in Ten Years. He has a point. Jasmine refines the point a bit, saying that if you're already a good developer you probably can pick up a new language or framework in a matter of days, and that if you don't have what it takes to be a good developer, ten years of plugging away at it won't make you good enough.
I've been getting paid to program since 1979, and I learn new things all the time. But I try to learn new languages no more than once a year -- and I wouldn't be able to invest 21 days in learning a language, either. More importantly, I've invested quite a lot of time and effort into spotting those who will be good developers some day, and trying to speed the process of making them better. I think the emphasis on debugging and on reading or fixing the code of others is appropriate. It's tempting to have the newbies work on little projects alone since they can't understand your big complicated project with difficult code written by the really smart people. But trying to understand that project and that code is what will make that newbie a developer -- or show you both that it's a hopeless cause .
Sunday, December 10, 2006
The title isn't mine, it's Charles Petzold's, and I would be quite surprised if you didn't learn things about C++/CLI just by learning things about the .NET Framework. In other words, you don't need to plan to switch to C# to get some benefit of this free e-book. It was originally supposed to be a chapter, but ended up over 250 pages long.
I know people still need this material. I have a new mentoring client with an established team of C++ developers who are just looking at moving to the .NET Framework. I came and did a "what is .NET" talk for them, with diagrams like this:
If you already recognize these pictures and realize what they are supposed to illustrate, then you don't need the e-book. But if you haven't really paid much attention to the .NET Framework, then this is a fairly painless way to learn a lot of it. The thing is, it's all C#. My suggestion to you is to bear with that -- a C++ programmer can read C# without too much difficulty -- and then come on back here to see how to do the same things using idioms you already know and love, and how to drop back into native code any time you like for various reasons include control over your application's performance.
Tuesday, December 05, 2006
Here's another neat way to search in Visual Studio. Press Ctrl-i to get into incremental search mode, and start typing:
Typing e finds the first e in the file. Keep going and find the next instance of your letter pair:
It keeps going as long as you want:
By the way the binoculars/arrows cursor reminds you what you're doing. Until you press Escape, you can also do Ctrl-i again to just go to the next one, Shift-Ctrl-i to go backwards, and Backspace to take a letter off your search string.
Fun, eh? I may like search in Visual Studio too much ... I routinely use the Find in Files to search folders of stuff that isn't anywhere close to code. Of course I don't have to do that on my Vista machines, where search is nice and fast.
Monday, December 04, 2006
My recent post of a joke about a priest and a politician highlights a privacy issue: sometimes any sufficiently specific information can become identifying information. If the priest had referred to "one of the first confessions" instead of "my very first confession" nobody would have learned anything when the late-arriving politician told the crowd he was the very first to give confession to the then-new priest. Similarly when a CIA operative was identified in the USA, at one point the person who identified her took refuge in pointing out he hadn't named her, hadn't said "X Y is an operative", but instead had named her husband, "A B is married to an operative." Of course that was equivalent to naming her.
Similarly, when you're worrying about privacy in an application, it's not as simple as naming some fields you shouldn't include in the system. That's a good first step, for sure: why does this application have a field for Social Insurance Number, what do we use it for? Why do we need to keep it after that? But it's not the whole story. For example, we may need everyone's home phone numbers, but do we need them on the main screen or would it be better to make people click to see the more private information. Can we use role based security to show private information only to managers? This takes some thought.
Microsoft is offering a 49 page Privacy Guidelines whitepaper you may find helpful. The introduction says:
The purpose of this document is to propose a baseline for establishing this higher bar. It offers guidance for creating notice and consent experiences, providing sufficient data security, maintaining data integrity, offering customer access, and supplying controls when developing software products and Web sites. These guidelines are based on the core concepts of the Organisation for Economic Co-operation and Development (OECD) Fair Information Practices and privacy laws such as the EU Data Protection Directive, the U.S. Children’s Online Privacy Protection Act of 1998 (COPPA), and the U.S. Computer Fraud and Abuse Act (as amended 1994 and 1996). In the interest of developing a common set of industry best practices for privacy, we invite the community and other interested parties to participate in an open dialogue.
It discusses categories of information, retention, consent, notice, and a few things that are web-specific like cookies. A good place to start your thought process.
Wednesday, November 29, 2006
To follow up on my post about pinning pointers, let me ask one of those tricky questions that someone asked me. If I have an array of things, how do I pin the whole thing? If I ask for a pinning pointer based on element #3 of the array, can I use pointer arithmetic from that pinned pointer to reach elements #4 through #11? Do I have to pin each element one at a time?
The answer is that pinning any element of an array pins the whole array, and that once you have a pinned pointer to one element of the array you can do the usual pointer things. This includes not only incrementing it to move through the array, but if it's a char* you can pass it to things that expect strings and those things will never know the difference. Here's an example from MSDN:
array<Byte>^ arr = gcnew array<Byte>(4);
arr = 'C';
arr = '+';
arr = '+';
arr = '\0';
pin_ptr<Byte> p = &arr; // entire array is now pinned
unsigned char * cp = p;
printf_s("%s\n", cp); // bytes pointed at by cp will not move during call
This sample prints out ++.
Sunday, November 26, 2006
I've recently been asked (again) about pinning pointers so I decided to blog it, so that next time I can just email the link and save everyone a little time
When you're working in C++/CLI, there are two kinds of indirect access to objects: handles and pointers. A pointer is that good old friend (fiend?) we've known for so long and it holds the address of a place on the native heap or the stack. You get a pointer by using the new operator with a type, or the address-of operator, &, with an instance:
Customer* pc1 = &c;
Customer* pc2 = new Customer("CTV");
Pointers stay still. You can cast them to ints, stick those ints into collections, do whatever you like to them, and later cast them back to pointers and dereference them and if they were pointing to something on the heap, like pc2 does, they will still be pointing to the same place on the native heap the whole time. What's more, the instance they point to will not have gone anywhere unless you explicitly delete it yourself.
Handles are the new kid on the block and they sorta-point-to a place on the managed heap. You get a handle by using the gcnew operator with a type, or the make-me-a-handle operator, %, with an instance:
Employee e("Kate", "Gregory");
Employee^ he1 = %e;
Employee^ he2 = gcnew Employee("Brian","Gregory");
Handles don't stay still. If you found a way to get the value out of them and then stuck it somewhere and let the handle itself go out of scope, the garbage collector might clear away the item on the heap, making the number meaningless. Even if you kept the handle in scope, the garbage collector might move the item to somewhere else, making the number meaningless.
Now normally this is nothing more than an interesting fact, one of the differences between handles and pointers. But what if you have some information contained inside a managed instance and you need to pass it to some native code that doesn't know about handles? Now you not only need to convert somehow, you also need to ask the garbage collector not to move that heap item while you are holding a pointer to it. This is called pinning. Let's switch to simpler types so you don't have to worry about what's in an Employee object. I need this most often with strings - I have some managed code that gives me a String^ and I need to pass it to some native code that needs a LPCWSTR or the like.
pin_ptr<const WCHAR> str = PtrToStringChars(title);
PtrToStringChars is a handy function you will find in <vcclr.h>. Those brace brackets are important -- when the pinned pointer goes out of scope, the garbage collector is allowed to move the item again. You really need to minimize pinning time or you will ruin your app's performance, so I've artificially shortened its lifetime to release it as soon as possible. And whatever NativeFunction does, it better not take a copy of the pointer it's given and save it away for future use, because it will be a dangling pointer once str has gone out of scope -- even if title is still in scope.
The concept is much the same when you want a member variable from a managed instance. Grab hold of it and use the pin_ptr template to pin it and give you a pointer, which you can then work with following all the rules of pointers. Let go of it as soon as you can.
Friday, November 24, 2006
There are quite a few products, generally older products, that aren't going to be supported on Vista and probably aren't going to work on Vista. One of the not supported announcements that seems to be catching people by surprise is about SQL Server 2000 and it's free sibling, MSDE. They seem to have run afoul of UAC, which really does require you to change your application.
If you are using SQL Server 2000, you should upgrade to 2005 anyway: it has a lot of improvements for you. But MSDE users don't generally even realize they are using a database: they're using an application that uses a database. Whoever made that application needs to tweak their install so it uses SQL Express (which is just as free as MSDE ever was, and doesn't have a governor) instead. And if that's you, learn about Vista development while you're at it in case your application ends up needing changes too.
Tuesday, November 14, 2006
The recording of our panel at Tech Ed Developers Europe is now available at the .NET Rocks site. "Kate Gregory, Stephen Forte, and Roy Osherove join Richard Campbell and Carl Franklin on stage at TechEd Europe in Barcelona for this discussion about Agile methodologies." We enjoyed doing the show, the folks who were there in person asked plenty of questions, and I hope you enjoy listening to it.
Sunday, November 12, 2006
Data tips are really cool. It's fun to drill down into containers and complex objects and really see what's going on:
So imagine you're in the debugger. You've expanded all this stuff, and you really understand what's in mapVectString now. It has two entries, each is a vector of strings, and you're looking at entry #1 and it has three strings, and you have a good mental picture of the object. Nice. So when I'm debugging, my next step is to say to myself what the code is going to do, given what the object holds. I know most of us do that -- we solve the bug before control even reaches the bad line. But there's one problem... these delightful data tips are covering up the code!
Now, you could move your mouse off the tips, let them fade, read the code, and bring them back again, but that isn't exactly fun or efficient. So try this instead. Press Ctrl. Nothing else, just press Ctrl by itself.
See that? the data tips go almost (but not completely) transparent. Let go of Ctrl and they come back! I bet the first time you try this you will press and release Ctrl a bunch of times with a silly grin on your face. I know I did. Enjoy! BTW, it appears to be Visual-Studio-wide so feel free to apply this tip to your VB and C# programming also.
Saturday, October 14, 2006
The code definition window is not just for C++. Here's a C# screen shot:
Doesn't seem to do anything for VB at all though. I just see No definition selected no matter where I click.
Friday, October 13, 2006
Not enough people know about the code definition window in Visual Studio 2005. I see them trying to understand code by getting editor tips on the classes and functions they see in use:
A reasonably clever trick is to use Ctrl+Shift+Space to get parameter tips for the function:
But the tips are transient, they go away when you use your mouse and try to do some work. So most people fall back on good old Go To Definition:
Sure, this isn't transient, but it leaves you sitting in another file and needing to flip back and forth from file to file when you're just trying to understand what a particular function call does. What I like to use in this case is the code definition window. It's on the view menu:
And here's what it gives you:
It also works to show you the code for a function you're calling. Once it's open, just click on the thing you want to see in the code definition window:
Once you get in the habit of just glancing down to the bottom of the screen to get a little more information, you'll wonder how you ever did without it.
Thursday, October 12, 2006
Here's an article on static code analyis that makes some nice points. I love the title: I’m not in denial, I’m in a hurry. It can be tough, at the end of a project, to find the time for that tidying up that you once thought there'd be time for. Better to get the comparison of what you're doing to best practices as you go along. In fact, every time you build your app. Then you'll know where you stand.
Wednesday, October 11, 2006
One of the things I do for many of my clients is code review. This comes in two flavours. The first is where we all pile into a room with a projector and someone walks us through the code while we ask questions. Sometimes as a result of this the original author has to go away and rewrite bits of the code, but it's just as likely that the outcomes will be everyone understanding how something works, or knowing what there is in someone else's part of the application. The second is less interactive. I read over code and point out bad, dangerous, sloppy, or hard to maintain code. This might be hardcoded error messages in a multilingual application, or non parameterized dynamic SQL, or poor object orientation, or any one of hundreds of other things. Often I point it out not to the author of the code directly, but rather to the author's manager. Or in at least one case, their former manager. (As in, now that we got rid of this person, can you tell just how much mess he left behind?)
Now, if you are thinking of going to Team Systems, let me give you another reason to do so. It can automate a lot of these types of checks. For example, here's a really quite poor little class:
Public Class Company
Private networth As Integer = 0
Public name As String
Private foundingdate As Date
Public Sub New()
When I run static analysis against this, in no time flat it points out:
Running Code Analysis...
C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe /o:"bin\Debug\Information.dll.CodeAnalysisLog.xml" /f:"bin\Debug\Information.dll" /d:"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727" /r:C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules
MSBUILD : warning : CA1020 : Microsoft.Design : Consider merging the types defined in 'Information' with another namespace.
MSBUILD : warning : CA2209 : Microsoft.Usage : No valid permission requests were found for assembly 'Information'. You should always specify the minimum security permissions using SecurityAction.RequestMinimum.
MSBUILD : warning : CA2210 : Microsoft.Design : Sign 'Information' with a strong name key.
MSBUILD : warning : CA1014 : Microsoft.Design : 'Information' should be marked with CLSCompliantAttribute and its value should be true.
C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\Information\Information\Class1.vb(6): warning : CA1805 : Microsoft.Performance : Company.New() initializes field networth of type System.Int32 to 0. Remove this initialization as it will be done automatically by the runtime.
MSBUILD : warning : CA1823 : Microsoft.Performance : It appears that field 'Company.foundingdate' is never used or is only ever assigned to. Use this field or remove it.
MSBUILD : warning : CA1051 : Microsoft.Design : Make 'name' private or internal (Friend in VB, public private in C++) and provide a public or protected property to access it.
MSBUILD : warning : CA1823 : Microsoft.Performance : It appears that field 'Company.networth' is never used or is only ever assigned to. Use this field or remove it.
Code Analysis Complete -- 0 error(s), 8 warning(s)
Done building project "Information.vbproj".
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
Meaningless initializations, unused variables, public member variables... they get found. It's a great start.
Sunday, October 01, 2006
A client of mine, International Time Recorder, is hiring in Etobicoke. Here's the job description:
Job Title: Senior Application Developer
Senior developer responsible for contributing to the design, development and implementation of commercial software solutions to a diverse marketplace.
• Contribute to the analysis and design, while being accountable for the support, development, testing and implementation of solutions and enhancements to software systems.
• Design and develop software components and features. This includes working with stakeholders in developing Detailed Functional Specifications, designing certain key components of the product and implementing the solutions.
• Support and design of maintenance and test procedures and test cases for the product.
• Participate in schedule development and ensure timely product delivery.
• Assist in the creation and implementation of concrete procedures for tracking and releasing product updates.
• Coach and mentor junior development team members in best practices for support, development, testing and implementation of software solutions conducting code reviews as needed.
Education: University Degree in Computer Science, or equivalent experience
Experience: 8 – 10 Years
• Familiarity with the following technologies: C#, ASP.NET, C++, ADO.NET, ADO, Web Services (SOAP/XML), RPC, all Windows Operating Systems, IIS, COM, Active Reports
• Two years experience in .NET development in commercial software development using C#, ASP.NET, ADO.NET
• Eight years experience in commercial Windows Application Development
• Experience in Scaleable Distributed Application design
• Three years experience in designing SQL Server databases
• Proven experience in developing database-driven Web and Windows applications with demonstrated flair for design and layout
• Two years experience as a project lead
• Time and attendance industry experience
• Experience with Microsoft Visual Studio Team Systems.
The firm is doing active development in both C++ and C#. If you're looking for a place to use both old and new skills (and a chance to get regular mentoring from me ), drop me a line and I will forward your information along.
Saturday, September 23, 2006
No, I'm not talking about where the brace brackets go! Coding guidelines are so much more than style guidelines. One of the things that sets me apart from many other developers I know, and especially the authors of code I am asked to fix, is a drive for simplicity. For me, that comes down to three things:
- Start by solving the problem you're actually facing, not some enormous superset of it
- Write the straight ahead way first, then adjust for the exceptions and strange corner cases
- When it's all working, and every time you touch it from then on, look it over to see if you can make it simpler.
That last one is the one so many people seem to skip. Then later when I come along and read the code, I see how it could be simpler, but I hesitate to change it. They must have done it this complicated way for a reason, I think to myself. It can take quite a long time to prove to myself that no, they just settled for 'working' and ran away as fast as they could, leaving this mess for someone else to sort out later.
A mentoring client gave me a pointer to an article ostensibly on Coding Guidelines which is as much philosophical as anything else. I like it. The rules are:
- Make your code look like other people's code.
- Use the simplest design possible.
- Don't re-invent the wheel.
- Document your code.
- Keep security in mind.
- Work in increments.
- Work in iterations.
- Have your code reviewed.
- Don't stay blocked.
- Do unto others as you would have them do unto you.
There are no false notes in this list and I endorse this set of philosphies whole-heartedly.
Sunday, September 17, 2006
Recently, Jim Allchin (Co-President, Platforms & Services, Microsoft Corporation) posted an open letter to developers. In it he points out that it's one thing to beta test a new operating system (as I and thousands of my closest friends have been doing with Vista) and it's another thing to adapt your applications for a new operating system. For me, there are two important parts to that:
- What do I have to do to my application to keep it from failing in the new environment?
- What can I do now to my application so that it will take full advantage of the new environment?
Some Vista-specific examples of this might be "how can I be sure my application will not trigger a bunch of UAC dialogs?" and "will my app have glass?" or "can I get those cool Task Based Dialogs with the blue arrows and stuff?" These are the sorts of things I'll be tackling in some of my upcoming talks. I hope my Vista category will also be useful. My point is, don't wait until Vista ships, then wait to see if any of your clients or customers feel like using it, and then wonder if you have a Vista-ready app. Find out now.
Or as Jim says, "... the opportunity will be tremendous. If you want to ride the wave we're creating with Windows Vista, the best way is to have your application ready by the time we ship! And that is very soon. "
Saturday, July 08, 2006
Conditional breakpoints are cool when you know the value of one variable that is associated with trouble: this only blows up when Xid is 1234. They can also be used to reduce the boredom of single stepping. Say you've got some loop that goes around a few hundred times building up some string or array or something. You don't want to keep going round and round and round... it would be nice to jump ahead to halfway through, for example, and see how things are looking. Now if this is a for loop with a handy named variable, say
for (int i = 0; i<1000; i++)
Then you can use a conditional breakpoint and say "stop when i is 200". Or you could be clever and stop when i % 200 is 0 -- so that's every 200 times. But what if there's no i? What if you're going through a file or a recordset/dataset/resultset and you're going until the end? You don't want to add some fake variable that gets incremented each time through the loop, just so you can set a breakpoint that breaks on certain values of that variable. Instead you want to use the hit count property of the breakpoint. Just right click the red dot and choose Hit Count. There you can set the breakpoint to break whenever it's hit, just the 10th time it's hit, every tenth time (10, 20, 30 etc) or every time after the 10th time Or, of course, whatever number you want instead of 10:
Don't debug the slow way when there are tools to make you so much faster!
Friday, July 07, 2006
Conditional breakpoints were another really important tool in solving a recent "only happens at the big installations" bug in a big and complicated C++ application. We wanted to debug the code with as few rebuilds as possible and we really didn't know how parts of it worked at all. Tracepoints helped us to figure out a lot of it in a short time. We didn't have a decent repro case though, so here's what we did:
- created a script to add an audit table and some triggers that write to it
- created a script to remove those triggers and the table
- created a batch file to run a server in verbose mode, and redirect the output to a text file (remembering DOS commands sure can be helpful... myapp.exe -verbose >logfile.txt was the magic phrase.)
- wrote some instructions for the support guy to grab a backup of the database, run the first script, run the batch file, let it run all night, then in the morning grab another backup of the database, run the second script, and stop the batch file.
Now we ran some queries on the morning version of the database to confirm that at least one X was missing a Y that should have been calculated overnight. We even had the Xid. Thanks to the tracepoint work of the previous day we knew where to be suspicious. A little digging in the trigger output told us whether the problem was "didn't get added" or "got added, but then got deleted". The last step was conditional breakpoints. These let us say "only stop here when you're processing the X with this Xid."
This really saves time when you just need to drill into what's happening in the case that is going wrong. You get to it by right clicking the red dot or diamond and choosing Condition.
Thursday, July 06, 2006
The mentoring client I helped solve a big hairy bug using tracepoints does work in C# as well. She asked if tracepoints are available in C# and VB.NET too. They sure are!
As well, you can get to them other ways than just right clicking the red dot. There's a breakpoints window (reach it from the Debug menu: Debug, Windows, Breakpoints) that shows you what is set up for each of your breakpoints and tracepoints, and which you can use to enable, disable, delete, and edit breakpoints. You can also double-click a line in this window to go to that line of source:
I like to add that "Language" column when I'm working on a mixed project. Just click the Columns button and make your choices.
Wednesday, July 05, 2006
When you have a "mystery" bug to solve, tracepoints are a vital part of your debugging arsenal. Single stepping and looking through code can be S-L-O-O-O-O-W and if you don't even know what you're looking for, it can consume hours and hours of effort. Tracepoints really speed things up. They're like breakpoints that don't break. In a way, they go back to the old "printf debugging" -- but you don't need to make code changes and recompile to change them.
To set a tracepoint, first set a breakpoint, then right-click on the red dot that appears in the margin and choose When Hit:
In the dialog that appears, click the Print A Message box and edit the starter message you are given. You can include any expression in braces and it will be evaluated when control reaches the tracepoint:
Leave the Continue Execution box checked so that you don't break. Tracepoints are identified by red diamonds instead of red dots:
The output from the tracepoints appears in the output window of your debug session:
You can set up something suspicious, let it run, then pore through the tracepoint output and see what you learn. It's a huge timesaver when you're tackling a "we don't even know where to start" bug. Plus, if the issue is related to threading or async issues in any way (and you know me, I keep preaching we will all be facing async issues eventually) then you don't have to worry that pausing execution suppresses the collisions. I recently helped a client solve a big hairy this-stuff-fails-for-our-biggest-customer-only bug using tracepoints... and a few other tricks I will cover in upcoming posts.
Sunday, May 14, 2006
While at DevTeach, a colleague was struggling with a laptop that was flaky because it was running hot. He had it on an exhibitor's table, which was cloth-covered, and the soft surface was impeding the vents, which were mostly on the bottom. I passed along this tip to him, and I just heard that it worked as well for him as it has for me, so I thought I'd share it more widely.
Take three or four pens, the same size as each other, and lay them parallel on the desk or table like this: I I I I
Then carefully put the laptop down onto the pens. If you only had one it would wobble, if you only had two it would roll around, but three or four are pretty stable. Presto, your cooling is dramatically improved and your laptop stops being quite so flaky. I've even presented like this, for one of those talks with two VPCs that really pushes your CPU hard.
Sunday, May 07, 2006
The title of this post comes from a staff member at a client of mine. We were discussing a possible project and the staffer was showing me how they did a particular task. They were using a web app that was going to a lot of trouble not to look like a web app: the users all had a shorctut on their desktop to launch a browser pointed at the site, most of IEs toolbars were suppressed so you didn't think you were even in a browser, and so on.
She performed a search, but before clicking the button she copied her search terms from the textbox, opened a blank Notepad, and pasted them in. "I'll explain that in a minute", she said. Then she clicked the button, and followed the link to the first search hit of twelve or so. On that page she made a small change, or noted down something she saw, something minor anyway. Then she said "Here's the frustrating part." There was no link back to the search results and the IE toolbars were all suppressed. So she used the nav bar links to go back to the home page, from there clicked a link to the search page, pasted in the search terms she had saved, did the search again, followed the second link this time (and the designer didn't like visited and non-visited links being different colours so she had to remember which one she was on) and round and round again.
So I asked "why don't you just use the Back key?" "What Back key?" She was on the second result, and I reached over and pressed Backspace to take her back to the search results. That's when she said "You just saved me an hour a day!" She didn't hug me, but she did something just as good -- ran around the office telling everyone else what she had learned. That particular project didn't fly, but I still do lots of work for that client. And those five people all have an extra hour a day for the rest of time.
What do you know that you're not telling users? Keyboard shortcuts, context menus, alternate ways to do simple tasks... share it!
Saturday, May 06, 2006
I have a mentoring client who is doing a fair bit of Sharepoint work. Some of it I just do for them and install on their servers, but I'm working closely with a team of developers who are building up their skills on both development and administration, and putting sites into production for real people to use to do their jobs.
This client is a pretty large firm - a Canadian household name - and so in addition to a large team of developers they have an infrastructure team, the "downstairs guys" who configure and support all their servers. As the number of Sharepoint sites grows, we're having strategy meetings with developers and infrastructure people about how to handle the growth of Sharepoint within the firm.
So at one point in this meeting the infrastructure person says to me "I need some sort of reports, some way to know how big a site is getting. I can look at the size of the SQL database but it's not very accurate. Or when we do the backups I can look at the size of the backup file. But then how can I tell what the issue is -- maybe someone has turned on versioning or something else that eats up disk space." Various people in the room start talking about the Sharepoint object model, about pointing SQL Reporting Services at a Sharepoint data source, and other developer approaches to the problem.
Now earlier in the meeting several of the developers had been telling the infrastructure person that he has to come to grips with Front Page. There are some things that are really hard to do any other way, and really easy to do with Front Page. And as a result I had Front Page open on my laptop and had opened a site (our own Gregcons internal site as a matter of fact) but hadn't done anything in it. So during this conversation about how to know the size of the site, I clicked the Reports button on the bottom Front Page toolbar that shows when you've opened a web:
And what do I see when I click that?
I grinned and spun the laptop around so that the infrastructure person (and his grandboss, who was at the meeting with us) could see it. "You're going to have to learn to love Front Page," I told him. And to the grandboss I said "aren't you glad you have a consultant?"
A lot of times I work really hard and long to bring my clients value. But there are so many times when I can do something in 30 seconds that the client would have spent days doing another way. I love those times.
Friday, April 21, 2006
I've just updated the mentoring and consulting pages on our website. The mentoring offering is where I get most of my fun, so we've decided to emphasize it a little more. I even found out how to put flare on my blog. Tell your friends
© Copyright 2015 Kate Gregory
Theme design by Bryan Bell
newtelligence dasBlog 2.3.9074.18820
| Page rendered at Thursday, November 26, 2015 11:29:25 PM (Eastern Standard Time, UTC-05:00)
On this page....
|My Visual Studio 2015 course is live!
|Lovely comment on a course
|Video - Stack Exchange Winter Bash (hats)
|Do you know an Australian who needs a C++ refresher?
|Conference Attendee Tips
|Summer Job in Peterborough Ontario
|Advanced C++ course now live on Pluralsight
|Yes, my C++ Precon will also be at Tech Ed North America
|When DateTime is not what you want
|Some guidance from Kenny Kerr
|Sequence Diagrams with Visual Studio
|Things you didn't know the Watch window could do
|Tech Ed USA - Recordings
|GoingNative on Channel 9
|Tech Ed Precon - Career Development
|Seeing a function's return value in the debugger
|STL wraps up the STL series
|Don't set yourself SMART goals
|PInvoke Signatures: "it compiled ok" is not enough
|ISO Technical report on C++ Performance
|C++ Interview Whiteboard problem
|Tech Ed Videos are Up
|What happens after BizSpark?
|Want to prove your Windows app makes the grade?
|Coffee and Code in Montreal, Mississauga and Ottawa
|Get Microsoft to write you a code sample (really)
|Great roundup of Windows 7 developer resources
|Coupling where you don't expect it
|Lalalala I'm not reading
|Career Advice: Be Nice. Work Hard.
|Good Social Media Book
|Hosting a Coffee and Code
|the DebuggerDisplay attribute
|Coding guidelines from the All-in-One Framework team
|Where is my Click Once stuff installed?
|Choose your metaphors wisely
|Is older better? Or anything?
|Soft skills, politeness, and what's in it for you
|.NET jobs in Eastern Toronto
|Be a better debugger
|Why do we make UML diagrams?
|You're not still using Source Safe, are you?
|Maker's Schedule, Manager's Schedule
|Detailed spec-- what?
|BizSpark Incubation Week - Windows 7 in Boston
|What are the travel restrictions doing to the new way of working?
|Comments then and now
|Why criticism shouldn't be wrapped in praise
|The pervasive invisible language
|Want to evangelize to developers?
|I do love solving a mystery
|What social networking should not be for
|NDepend for C++: CppDepend
|A star developer is not just a faster developer
|Women in Leadership and Technology event
|How a VC checks you out
|Some job search links
|Top 25 Programming Errors
|Programmers Should Read?
|Free training if you're laid off
|Just Showing Up
|Get and Set Methods ... could they be Considered Harmful?
|Business rules are made to be broken
|Not formally Agile
|What are you selling, again?
|Wow! DevTeach extras just got extra-ier!
|Startups - Don't Pay for Software
|The Manycore Shift and the Concurrency Land Rush
|Real Programmers Don't Test?
|Herb's new concurrency column
|What should your exception class derive from?
|Be careful what you ask for
|Rules, Methods, Objectives, Values
|Vista Reliability Monitor
|Know your libraries
|It's not what the software does...
|Tech Ed Time
|How do I make a debug build?
|Steve Teixeira and Bill Dunlap on Channel 9: Visual C++ Today and Tomorrow
|Teach Yourself Programming in .... How Long?
|What the C or C++ Programmer Needs to Know About C# and the .NET Framework
|More cool search tricks in Visual Studio
|Pinning a whole array
|SQL Server 2000 and MSDE - not on Vista
|Tech Ed Europe Agile Panel on .NET Rocks
|Transparent Data Tips
|Code definition window - works in C# too
|Code Definition Window
|More on static code analysis
|Code analysis - save money on consultants
|Senior Developer position in Etobicoke
|Vista: are you going to try to be ready?
|One more breakpoint tip - hit count
|Tracepoints - not just C++
|Hot Laptop? Here's a tip
|You Just Saved Me An Hour A Day
|One dollar for hitting it with a hammer...
Pluralsight Free Trial
Click Subscribe, then Start 10-Day trial