Jerry's Blogs

Tuesday, February 19, 2008

On a Beautiful 3-Day Weekend...

...I spent most of it working, and the rest of it sleeping and eating.

The weird part isn't that I started at 11am Saturday and worked till 3am Sunday morning. It also wasn't that I strangely ended up at Denny's with the same group of people until 5am. And it even wasn't how I passed out in the back seat of my car until 8:30am (thank you Chuck Norris).

No, the weird part was none of that. It was the fact that I ended up back at work around 2pm on Sunday and Monday. And I had a great time all 3 days. What a refreshing sense of accomplishment to (very nearly) finishing a long overdue project. It was also the first time ever that I've really worked with Minh on ... anything ... And I'm happy to say that I really do like working with the guy. He's sharp and I think he makes me more confident and egotistical about my software engineering rants.

I'd say the downsides to the weekend were not seeing Wendy enough, and not getting around to any of my homework :( That's all going to suck later.

Labels:

Sunday, December 16, 2007

On Consistent Development Environments

It's painfully clear how ineffective I am on other people's computers these days. There's muscle memory in my hands to do all kinds of common and not-so-common tasks. Launch an application? Alt-Esc (QuickSilver). Navigating text? Emacs key bindings. Email? Chat? Webbing? You name it, I've got some obscure keyboard sequence to go about it. I'm not the only one either, since it seems that everyone in rescomp has a very customized daily workflow. Dotfiles are pimped out to the limits of un-usuability by any foreign hands.

Now that everything's customized just so, you'd think productivity should shoot through the roof. Unfortunately, I've found this to not be the case. Once people get cozy, a whole new nightmare creeps up. Instead of people being very dependent on environments, CODE will become dependent on the environment. The code may expect certain environment variables to be set; It may expect certain libraries to be installed; It may expect to be put in a certain location in the filesystem; It may only work when just the right amount of sunlight hits it. These problems don't crop up as long as you continue to develop in the same environment as the code, but is really shortsighted and hard to maintain later on.

What solutions are there? Obviously, you can write out a ton of config files that are meticulously tailored and configured for every development and production box. But it's equally clear that this can get hairy and different combinations will eventually lead to deprecated configs and major rewrites. The other approach is to centralize as many things together and minimize the different places configurations can be made. I see this as a much better practice for maintaining consistent development environments. Instead of writing documentation that tells new developers the dependencies they need to install in order to build the app, simply bundle the dependencies along with the app. Similarly, when developers use 3rd party libraries, why not version it alongside the app code to maintain a _single_ consistent version of the library that all developers share? Taking this philosophy to the extremes, we can even apply this to deployment and production. Bundle the toolchain, OS, servers, hardware, and support software... Imagine how fantastic it would be to pull a VM from the net and be confident that a bug is a real bug, and not a bad configuration.

Oh, and zombies scare the crap out of me, especially when seen in IMAX form

Labels: ,

Monday, December 10, 2007

On Getting People to Work on Projects

Though I haven't made more than a couple of attempts to work with people on exciting projects, I've already noticed a few negative recurring themes. I'm not blaming these on any specific people either cause I'm just as guilty as the next guy. I've heard some of these a few times now:

  • Can't, school. (totally legitimate, but doesn't apply to me)
  • Can't, _insert_hobby_interest_here. (all the more power to them)
  • Can't, not interesting enough problem. (then come brainstorm a better problem with me)
  • Love to, then work on everything else except with me. (hasn't really happened that much, but I feel like it sometimes)
  • Love to... never hear back again

Basically, what I have is a bunch of really cool and awesome people I'd like to work with. I don't care if I make money (at least for now). Even my elementary school buddy from Ohio has shown more interest in brainstorming with me than some of the people I'd like to work with. I understand school is hard. I get that work takes time. I sympathize with everyone's reasoning about everything. But when it comes down to it, there must exist SOME project which is exciting enough that you'll bump it up in terms of priorities. I don't even care if that project isn't something you want to share! I just want to see more people care or do projects for the sake of having fun. At some point, someone has to overlap with me right?

I was bitchin' to Andrew, and he gave me a great response. Something I'd like to ask people next time I want to do a project:

[00:13] Get a timeline, get that list together of people you want, go through each one, ask them for their schedules and where they see themselves in like 5 years, find out who's actually available to work on your project, poll each of them for their true interest and to see what they'd like to do, if their plans and personal interests line up with your plans, then it's a green light go
[00:13] put them in our team, get steady lines of communication with each of those that care
[00:13] with the timeline, have certain deadlines
[00:13] like, by day 40 of the launch, i will have a tentative team list of 8 or 9 people
[00:14] by month 3, I will have had an office or a code base or a proper code repository set up
[00:14] or hell, by month 4, all of the foundation will set up and true coding can be setup
[00:14] you can also have parallel timelines
[00:14] like one for business setup
[00:14] one for coding
[00:14] one for idea throwing around
[00:15] and one for, i don't know, staff development, a happy team is a strong team
[00:15] without visible goals, no one has a drive to do anything
[00:15] even if they're soft deadlines, they're better than nothing at all otherwise procrastination sets in
[00:17] I don't know if Im' relaly consoling you...
[00:17] I feel like I'm hitting you with a stick :(

As a last resort, maybe it's cause I smell bad. I'll go take a shower now :)

