2025 01 14 Helplessness
Asking for help is unavoidable as a software engineer. It is easy to become completely stuck, especially when you are working on a new piece of software or with new tools. Much of your professional growth will entail gaining the knowledge required to answer questions posed to you by developers with less experience, and those skills are difficult to acquire without having first asked many questions yourself. That being said, there are good and bad ways to ask for help.
Any time you ask for help, whether you recognize it or not, you are evaluating the set of costs and values of a number of factors:
- What is the value to the business in having the problem solved quickly?
- What is the potential value in finding the solution to the problem without asking for help?
- What is the cost to the business in consuming the attention of the person receiving the question?
- What is a reasonable amount of time to spend preparing to ask the question, in terms of data gathering, etc?
- How will my level of preparedness in asking a question impact my relationships with coworkers?
Obviously, judgement is required in order to balance these questions. We can only develop judgement through experience, which is precisely the thing we’re lacking when we get stuck. You may therefore have difficulty in estimating the values referenced by these questions. That’s OK.
Let’s address each of these factors individually.
What is the value to the business in having the problem solved quickly?
In a crisis, time is the scarcest resource, and therefore the value of any experience you might gain through solving a problem on your own will be expensive to the business. If the business has measures in place to identify subject matter experts, the cost in time for you to identify an expert and ask a question should be sufficiently low that it is worth doing first.
Not all problems are urgent, though. If your manager has given you a task with no specific deadline, the cost in time is likely low enough when balanced against the value of gaining experience and the cost of engaging an SME that the most efficient first step may not be the asking of questions. So if you’re in an obvious crisis, reach out for help first.
What is the potential value in finding the solution to the problem without asking for help?
All clever engineers I have encountered have one thing in common, which is that they enjoy poking around on things that are misbehaving. Taking apart broken devices, looking at the internals, and studying the results of flipping switches or wiggling parts, etc are how we develop an intuition about the logic behind the way things work.
There are often risks related to that tendency which are not obvious. For example an uncle of mine who was an electrician cautioned me not to take apart any televisions or microwaves unless he was around to supervise. I had taken apart plenty of radios and couldn’t fathom why a TV should be concerning, but his advice had always been valuable so I took it seriously. By the time I started taking those things apart he had taught me what needed doing to avoid disaster.
In the software business you could run into trouble through the virtual poking and prodding of a production software component, but any good engineering shop recognizes the danger of such unsupervised troubleshooting and will have some safeguards in place to mitigate that risk – for example, providing development environments that can be poked with reckless abandon.
Test and development environments are sandboxes for the type of play that allow engineers to experiment with software exhibiting bad behaviors, and play is one of the most effective modes of learning at our disposal. Through this exercise you should start to notice that most software systems will have some of the following characteristics that allow you to learn their function and their misbehavior:
-
Some supervisory process which records information about the running status of the component, such as systemd, docker, sysvinit, etc.
-
Some facilities for generating diagnostic output, in the form of logging or telemetry. For example stdout/stderr (possibly sent to the systemd journal or syslog) or dedicated logfiles somewhere on disk.
-
Interactions with the operating system, for example the Linux /proc virtual filesystem with copious data about the state of a running process.
-
Everything involved will have some version. The software in question has a version. The OS distribution has a version, and its kernel version may vary.
-
Tools for interacting with a process in situ, like strace, gdb or bpftrace.
Virtually every technical problem I have assisted developers in solving during my career involved some or all of these facilities. As a result, whenever I encounter a system I have never used and run into issues with it, the first thing I do is to identify where these resources exist (if they do) and then to examine them for anything interesting.
Discerning harmless messages from those that indicate the actual nature of a problem requires experience, so avoid racing to a conclusion based on the first suspicious message you encounter. Instead, collect a reasonable amount of data; for example, log lines five minutes before and after a problem occurs. Even if the problem ultimately stumps you, collecting these resources will dramatically reduce the cost of asking another engineer for help, since they are precisely the same resources the engineer will use to identify the root cause, maximizing the value of both your time spent.
What is the cost to the business in consuming the attention of the person receiving the question?
This is a difficult question to answer, because the value of your colleagues' time varies by the day of the week or the day of the year. As the poser of a question it’s also impossible to predict what the cost in time of answering a given question might be since you may have no idea how complex your problem is.
A safe bet when performing this balancing test is to ask yourself how much time you have personally invested in troubleshooting the problem. For example if you have run your first build of a component resulting in a failure and you have no idea what to do, asking for help is not a logical first step. Alternatively, if you have attempted every troubleshooting method included in the list of five items in the previous section with no results, you may do the business more harm than good by failing to look for outside help.
You must also consider the cost in terms of the attention of your colleagues. During the era in which all employees worked in person at the headquarters, physically walking to a colleague’s space and asking a question was expensive because it required their complete attention to your question. Using the telephone for such questions was almost equally expensive. The use of services like Webex or Slack chat make it easier to engage your colleagues somewhat asynchronously, and email is also still a very viable option.
The best you can do is to balance your own perceived level of urgency against the value of your colleagues’ time. Avoid treating asynchronous chat services like synchronous communication, for example opening requests for assistance with formal salutations like “Hello! How are you?” rather than combining the greeting and the question into a single message which can be answered when it is practical for the subject. Formulate your question, provide all the supporting information as described in the previous section, and be ready to respond to counter-questions.
What is a reasonable amount of time to spend preparing to ask the question, in terms of data gathering, etc?
A phenomenon you will notice as an engineer is that the first responses to your appeals for help tend to be met with appeals for information, and those questions will likely focus on the list of five items in the What is the potential value in finding the solution to the problem without asking for help section above. Those questions-in-response-to-questions serve as a guide for what you should ask yourself before asking others.
For example, error messages emitted in logs are generated by code, and code can be searched, which means that the locations in code where errors arise can be found using tools like grep. These error messages are often composed using string interpolation; for example, an error message like:
Couldn’t find component ‘snarfu’, exiting abnormally
Grepping for Couldn’t find component ‘snarfu’ is going to return nothing, because snarfu is almost certainly a variable that was interpolated into a log message. With this fact in mind, it is never a bad idea when encountering an error message to grep for the shortest pattern that is likely to yield a result, like Couldn’t find component and then to study the code in that area. Or, better yet, to use the toolchains debugger to insert a breakpoint at that line in the code and to inspect the callstack and local variables at the point where the error occurred. If you don’t know how to use the debugger for the language you’re using, now is the time.
Minimally, you should investigate all five items in the list, and you should include everything of interest as part of your question, for example the log lines surrounding the error of interest.
Do not take screenshots of text. Any subject matter expert who will be able to assist you will want to be able to search for substrings in error text, and this is impossible if you post screen captures rather than literal text. Posting literal text to chat applications often requires methods of identifying pre-formatted text, so learn the methods used in your chat application. In both Webex and Slack, single line preformatted text can be marked as preformatted by enclosing it in single backticks, and multi-line text can be delimited with triple backticks.
If you can repeat an error condition on a development environment machine, you should include the coordinates of that machine in your question. If it will be necessary for another engineer to request access to that machine in order to answer your question, be prepared to request the necessary access for them as the onus is on you to do so.
Your question should also describe the troubleshooting steps you have already taken, as this will allow the recipient of the question to bypass steps that you have already performed.
Finally, if you have a theory about why the problem is happening but you’re asking for help, be fully prepared for the subject matter expert to reject your theory. The Dunning-Krueger effect predicts that the lower our level of expertise on a subject, the more faith we are likely to ascribe to our theories about how that thing works. It is tempting to feel that you are ever so close to solving a problem based on your theory of its nature, and then to take offense to the idea that your theory is completely wrong. Anticipate this scenario and maintain a state of open-mindedness toward responses that contradict your theory of the malfunction.
How will my level of preparedness in asking a question impact my relationships with coworkers?
Before saying anything else, I want to address the matter of fear when faced with asking for help. In my opinion it is never appropriate in a workplace to react with anger at being asked for help, but I’m just one of the hundreds of engineers you may work with and I’ve encountered many who don’t share my opinion. I think it is a mistake to allow your fear of being judged or chided by another engineer to discourage you from asking for help when you believe you have exhausted your options. The best approach I know to preventing unpleasant interactions when asking for help is being prepared.
Nothing is more impressive to me as a senior engineering staff member than a well-prepared question from a junior engineering staff member. Such questions are a sign that the junior engineering staff member is likely to be a future capable senior engineering staff member, because they have considered the issues of efficiency described earlier in this essay and recognized the ways they could improve the efficiency of the question-asking process.
If you have ever read or listened to an interview with a celebrity of any type–for example. a musician you admire–you will likely have noticed that the ratio of people to questions is rather lopsided. You will have noticed how many interviews included questions like “What drew you to singing?” Questions of this type are problematic because an adept interviewer will have read many previous interviews of their subject in order to avoid wasting time on questions that have been asked already. Some subjects have been asked the same question so many times that they become annoyed because they are accustomed to encounters with seasoned interviewers.
Asking for help is quite similar to conducting an interview, and there are two principles which should guide you.
If you find value in the responses you receive in your requests for help, you should document them. If your colleague agrees to provide you with valuable information in exchange for nothing, you can repay the favor by recording their responses in a way that allows other members of your institution to find them. This could be blog posts, FAQs, etc.
The other principle is that you should avoid repeating questions. Our institution provides facilities for both subject matter experts and askers-of-questions to document (in a searchable manner) technical questions and answers. If you engage a colleague in a technical question and answer session and leave with an understanding you did not previously possess, you should document it with consideration given to whether others will be able to find the information using a search engine. A few minutes of your time may result in countless hours of time savings for your current and future colleagues who find the knowledge you have captured.
Closing
Asking for help can often feel like laziness, but the ability to enjoy moments of laziness can be earned by a preemptive effort. In more cases than I can count, after having been stymied by some problem for several hours, I would cave and begin preparing a message to one of my colleagues, and the simple act of writing out the detailed explanation I described above resulted in a eureka moment. By imagining the questions I might be asked in response, I looked for the answers to those questions before asking for help and wound up solving the problem without having to ask. After that happened several times, the voices of my colleagues were practically living in my head, having internalized their debugging habits.
Developing your internal flowchart of debugging steps will serve you well as an engineer, particularly in situations where you are the sole SME or are working at odd hours where your colleagues are not available. More importantly, you’ll be able to pass the skills that you learn along to the next generation of developers!