Effectiveness is key for software engineers as it encourages a focus on what matters most. Often this is delivering the best value to users, the business, and ultimately careers with the time available.
If we’re focused on activities that are considered most effective, we can also demonstrate our value to the team and increase the chances of promotions and other career opportunities.
Here are 10 traits I believe help engineers be effective:
1. Cares about the user and their needs
2. Is a great problem solver
3. Keeps things simple, while caring about quality
4. Communicates effectively with your team
5. Builds trust, autonomy, and social capital
6. Understands team strategy
7. Prioritizes appropriately and execute independently
8. Thinks long term (e.g. implications of decisions)
9. Leaves software projects better than you found them
10. Is comfortable taking on new challenges
This is a list of traits I’ve consistently found important while leading teams at Google and which I believe also translate well to many companies.
Efficient engineers do things right. Effective engineers do the right things. Ideally do the right things right.
If interested in this topic, I’ll be covering how to be an effective software engineer, technical leader or manager in my O’Reilly book “Leading Effective Engineering Teams: Lessons from 10+ Years at Google”, available to pre-order.
The making of an effective software engineer
As a software engineer, you should care about your users and what they want. You should be able to understand the goals of your company and how your work will impact them.
This is because you are ultimately responsible for building software that solves problems that customers would pay to have solved. If you’re not thinking about how people will use the product or service, then it’s likely that what’s getting built won’t actually be useful.
While this may sound obvious, it can be hard for many developers to grasp. Often we see developers get caught up in the details of writing code, without fully considering why they’re doing so in the first place.
This can lead them astray from their actual goals, as well as drifting from their best work by focusing on small tasks, instead of making sure they’re contributing towards larger strategic outcomes.
Cares about the user
A core part of being an effective software engineer is caring about your users and their needs. This is more important than using a specific technology or framework.
An effective software engineer will consider:
The problem domain – what does the user want to accomplish with your app?
The business context – who are you building for and what can they benefit from?
The technology – what technologies do you have available, and what would be best for this scenario?
Team goals and objectives – how will your work contribute (or not) towards accomplishing your team’s goals?
What might this look like in practice?
To foster a user-centric culture within the team, software engineers can adopt the following practices:
Advocate for users: Be a champion for user-centricity throughout the product development process (to the extent you’re involved). Promote a culture of empathy and understanding for the user's perspective.
Emphasize user research: Encourage and even participate in user research activities, such as user interviews, usability testing, and surveys. Gaining a deeper understanding of user needs and pain points can make a difference.
Prioritize user needs: Advocate for user needs during design and development discussions. Bring user feedback and insights to the forefront of decision-making.
Iterate and improve: Embrace an iterative development approach. Support gathering user feedback signals. Use this feedback to refine the user experience and make incremental improvements over time.
By adopting these practices, software engineers can empower their teams to create products that are truly user-centric.
Is an effective problem solver
You have to be good at solving problems.
Often, the best solutions are simple and elegant. But sometimes you may need to think outside the box. A lot of times, a problem can be solved in multiple ways – some that are neat and tidy (but not overly complicated), others that are unconventional but still effective.
The ability to solve problems is something anyone can do once they’ve mastered their tools and processes. Being able to think outside the box while also considering all aspects of a problem will help ensure that your product or service lives up to its potential and makes customers happy.
A systematic approach to problem-solving is crucial for engineers to tackle complex issues efficiently. This approach can involve the following steps:
Problem definition: Clearly define the problem, its scope, and the desired outcome.
Root cause analysis: Identify the underlying causes of the problem, considering both technical and non-technical factors.
Brainstorming solutions: Generate a diverse range of potential solutions, considering both conventional and unconventional approaches.
Evaluation of solutions: Evaluate each potential solution based on its feasibility, effectiveness, and impact on the overall system.
Implementation and testing: Implement the chosen solution, rigorously test it to ensure it addresses the problem without introducing new ones.
Keeps things simple, while caring about quality
You don’t need to write the world’s most complex software. You just need to be able to understand the problem, know how to solve it in a reasonable way, and then keep things simple.
As you gain experience in the industry, you’ll get better at understanding the tradeoffs between simplicity and performance. As a result, your code will become more efficient, without sacrificing its overall quality.
This is one of those traits that sounds deceptively simple. In reality, caring about quality requires constant vigilance as an engineer, because you’re always balancing trade-offs between different dimensions of quality (such as accessibility versus performance).
It’s important to know what matters most in terms of your product or service, so that when there are competing priorities at play you can make informed decisions about which one should win out during development cycles.
Builds trust, autonomy, and social capital
Let’s tackle these one by one:
Trust - you can’t build trust overnight, but you can slowly work to build it over time.
Trust is the foundation of any successful team. It is built through consistent actions, reliability, and a commitment to transparency. Engineers can earn the trust of their colleagues by:
Being dependable and meeting deadlines: Consistently delivering on commitments builds confidence and reinforces trust among team members.
Being open and honest: Communicating openly and honestly about progress, challenges, and potential roadblocks fosters transparency and strengthens trust.
Actively listening and respecting others' viewpoints: Valuing diverse perspectives and engaging in active listening demonstrates respect and encourages collaboration.
Autonomy - autonomous workers are happy workers
Autonomy empowers team members to take ownership of their work and make informed decisions within their areas of expertise. It fosters a sense of responsibility, creativity, and engagement. Effective engineers promote autonomy by:
Providing clear goals and expectations: Clearly defined objectives and expectations set the framework for autonomous work while ensuring alignment with overall team goals.
Empowering team members to make decisions: Trusting team members to make informed decisions within their scope of responsibility encourages ownership and fosters a sense of empowerment.
Encouraging feedback and continuous improvement: Creating a culture of feedback and continuous improvement empowers team members to identify areas for growth and contribute to overall team success.
Social capital
Social capital refers to the network of relationships and connections among team members. It facilitates knowledge sharing, collaboration, and mutual support. Software engineers can cultivate social capital by:
Participating in social events and team-building activities: Engaging in social interactions outside of work helps build rapport, camaraderie, and a sense of community.
Seeking opportunities to mentor and learn from others: Sharing knowledge and expertise with colleagues fosters a culture of learning and strengthens social connections.
Actively participating in discussions and brainstorming sessions: Contributing ideas and engaging in collaborative problem-solving enhances communication, builds trust, and expands the network of connections.
My experience is that software engineers are often introverts by nature (I was once!); therefore getting out there and making friends might seem difficult at first. Fortunately there’s nothing stopping folks from joining groups focused on topics which interest them, or joining meetups to learn new skills.
Understands team strategy
Understanding how the team is going to achieve its goals, and how your actions will help or hinder the team’s success is critical for an effective software engineer.
You should be able to answer these questions:
What are we trying to accomplish?
How do we plan on getting there?
What role do I play in achieving these goals?
How will my actions affect other teams or individuals in achieving their goals?
In a little more detail:
What are we trying to accomplish?
Clearly defined goals provide direction and motivation for the entire team. Understanding the team's objectives allows software engineers to prioritize their tasks, make informed decisions, and align their efforts with the larger purpose.
How do we plan on getting there?
The team's strategy outlines the roadmap for achieving the set goals. Understanding the strategy enables software engineers to identify their place within the plan, assess the effectiveness of their contributions, and adapt their approach as needed.
What role do I play in achieving these goals?
Each member of the team plays a unique(ish) role in contributing to the collective success. Understanding one's specific responsibilities and how they fit into the overall strategy empowers software engineers to take ownership of their work and make meaningful contributions.
How will my actions affect other teams or individuals in achieving their goals?
Software development is a collaborative effort, and individual actions can have ripple effects across the team. Understanding the interdependencies between team members and departments allows software engineers to anticipate potential impacts of their work and proactively address potential conflicts or roadblocks.
Prioritizes appropriately and executes independently
A software engineer who is able to prioritize appropriately and can execute independently is someone you want to keep in your team.
This person understands the direction of the business and can make decisions that align with that. When there are problems, they know how to identify the root cause and come up with a solution that’s best for both minimizing technical debt, enhancing speed of delivery, maintaining quality, and ultimately pleasing customers.
An effective software engineer knows when it’s appropriate to take ownership of tasks and projects, without being told what needs doing by their direct manager. They will also know when it makes sense to draw from their peers to help bear the load and then communicate effectively with other teams.
Thinks long term
Being able to think long term is an important trait for an effective software engineer.
You need to be able to see the big picture and understand how each individual component of your product fits into the overall goals of your company.
Software engineers who can think long-term are better equipped to understand how new technologies will impact their products in the future. They also have a better understanding of what kind of team dynamics and culture they want to create as they continue their development efforts over time.
An effective software engineer understands that trust is built over time through mutual respect and open communication with other members of their team. This type of behavior is essential if you want autonomy from others while still collaborating effectively together on projects that require both creativity and technical skill.
Leaves software projects better than found
If time allows, you should always try to leave a project in better shape than how you found it.
This means leaving the code better, making sure that the documentation is up to date and accurate, and cleaning up the environment so it’s easier for the next person to pick up where you left off, improving your team’s processes and culture over time, and growing yourself as a professional developer by learning more about other languages, technologies, and frameworks that are relevant.
You should also consider how your work impacts not just your immediate colleagues, but everyone in your organization and community. For example: if you’re working on something that will directly impact customers, take extra care to make sure that you are listening carefully to feedback from them during development.
This way, when it goes into production, there should be fewer bugs or other issues than normal, because people don’t know what they don’t know yet!
Is comfortable taking on new challenges
An effective software engineer is comfortable taking on new challenges if organizational requirements change.
I’m a huge fan of having a growth mindset. The ability to adapt and learn new things is an essential part of being a software engineer. As technologies evolve, so do the requirements for your job. If you are not able to grow with your organization, you may find yourself struggling – or worse yet, out of a job.
Being flexible and learning quickly will help ensure that you can adapt when necessary and be ready when the opportunity presents itself for advancement in your career or organization at large.
There are a few benefits to being comfortable taking on new challenges:
Enhanced career growth (potentially): By demonstrating a willingness to take on new challenges, software engineers position themselves for career growth and advancement opportunities. They showcase their adaptability, problem-solving prowess, and ability to step outside their comfort zones.
Expanded skillset and expertise: Each new challenge presents an opportunity to expand one's skillset and expertise. Software engineers who embrace new challenges continuously broaden their knowledge base, making them more versatile and sought-after in the industry.
Increased problem-solving abilities: New challenges often require innovative and creative solutions. By tackling these challenges head-on, software engineers enhance their problem-solving abilities, becoming more adept at identifying, analyzing, and resolving complex issues.
Enhanced Learning and Adaptability: Embracing new challenges fosters a culture of continuous learning and adaptability. Software engineers who regularly step outside their comfort zones become more comfortable with learning new technologies, approaches, and methodologies.
Communicates effectively within the team
Communicating effectively with your team, other teams, and the customer is essential.
This means that you must be able to communicate technical information effectively to your peers and management. If they don’t understand what you’re talking about, it can lead to miscommunication, which may result in bugs or issues that need fixing.
It’s also important to communicate effectively with other stakeholders such as sales or marketing departments. A software engineer should know what their product does, how it works, and why it benefits customers and users, often in a way their managers don’t have time to. When communicating with a customer, engineers should use simple language, and avoid technical jargon.
Let’s cover a few tips for communicating effectively.
1. Tailor your language to your audience
For technical teams: Use precise, technical language but avoid over-complication. When explaining complex concepts, break them down into smaller, understandable components. Use diagrams or code snippets where verbal explanations fall short.
For non-technical stakeholders: Translate technical details into business language. For instance, instead of explaining the technical intricacies of a database optimization, explain how it will improve system performance and user experience.
For customers: Focus on the benefits and functionalities of the product rather than its technical specifications. Use analogies or relate to common experiences to make complex ideas more accessible.
2. Effective email and documentation
Clarity and brevity: Keep emails and documentation clear and concise. Use bullet points or numbered lists to highlight key points.
Contextual information: Provide necessary background information, but avoid overwhelming the reader with details. Link to additional resources for those who want to delve deeper.
Regular updates: Keep all stakeholders informed with regular updates. This can be in the form of a weekly email, a dashboard, or a brief at team meetings.
3. Active listening and empathy
Understand concerns: Pay attention not just to what is said, but also to what is not said. Look for non-verbal cues and read between the lines to fully understand concerns or suggestions.
Empathize: Acknowledge the feelings and perspectives of others. This helps in building trust and encourages open communication.
Feedback loop: Establish a feedback loop where team members feel comfortable sharing their thoughts and know that their input is valued and considered.
4. Effective meetings
Agenda and objectives: Always have a clear agenda for meetings and communicate the objectives beforehand.
Time management: Respect everyone's time by starting and ending meetings on time. Keep discussions focused on the agenda.
Engage participants: Encourage participation from all attendees. Ask for opinions, and make sure everyone's voice is heard.
5. Handling conflicts and difficult conversations
Address issues early: Don’t let conflicts fester. Address them early in a calm and constructive manner.
Focus on the problem, not the person: Keep the discussion focused on the issue at hand, and avoid personal attacks.
Seek win-win solutions: Aim for solutions that are acceptable to all parties involved. Sometimes, this requires creative problem-solving and compromise.
6. Continuous improvement
Seek feedback on communication: Regularly ask for feedback on how you can improve your communication. This can be done during one-on-ones or through anonymous surveys.
Learn from mistakes: Reflect on instances where communication did not go as planned. What could have been done differently? Use these insights to improve future interactions.
Common anti-patterns for software engineering effectiveness
While any good software engineer can master the above skills, there are a few anti-patterns to avoid if you want to achieve true effectiveness.
Hoarding the code – This is when you want to be sure that no one else can touch your codebase and make changes without understanding how it works. If everyone keeps their own code in separate places, then it becomes very hard for anyone else on the team to understand what’s going on with all of them together. While this may seem like a good idea at first, in practice it leads to slower development cycles and makes finding and fixing bugs more difficult.
This is especially problematic if multiple people are working on solving similar problems or building off of each other’s work, because then they might end up with slightly different ideas about how things should work, which leads back into confusion over time.
It also means that there won’t be much sharing between projects, since everyone will probably want their own version control system, instead of relying on some shared tool like git or SVN, where they need access rights set up correctly so others can pull/push changesets onto/from each other’s repositories as needed.
Over helping – If someone asks for help with something related but outside your immediate area of expertise then consider whether or not it would take too much time away from what could otherwise be more productive tasks, such as cleaning up the documentation, debugging existing code, or building new features into existing functionality.
On the one hand this could mean missing out on opportunities where learning new skills could lead into greater job security down the road, but then again it depends what kind of environment you’re working in as to whether these opportunities come along often enough.
Reflections
Effective software engineers are highly-skilled, detail-oriented, and capable of solving complex problems. They have strong technical abilities, excellent communication and collaboration skills, and are able to adapt to new technologies and challenges.
While what is considered effective will vary from one organization to another, many of the traits outlined here are ones I’ve found to be representative of truly effective software engineers.
What do you think makes for an effective software engineer?
This is an expanded version of an article I originally published on LeadDev
If you’re a paid subscriber, I wanted to take this opportunity to sincerely thank you and also provide you with an expanded version of the above article.
What Google research teaches us about effective software engineering teams
Google researchers in Project Aristotle found that there are five team dynamics separate highly effective teams from less effective ones. In order of importance these are: psychological safety, dependability, role clarity, meaningful work and impact.
As an individual contributor on a team, there are a number of things you can do to be an effective software engineer.
First, help foster a psychologically safe environment by being open to sharing your ideas and accepting others for who they are. This means being willing to take interpersonal risks, seeking out different perspectives, and resolving conflicts constructively. You can also encourage psychological safety by modeling vulnerability and admitting mistakes.
Second, be dependable. This means meeting deadlines and delivering high-quality work. It also means being clear about your priorities and communicating with your team about what you're working on.
Third, understand the roles and responsibilities of your team members. This will help you to work together more effectively and avoid duplication of effort.
Fourth, seek out opportunities to contribute to the team and to make your work meaningful. This could involve finding ways to align your work with your interests and passions, or volunteering for projects that you think will have a positive impact.
Finally, be open to feedback and take steps to improve your performance. This could involve asking for feedback from your manager or peers, or reflecting on your own work and identifying areas where you can improve.
By following these tips, you can be an effective individual contributor and help your team to be successful.
Next, what are some traits that can take a software engineer from being effective through to being exceptional?
The hallmarks of an exceptional software engineer
Becoming an exceptional engineer is not solely about their effectiveness or coding skills; it's about their approach to work, their attitude towards learning, and their contribution to the team and the organization at large.
Embracing and driving change: We know that the tech world is in a constant state of flux, and the engineers who excel are those who don't just keep up but lead the charge. They have an innate ability to spot opportunities for improvement, whether it's adopting new technologies, enhancing processes, or devising more efficient solutions to old problems. Saving the business money, especially during economic downturns for example, can be viewed positively.
Balancing technical debt and innovation: Exceptional engineers understand the thrill of building new features, but they also give due importance to managing technical debt. You might be in a unique position to understand this in a way that leadership or business stakeholders may simply not have as much visibility into. They are keenly aware of the need for refactoring, updating, and improving existing code to maintain the system's health and ensure its longevity.
Cultivating a feedback culture: These engineers recognize the power of collaboration and constructive feedback. They don't operate in isolation; instead, they create an environment where sharing ideas and suggestions is encouraged and valued, leading to better overall results.
Commitment to continuous learning: The best engineers are perpetual learners. Their drive to stay updated with the latest advancements in technology, industry best practices, and emerging trends is unyielding. They are not hesitant to explore new languages, tools, or methodologies, even if it means stepping outside their comfort zones. At the same time, they understand that it’s often OK to stick to boring architecture for as long as possible.
Prioritizing team success: While personal achievements are noteworthy, outstanding engineers understand that the success of the team is paramount. They work collaboratively, share knowledge freely, and foster a team culture that is both positive and productive.
Empathy and inclusivity: Technical skills are just one part of the equation. Effective engineers recognize and value different perspectives and work towards creating an inclusive environment. This approach is crucial for collaborative problem-solving and spurring innovation within the team.
Efficient time and priority management: These engineers excel in managing their time and priorities. They know how to balance urgent tasks with important long-term objectives and are adept at saying no when necessary to prevent overcommitment and avoid burnout.
Adaptable communication: Whether explaining complex technical concepts to non-technical stakeholders or guiding junior team members, exceptional engineers can tailor their communication to suit their audience. This adaptability ensures that their messages are always clear and understood.
Demonstrating resilience and perseverance: The journey through software engineering is fraught with challenges and setbacks. The most effective engineers exhibit resilience, learning from their failures, and persistently moving forward, no matter the hurdles.
Leading by example: These individuals set high standards for themselves and serve as role models. From adhering to coding standards and punctuality to showing respect to colleagues, they establish a benchmark for others in the team.
To sum up, the most impactful engineers are more than proficient at coding; they are well-rounded and make substantial contributions to their teams and organizations.
They truly elevate those around them, steering both the team and the project towards success.
It's an effective approach to be used without moderation at See-Docs & Thenavigo.
Define vision (Google Doc), Strategy & Metrics (Cascade), Execute (Team), Evaluate team performance (LinearB).
Thank you for sharing.