I was having a discussion today with some people at work who were reading a book that helps you determine your strengths so that you can take advantage of your strengths and be great at what you do. That led me to think that while knowing my strengths is a good thing, I also want to know my weaknesses.
When I was starting out as a developer, I remember reading up on how to interview well and potential questions that interviewers might ask. One of the potential questions that I saw listed in several articles was, “What are your weaknesses?” That question didn’t really make much sense to me, maybe because I didn’t really know how to answer it (“yeah, my weakness is that I work too hard”), and I didn’t really know what an interviewer might want to get out of it.
I’ve never had anyone ask me that question in an interview (and I don’t think I would ever ask it in an interview myself), but I think the reason that someone might ask that is to see if someone is aware of their own shortcomings and if they’re doing anything about it. So here are some reasons that I try to learn my weaknesses.
Knowing what roles to avoid
We all have things that we are good at and things that we’re not so good at. There are many different roles you can play on a software development team (or any team for that matter). Maybe you really enjoy coding and are really good at it. Maybe you are good at project management and coordinating multiple efforts in order to reach a common goal. Maybe you have strong management skills and can help your team members get better and achieve their career goals. Maybe you are good at helping teams adopt Agile practices. Maybe you’re good at talking to users and business people.
As you read that list, you probably thought of some of those things that you are good at and that you really enjoy doing, and maybe others that don’t get you so excited. This is really really important to remember so that you don’t inadvertently steer your career down the wrong path. The classic example is the developer who was really good at coding and was promoted to management and now can’t take advantage of their strong development skills that got them there in the first place. On the other hand, I know some developers that went into management and thrived there. Either one is fine, but you’ll be happier and more successful if you can stay in a role that emphasizes your strengths.
Knowing what to work on
Some things will come naturally to you, and other things won’t. That doesn’t mean that you should only do things that you’re good at. Most developers naturally are not extremely gifted when it comes to talking to users and business people, but I think this is a very important skill that I think every developer should work hard at. Being able to right good code does you no good if you can’t create systems that will actually solve the right problems.
This is why most meetups that I attend have more to do with QA testing, business analysis, and project management. I’m better at development than I am at all those things, and I like development the best, but I want to be better at the other disciplines because it makes me a more well-rounded developer and allows me to know how to help entire teams instead of just developers (which lines up with my career goals).
We can develop these skills if we work at them, even if they don’t come naturally. But if you don’t take the time to look at what you need to work on, you won’t ever get better.
Knowing how other people might see you
There are two sides to this one. First, I want people to know me for my strengths. There are thousands of .NET developers, agile coaches, project managers, etc. out there. What is going to separate you from the crowd? What you’re great at.
That will get you in the door, but if you stay somewhere long enough, people will find out what you’re weaknesses are. This is fine, but I want to be aware of how people might be viewing me because that might help me understand the way that people act towards me and why they might make various decisions that affect me. If I’m aware of my weaknesses and other people also have discovered those weaknesses, now I can take what they say and understand more about what they are saying and what is causing them to react a certain way. In turn, this teaches me more about myself and what I need to work on in order to get better. (At no point should I ever beat myself up for my weaknesses, this has no constructive value for anyone.)
For example, I am an extrovert, which is a minority in the software development world. This means that I sometimes tend to think out loud, and sometimes I’ll throw ideas around without having really thought them out. I think this sometimes confuses and overwhelms some of my other team members, who were still trying to understand my previous thought which I’ve already moved on from. While this is the way that I tend to process ideas, I’ve realized (based on how other people have reacted) that this isn’t always constructive for others and that I sometimes need to think things through more internally before I verbalize them.
While thinking about your weaknesses isn’t always a whole lot of fun, it will go a long way towards bringing you career success and enjoyment. We could all use a little more of that.
The open team workspace, once limited to hardcore Agile enthusiasts, is now becoming more mainstream (dare I say trendy). Tall cube walls are being torn down in favor of short walls, folding tables, rolling desks, and any number of other creative setups. But some people are wondering if it’s a good thing.
I’ve been working in open environments for most of the last 8 years now. I had L-shaped desks, folding tables, low cube walls, no cube walls, and everything in between. I’ve been a huge fan of this sort of setup, but I’ve worked with some people who didn’t like it as much. This is what I’ve got now (which I really like):
Regardless of whether you like open workspaces or not, there are some things you need to learn in order to work in this sort of environment. If your company has an open floor plan, there are definitely some considerations that you should think about.
The #1 complaint I hear from people who don’t like open workspaces is that it is hard to focus. Sometimes when you’re working on a difficult coding problem, you need solid time to focus on one thing and one thing only. This is really important, but thankfully there are many ways to handle it.
This one is pretty obvious. I often joke that our IT department sounds like the mall food court. We are by far the loudest department in the company (excluding departments where people are on phone most of the day). All of this is good but you need a way to block out the noise.
Everyone in our IT department has a laptop. That means that we can work at our desk, or we can go work in the lunch room, the coffee shop, or at home. We have some docking stations set up with monitors in some rooms where you can work by yourself, or collaborate with your friends. We have conference rooms with big screen TVs and whiteboards. We can draw on the windows with dry erase markers. I’ll often go sit somewhere else in the building, which I like to do if I’m going to work on something that requires a lot of creativity just to get a change of scenery. We have rooms that look like this (no this is not a stock photo):
I have young kids, so I tend to get in a little later, leave a little earlier, and work some at night after the kids go to bed. I can kick off a job at night before I go to bed and it’s ready for me to test in the morning. The flexible hours allow me to do some of my work at home when no one can bother me, and I still have plenty of time with the team. It’s the best of both worlds.
Keep teams together… and separate
I love the collaboration, camaradarie, and togetherness that comes with an open work environment. I’m a people person, so I thrive on the energy. Working from home can be nice but I love seeing people every day. I love that I go into work and people ask me how my weekend was.
At the same time, if you’re going to have an open floor plan with several different teams in the same area, you do have to be careful about putting different teams too close together. We have lots of teams in one area, but I’m friends with most of them, so it’s not a big deal. And while our environment is very open, it’s not like we’re crammed onto rows of folding tables like we’re in a computer lab. I still have my own personal space. I like the sound of my teammates talking and collaborating, but the sound of people that you don’t know is like fingernails on the chalkboard. It can drive you insane.
The common thread
After years of hearing pros and cons of open environments, I think I’ve found the common thread that most people will agree on. We need work environments that meet multiple needs and many different situations. Sometimes you need to collaborate, and sometimes you need to focus by yourself. Sometimes you need to look at code with a group of people, and sometimes you need to draw things out on a whiteboard. Sometimes you need a place that helps inspire creativity. Some people thrive around people, and some people need peace and quiet. Some people like working during the day, and some people like working after midnight. There are ways that we can provide work environments that provide the best of everything and allow people and teams to work in whatever manner works best for them.
I believe in open work environments because we are solving business problems, and the hardest part of every software project I’ve been on has been not having enough communication. Sure, there are difficult technical problems, but those are best solved in the context of the team, even though much of the actual work is done individually. Tall cube walls tend to decrease communication when we usually need to increase communication. In an open environment, the communication barriers are broken down (literally), but I still have ways that I can get away and focus.
We need to remember that people are all very different. What’s good for one person may not be preferable to another, and we need to be aware of that.
We all love the DRY principle (Don’t Repeat Yourself). It really is a good idea, we don’t want to have two places in the code that do the same thing, and we want good object-oriented design. But even DRY can go too far.
Recently I’ve run into some cases where DRY decreases the readability of the code. I had some simple classes to write that do some relatively simple calculations, and the business rules are fairly similar to some other classes that exist, but with a few differences. I started down the path of making one class that can handle all situations, with hooks for modifying the behavior of the class (either virtual methods or configuration settings somewhere else).
This is all well and good until you realize that now you’ve taken something simple and turned it into something really complicated that even you have a hard time understanding anymore.
DRY is great, but I lost sight of why DRY is good. DRY is good because it makes code more maintainable, more consistent, and easier to understand and add new functionality. But as soon as DRY stops providing those benefits, maybe it’s time to keep things simple and just write readable code that makes sense, even if it means you have a little bit of duplication.
There are lots of code katas out there that are typically used to help developers practice test driven development and writing well-designed code. I have a new kind of kata for you today.
In my last post I talked about how developers should be able to test their own code, but as developers we need to get better and defining all of the test cases. The only way to get better is to practice.
Testing a four-function calculator
Let’s say you need to test a basic four function calculator like this one.
What are all of the testing scenarios? Keep in mind that just from looking at the picture, you might not know the exact requirements of how the calculator works without asking some questions.
Some basic details (for those of you who are too young to ever have used one of these calculators):
- Pressing M+ will add the current value to the value stored in memory (or 0 if there is no memory value), but not change the value on the screen
- Pressing M- will subtract the current value to the value stored in memory (or 0 if there is no memory value), but not change the value on the screen
- Pressing MR will load the current memory value and display it on the screen
- Pressing MC will clear the current memory value, but not change the value on the screen
If you don’t know how something should work, write down the question that you need to ask or record the assumption that you made about how it should work (so that you could validate the assumption later). You’re also allowed to try things on your computer’s calculator to see how something should work (in real life, we often look at other implementations of our software to get ideas about how it should work), but remember to write down your assumptions so that you can validate them.
Come up with your test cases, questions, and assumptions and post your answers in the comments. You can use any format for the test cases that you would like. Let’s see what you can come up with.
There are those who believe that a developer should not test their own code. This may sound logical, but I’m not sure I’m buying it.
This statement typically refers to QA testing, and doesn’t mean that a developer shouldn’t write unit tests. The thinking here is that a second person testing the features that you’ve developed might think of things a different way and find a problem that you didn’t think of when you wrote the code.
There are lots of commonly accepted statements and ideas like this in software development. But I’ve found that in many cases, these ideas are usually based on certain assumptions, and if you can challenge those assumptions, you might open yourself up to things that you didn’t think were possible.
The assumption that I see here is that a developer writing the code is not sufficiently capable of thinking of all of the test cases. Imagine you write code for a feature, and now you have to test it. At this point, you’ve gone through a certain mental thought process when you implemented the feature. This makes it much harder to think outside of the box to come up with the edge cases. Not to mention that when you see that the feature appears to be working overall, it’s really really tempting to do some basic manual testing and then move on to the next feature without really doing your due diligence. A independent QA tester, however, will look at the feature objectively because their thought process isn’t clouded by past experience of having written the code.
OK, so what if the developer figured out all of the tests cases before writing the code? Now their thinking isn’t clouded by the implementation of the feature because they haven’t wrote the code yet. Maybe a QA person helps define the test cases, but this post is about developers testing their own code, so let’s assume that QA people aren’t involved. I would argue that now we’ve removed the main reason that developers are not good at testing their own code (thinking of the test cases after writing the code), so they should be able to think of test cases just as well as a QA tester, and therefore they should be able to test their own code.
Don’t misconstrue what I’m saying there – I’m not saying that we don’t need our QA teams. I’m saying that developers need to be responsible for testing. QA teams can add more testing help, but developers need to be responsible for their own code.
This opens you up to new possibilities. It enables developers to be confident about the quality of their code. It limits the wasted time you incur when you have the back-and-forth that comes with QA finding bugs and developers having to go back and fix things. It can reduce the amount of “checking” that QA people need to do because they might be comfortable knowing that developers are writing quality code.
If you’re a developer, this is some thing you can start doing today. Before you implement a feature, come up with all of the test scenarios before you write your code. If you have a QA team, have them review your test cases to see if you’ve missed anything. Then go write some bug free code!
How much of the responsibility for the software that you are creating falls on your shoulders?
There are two ways of looking at responsibility on a team. One view would be to say that if there are 10 people on the team, then I’m responsible for 10% of the software development process. I don’t need to be concerned with the quality of the requirements because that’s the business analysts’ job. I don’t need to worry about testing my code because we have testers to do that.
The other view is that even in a team environment, I am still 100% responsible for the software I’m creating. That means that I’m not just implementing the requirements, I’m trying to understand the requirements to make sure that they’re correct and that we’re building things in the best way possible that will meet the needs of the business. And that certainly means that I’m never ever going to send code to QA that I haven’t tested just because I think they’re going to test it for me.
I need to be responsible for communicating with my team members the best that I can. I would much rather be clear about who is doing what rather than assuming. If I make an assumption, it’s probably going to be wrong – either I will assume someone is going to do something when they’re not and something will slip through the cracks, or I will assume someone is not going to do something when they are, and now we’ve duplicated effort.
This is what I see happen often on software teams, especially when it comes to testing. Developers assume that QA is going to do the testing, so they give code to QA without completely knowing if it’s working. QA assumes that developers are going to do this and don’t know what was tested and what wasn’t, so they think they have to test 100% of the functionality of the feature. In reality, the developer probably wrote decent code that mostly works, and they probably did test it to some extent (whether manual or automated), so the tester is duplicating some of the effort, but if they don’t know what was already done, they don’t have a choice.
This is where communication is key. If I as a developer am going to write automated tests to prove that my code works, then I want QA to be involved in the writing of the tests (even if that’s just reviewing what I’m doing). That way QA doesn’t have to duplicate effort because they can know that developers have already done some of the testing, and developers can start giving code to QA when they are confident that it works (with actual proof to back it up). QA and developers can work together to decide who is going to test what, what is going to be tested, and how it’s going to be tested.
In this case, everyone is 100% responsible for the quality of the software. Instead of expecting others to cover for us, we work together with others to make sure everything is covered. This requires people to move past their traditional roles, trust each other, and work together. In the end, we won’t duplicate effort and we won’t let things slip through the cracks.
Do you sometimes have that feeling that your life is running you instead of you running your life? Do you feel so bogged down with meetings and distractions at work that you feel like you’re unable to get anything accomplished? Are you feeling like you don’t have the discipline to accomplish your goals?
The answer to all of these questions involves focus. I firmly believe that I need to have a plan for achieving my goals and getting things done so that I can be in control of the situation rather than have the situation control me.
Focus at work
Most of feel (or have felt) that we have too many meetings and distractions. I’ve certainly felt that way a lot in the past. I’d like to tell you to just start skipping meetings, and while that might be a good idea in some cases, most of the time you can’t do that. What you can do is prioritize meetings and distractions so that you have time for the most important things.
If I’m working on a project, people expect me to get things done. So if all of my time is consumed by other things like meetings, production monitoring, asking questions, etc., then I’m not sticking to my promises. I started blocking off work time on my calendar. Actually our whole team blocked off 3 hours in the afternoon for “work time”, and if my day got to be half full with meetings, then I would just block off the rest. I decided that I needed at least half a day of time to get things done because that was important. I wasn’t dismissing everyone else, I was just making a conscious effort to decide what was most important.
I’ve also been getting better at saying no. Even if I’m not feeling swamped by deadlines and meetings, I still have a primary task that I’m focusing on. In order to maintain that focus, this means that I’ve started saying no to other people who need things done if I’m not the person who should be responsible for doing the work. I generally like to help people, so it’s been hard to do this. I’ve even started doing it with relatively easy tasks. Sure, I could spend 20 minutes and get that thing done for someone, but then they will keep coming back. This sounds somewhat selfish, but I’m making a conscious effort to focus on my task at hand.
Focus in life
There have been times when I have felt like my life was running me and that I was just treading water and trying to keep up. No one likes feeling like this.
I realize that I’m only somewhat in control of my life. I could get cancer tomorrow, or get hit by drunk driver. Thankfully those haven’t happened to me so far, so I want to proactive and intentional whenever I can.
The first thing to do is decide what you want your life to look like and then come up with a plan for success. Then you need to arrange your life and activities around those priorities. Time is a scarce resource for all of us, which means that at some point we have to think about what’s filling our day and eliminate things that aren’t important. With all of our electronic devices, it’s so easy to spend more and more time surfing the internet, reading blog posts, playing online games, and so on. Not that those are bad, but I’ve found that I need to cut some of those out so that I have more time to do the more important things I need to do.
This is not your typical technical blog post. It’s about something I’ve started doing personally to increase my productivity at work. And it’s been around since the beginning of time.
It started because I had a 5 week old baby at home, so I would occasionally be a little more tired than usual at work. We have a room at work with a recliner, so I went in there, closed the door, turned the lights off, and took a 15 minute nap.
When I got up… wow. I felt like my eyes were so wide open that people were going to look at me funny walking down the hall. This was better than caffeine.
I now have a 7 week old baby at home who is nice enough to sleep through the night now, so I’m getting back to my normal sleep schedule at night. But most days I still take a nap. All it takes is 15 minutes and the lunch coma is gone. Afterwards I find that I’m thinking so much clearer, and I generally do things much faster than before I rested.
I’ve always joked about how work would be so much easier if I could take a nap in the middle of the day. I guess it actually works.
I recently went through a big change in my role at work. I went from being a tech lead on a team of 15 people to working on a project all by myself.
Anytime you go from one extreme to the other, you see some stark differences between the two environments, and in my case, it caused me to think about the way we do things in teams.
The most obvious change was a huge decrease in meetings. I went from an average of 4-5 meetings a day (not counting standups) to an average of 1 meeting a day. When you’re a team lead of a large team, I suppose that comes with the territory. But when you have close to 7 hours a day of time to work with minimal interruptions, you get a LOT of work done.
Meetings are a common complaint from people who work in a team environment. And even though you can read hundreds of articles about how meetings are pointless and you should skip them, the fact is that most meetings exist for a good reason, and while skipping all your meetings may seem like a good short term decision, you can’t realistically do that all the time.
I think that the problem isn’t necessarily the meetings, it’s the fact that the meetings are needed in the first place. Every time you add a person to a team, you’re introducing more inefficiency to the team because now there is one more person that you need to communicate with, that you have to share information with, that you have to invite to a meeting.
Now, even though this inefficiency exists, typically you are adding someone to the team because the benefits of having them there outweigh the negatives. But to what extent? Is there a point where you get diminishing returns from adding new people?
Managers exist for a good reason – to coordinate team activities, make sure everyone is on the same page, communicate with other teams, and go to lots of meetings so that the rest of the team doesn’t have to. When your team gets really large, you start needing more management. Then what happens is one of two things – the manager becomes overworked and can’t keep up with everything, or you end up having your tech leads go to more meetings and become more like managers. The problem there is that tech leads are tech leads because they’re good at tech, not necessarily because they’re good at management, and now you’ve essentially taken your best technical person and removed them from the role where they can provide the most value. Then your tech leads get frustrated because they feel that they don’t get anything done because they spend all of their time on meetings.
If you’re hiring a bunch if people and creating a big team, it’s probably because you have a lot of important work that needs to be done, so I’m not saying to not hire those people. But I would encourage you to find a way to split them up into smaller teams. You may have multiple teams working on the same project or even in the same codebase, and that’s fine, we just want to decrease the amount of communication that is needed in order to get things done.
Our IT department has done a lot of this lately, trying to take large teams and divide them up into smaller sub-teams of around 4-5 people. Now those communication inefficiencies are diminished because you only have to communicate with a few people (who ideally sit in the same area as you). Not only that, planning is so much easier. It’s much easier to accurately predict what you can do with 4 people than it is with 15 people, not to mention that if things go off the rails for an iteration, it’s a lot less expensive.
I think the ideal team size would be 3-5 people, where you don’t have more than 2 people in each discipline (BA, QA, dev). It would be even better if those people were somewhat cross-functional so that they can help each other out when someone gets behind.
While splitting into smaller teams may make those teams more efficient, you still will need coordination across teams and more meetings and management. But I think having smaller teams helps you to see the need for management and enables you to put the right people in those roles instead of just pulling your tech leads in to fill those roles.
There are no hard and fast rules for this sort of thing, and the results may be different for you than it was for me. The important things is that we constantly evaluate how we are doing things and find ways that we can increase our efficiency and reliability of our software teams.
Software developers are notorious for falling in love with new, shiny things. I always try to use the right tool for the job, whether that’s new or old technology. But every now and then I find something that makes a whole lot of sense in my head and I can’t ignore it.
I’ve been learning about NoSQL databases for the last year or so mainly because there’s a lot of noise about them and I was curious, and I also find data access to be this annoying problem that always seemed to be harder than it should be. First I looked into MongoDB and then eventually RavenDB. I haven’t used either of them in production yet (although I work with people who have), which is why I titled this article a “hypothesis” because I don’t really have any real life stories to tell to back up what I’m going to say.
In my research of NoSQL databases I noticed two particularly interesting things:
1) I find that ORMs make data access with relational databases much easier in most cases over using stored procs for everything, but even with all of the experience I have with various ORMs, data access is still a pain.
2) Ayende Rahein was one of the main contributors to NHibernate for years, and he probably understands ORMs better than almost anyone in the world. And yet even he decided to create RavenDB and move to NoSQL. If the ORM expert decides that using an ORM is too hard, maybe he’s onto something.
Here’s how I see it: relational databases are really good for reporting and querying, but not so good for loading information in an application. NoSQL databases are really good for loading information in an application, but not so good for reporting and querying.
The application I’m working on is 2 years old now and we use SQL Server. We are starting to accumulate a lot of data in the database, which is exposing performance problems in our application and everything is starting to process a little slower as we get more data in the database. Our database is not good at loading information in the application (it takes a lot of queries to load up the main screen because it has to query so many tables).
We are also starting to move away from reporting against our database now and moving more data into our business intelligence data warehouse so that our reports can run faster and be written against a relational schema that is optimized for the types of reports that we tend to write.
So let’s recap.
1) Our app is not good at loading data into the application using a relational database
2) Our relational database is not going to be used for much reporting and querying because we’re going to move the data into another database for that purpose.
So with that in mind, why am I using a relational database? Shouldn’t I be optimizing for the loading and saving of the primary objects in my application since that’s my pain point? (I haven’t even started talking about the increased in developer productivity from being able to do more in the business layer and less in the data access layer and stored procs.)
I’m not saying that I’m going to switch my application from SQL Server to RavenDB, because I don’t know that it would be worth the time at this point. But if I were to do so, I would be able to delete a slew of complicated stored procedures and turn my data access layer to a really really thin layer than essentially just passes a C# object to RavenDB. I would be able to load, modify, and save our primary object (and all it’s children) with 2 database calls instead of over 20 (in some cases). If I use RavenDB, there are built in mechanisms to write triggers that will take updates from RavenDB and replicate them to a relational database.
When people start a new application, it’s just assumed that they will use a relational database. But why? Is a relational database really the best data store for every application? Given that we have good NoSQL alternatives, maybe it’s time we start evaluating all the options.
I’m sure it’s not all rainbows and unicorns, and in some ways you’re just trading one set of problems for another. Dealing with large amounts of data is never easy. But I’m seeing a lot more solutions than problems.
Older Posts »