Labels: ,

Saturday, September 15, 2007

On Premature Software Testing

I've fallen victim to it a few times now and would like to remind myself of the causes and consequences.

Don't get me wrong, I love testing and have attempted/done/failed at it ever since CS61B. I've used standardized test frameworks, hackish quickie frameworks from school, and created my own small frameworks for specific projects. Testing is a good thing.

But there is such a thing as testing too early. My most recent mishap happened during my internship. I finished a tool that I thought did what I want, and fully tested it. Well, the plus side was that it was perfectly tested against what it does, and worked beautifully for all possible inputs. The downside was that the code didn't do what it was supposed to do! I misunderstood my own requirements and coded something wrong. Then instead of having tests that could support me as I refactored, I ended up with an extra set of barriers that kept me constrained to wrong solutions. In other words, I believed in my tests and this slowed down my redesign towards a correct solution.

Another time this happened to me was during cs164 while I was writing an Earley parser. This one cut me deep because the solution just happened to work against the cases I specified in my tests. Then about one week before the due date, I noticed that I misread the original paper and implemented a system with different semantics. All the tests that exercised individual methods were scrapped. In the end, all tests were scrapped :(

I lost many hours on both those mistakes, but I have noticed different cases when I'm more successful. Here are some guidelines I think work well:

When to Start Testing

  • start testing when you start coding for real.
  • start coding for real after you've read and re-read your spec enough times to recite it backwards. Think of a design, think of how use cases would fare against that design.
  • if there are sections of the design that are ambiguous, or if you aren't sure of what tools to use to implement something, explore with quick dummy code and take notes. Don't even bother putting the dummy code in your repo, or actual directory... It'll only tempt you to keep crappy code. Throw the code away, but keep the notes.
  • with design doc, and notes from exploring in hand, try writing some real code. If you find yourself rewriting a ton of stuff repeatedly, you didn't design/explore your problem space enough before starting.
  • when exploring concepts and designs, it's a good idea to explore what test strategies are appropriate. I say appropriate because there'll always be some gigantic mammoth of a testing framework with more features than your project needs and a configuration and learning curve to match. Sometimes, the framework that's "just right" is one that you glue together.

How to Test

There are plenty of good guides out there on 'what' to test, but I think many of them provide examples that are too trivial and brittle against refactoring.

  • when testing data models, focus on getting consistent domains, and lightweight models. If it's hard to test, it might indicate a flaw in your design.
  • unit testing is fantastic, but double check that the methods you're testing are actually relevant and useful. A correct method doesn't imply a useful one. Also, instead of tying very strictly with method names, it can be more readable and flexible to describe your test in terms of the action or mutation.
  • don't strictly focus on unit testing. Do the functional tests in parallel to expose useless methods and flawed interactions early on. The same applies for integration tests. Also, the sooner you communicate with modules written by other members of your team, the better.

We all knew that testing too late or not testing at all can cause cancer, but there is such a thing as testing too early. It wastes your time, and may restrict you to a suboptimal or incorrect design. Furthermore, testing isn't the same as designing. No amount of random testing will yield a solid design. Rather, an elegant design will naturally encourage you to think about tests, and those tests can then verify your implementation. Testing is like eating your vegetables: it's good for your health in the long run, but eating too much or the wrong kind will give you the runs.

Labels: ,