<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alexey</title>
    <description>The latest articles on Forem by Alexey (@lxkuz).</description>
    <link>https://forem.com/lxkuz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F126651%2F4fe26f3f-45ce-4134-bbc9-3f173db73c1f.jpeg</url>
      <title>Forem: Alexey</title>
      <link>https://forem.com/lxkuz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lxkuz"/>
    <language>en</language>
    <item>
      <title>Oh Man, Look at Your API!</title>
      <dc:creator>Alexey</dc:creator>
      <pubDate>Thu, 18 Mar 2021 08:36:09 +0000</pubDate>
      <link>https://forem.com/lxkuz/oh-man-look-at-your-api-1474</link>
      <guid>https://forem.com/lxkuz/oh-man-look-at-your-api-1474</guid>
      <description>&lt;p&gt;Here's my small effort to make the world a little bit of a better place. It could be useful for those of us on the way to building your own super-duper API or who have the patience to improve on an existing one. These tips are based on my own painful experience with APIs I've worked with. Some API made me hate them, others trained my intuition or even helped me developed something like a kind of paranormal ability. Still others made me break down with hysterical laughter. As you can see there's a lot to go over, so let's get started!&lt;/p&gt;

&lt;h1&gt;
  
  
  Good API is boring. No exceptions
&lt;/h1&gt;

&lt;p&gt;You shouldn't try to invent anything new here. The system behavior should be the same everywhere and at every stage. It works for both the principles of API endpoint construction and input/output data formats. You need boring, standard API error messages and request/response headers. Fields with every data type should always have the same output and input formats. All empty fields should look the same. Programming your API process is very similar to lying; the more you have built up around it, the much you (and your clients) have to disentangle later. In other words, the more boring you design an API, the more satisfied your clients will be with it.&lt;/p&gt;

&lt;p&gt;By the way, this advice is good to keep in mind for the design of your whole information system.&lt;/p&gt;

&lt;h1&gt;
  
  
  Documentation
&lt;/h1&gt;

&lt;p&gt;We all know that the most common advice says to document your API but lots of people avoid doing it anyway. While I understand that nobody ever seems to have enough time for these things, it is the face of your API. It might be worth it to put off your much more interesting API coding challenge to invest in writing this documentation. Here are some basic tips for doing it well:&lt;br&gt;
You should offer always working examples of HTTP requests and responses or of actual working code.&lt;br&gt;
Documentation should be formatted as consistently as the API itself.&lt;br&gt;
The foundational principles of your API should be described clearly and in detail.&lt;br&gt;
Use API frameworks such as &lt;a href="https://swagger.io/"&gt;Swagger&lt;/a&gt;, &lt;a href="https://apiary.io/"&gt;Apiary&lt;/a&gt;, or &lt;a href="https://www.postman.com/"&gt;Postman&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember that without good documentation for your super-duper API, using it becomes like piecing together a complicated puzzle.&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Postman API Documentation example:&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlyf323stujvpy5drn0j.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlyf323stujvpy5drn0j.jpeg" alt="Alt Text" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Errors handling
&lt;/h1&gt;

&lt;p&gt;Even if API has poor documentation, it is possible to get quite far relying only on error messages, if they are good. As a rule, accurate and clear error messages really matter to the user experience. Even for API developers, good error messages make you more confident in your work and help you react to errors quickly.&lt;br&gt;
Bad error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Unprocessable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Entity&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Invalid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Attribute&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Unprocessable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Entity&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;application/vnd.api+json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"422"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"pointer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/data/attributes/first-name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Invalid Attribute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The first name must contain min three chars."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Authorization
&lt;/h1&gt;

&lt;p&gt;Every authorization type is useful if it's &lt;strong&gt;STANDARDIZED&lt;/strong&gt;. Please do not mess around with this! Working on authorization processes becomes a real issue if it's unique in some way or is too weak. Take the example of &lt;a href="https://en.wikipedia.org/wiki/OAuth"&gt;OAuth&lt;/a&gt;; it was an API that generated a refresh-token on every access-token update, and also needed access token expiry time. In my opinion, that's too much. First, let your users decide what security level they need and if you can allow non-expiring tokens. Second, keep the processes uncomplicated. Many good APIs use static refresh tokens. Secure is not the same thing as confusing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Data formats
&lt;/h1&gt;

&lt;p&gt;Do not even think about constructing new data formats! I've seen APIs with custom data formats and they always suck. Parsing your unique data format slows work down a lot and makes it a chore to do. Sure, I know it is hard to suppress your creativity when it spills out into these strange ideas, and that these are difficult to throw purely because of your own parental feeling towards your creation, but you must resist. We already have JSON, XML, and all the rest, right? They are enough.&lt;br&gt;
You should take advantage of specifications like &lt;a href="http://jsonapi.org/"&gt;JSON API&lt;/a&gt;. Stripe, Braintree, and lots of other companies are already using it successfully. JSON looks good, has an easy-to-use structured data format, and the JSON API spec is generally well thought out.&lt;br&gt;
Also, please do not support multiple data formats. Customers do not generally care which standard data format they use because all programming languages and technologies already support data formatting and parsing for every standard type. Including multiple formats only slows your API and documentation maintenance down.&lt;/p&gt;
&lt;h1&gt;
  
  
  Use HTTP status codes
&lt;/h1&gt;

&lt;p&gt;It's so much fun! It is very confusing for a developer to get inner API errors with HTTP status 200. This really slows down development. And HTTP status codes can fill the error message role in many cases. Common examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;200 (OK) - success, handle responded data.
500 (Internal Server Error) - something went wrong, ask for API system technical support.
400 (Bad Request) - wrong API request, check the documentation.
401 (Unauthorized) - wrong client credentials, recheck them or if API key token has expired, then refresh.
403 (Forbidden) - unpermitted action, current user does not have enough access rights.
404 (Not Found) - record not found, maybe it doesn't exist anymore or wrong record ID was used.
405 (Method Not Allowed) - this API method is not allowed anymore.
406 (Not Acceptable) - not acceptable action, probably from an attempt to save invalid data.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check &lt;a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors"&gt;Wikipedia&lt;/a&gt; for the rest of the codes and I bet you'll always find a suitable one.&lt;/p&gt;

&lt;h1&gt;
  
  
  Content-type
&lt;/h1&gt;

&lt;p&gt;This is very simple advice. Without any special reason to change it, your content type always should be the same. It helps keep client architecture consistent and accelerates and simplifies the development process. Also, avoid allowing several supported content-types for an endpoint. Developers working with that endpoint could be confused by this. For example, your endpoint "A" works fine but endpoint "B" returns a Bad Request error even though you use it in the same way. Changing your content type doesn't look like an obvious solution.&lt;br&gt;
Object structure&lt;br&gt;
From the client's side of things, it is always very helpful to know what fields the entity actually has. That is perfect if API has a special endpoint that returns a full entity field map. Otherwise, you should at least ensure that you object/list getter returns EVERY field even if it is empty. We don't need dynamism and brevity here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9c7fd1e5-97f0-4b6a-979c-1d7adf5bda16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"firstname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lastname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Smith"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RU"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-03-27T05:40:31.929Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2018-04-08T09:24:39.683Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"citizenship"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Pagination
&lt;/h1&gt;

&lt;p&gt;When I was working on an API connector for a famous CRM system, I realized that it has NO pagination records. When I asked technical support about this, I was told that "unfortunately, we haven't included it, but that's a good idea for implementation." This seemed unbelievable to me. I know that all of you clearly understand why we can't load all of the data at once, so let me explain what pagination is perfect in my view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's useful when you can control pagination page size. It enables users to choose for themselves between the quantity and quality of requests.&lt;/li&gt;
&lt;li&gt;It has meta information to understand how many records summaries we have. In the case of loading all the records, it really helps to understand progress. Also, records counting doesn't require the loading of every page, let's not waste time and money.&lt;/li&gt;
&lt;li&gt;The clear and constant naming of pagination variables, for example: page_number - current page number; page_size - pagination step size; pages_total_count - total count of pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Images and files
&lt;/h1&gt;

&lt;p&gt;This might seem obvious, but you shouldn't include files or image bodies inside responded data. It is much better if you return a temporary upload link.&lt;br&gt;
Time and date&lt;br&gt;
I want to note that it is really important to explicitly specify what time zone we use. It could be part of the time format or just a phrase in the documentation. How to use timezones deserves a separate article of its own, but to keep things simple for now: You can just return date in integer numbers of seconds since the Unix epoch for the time was converted into a UTC timezone. Every client can handle this to correct their format and timezone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="s2"&gt;"created_at"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; 
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt; 
&lt;span class="c1"&gt;#=&amp;gt; { ..., created_at: 1523556863 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Payment plan
&lt;/h1&gt;

&lt;p&gt;You should use HTTP status codes to inform a client when they try to use payment-required endpoints on a free or "not enough paid" plan. Sometimes it is rather difficult to understand what went wrong, and it wastes time to keep fighting with nothing while trying to choose the correct request format. I suggest using the 402 Payment Required HTTP status code here. You can pick any other code you want but it should be clear what is happening. API documentation should have notes about these using conditions as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  API limits
&lt;/h1&gt;

&lt;p&gt;If you programmatically limit request counts in your API, I want to see a clear error message when I have reached the limit. Ideally, there would be a special endpoint with this information. Your customers shouldn't have to calculate API requests count, you already have that information on your end. It's a good idea to render information about available API calls in HTTP Response Headers. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X-RateLimit-Limit - Request limit per hour
X-RateLimit-Remaining - The number of requests left for the time window
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.zoho.eu/crm/help/api/api-limits.html#API_Limit"&gt;Example of API Limits in ZohoCRM&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Logical aspect
&lt;/h1&gt;

&lt;p&gt;While developing your API, a one really good idea is to put yourself in the client's seat. You can find lots of helpful things at an early stage this way. For example, I saw in some APIs that when you delete a record twice, you'll get the same response each time. In my opinion, this is bad because it allows your client to incorrectly believe that they removed it again or removed a different record already. It should return a 404 HTTP status code if the record was already deleted, to help your clients to notice their mistakes.&lt;br&gt;
Another observation about APIs&lt;br&gt;
In my view, if you have strange API endpoints it may be a sign of something really bad in your project design. So instead of diving into creating facades and adapters, take a break and look around. It is very possible that you will see a good opportunity for a refactoring iteration that will kill two birds with one stone: both simplifying your API interface and improving your project structure.&lt;/p&gt;

&lt;h1&gt;
  
  
  Afterword
&lt;/h1&gt;

&lt;p&gt;I want to say huge thanks to all the developers who produce high-quality and easy-to-use APIs. I know that you are very often doing it run by your own conscience and sense of beauty. At first glance, these investments don't give obvious advantages, but I believe they pay off in the long-term effect by growing loyalty of the clients. All the best to the diligent workers behind this difficult task!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>api</category>
      <category>beginners</category>
      <category>backend</category>
    </item>
    <item>
      <title>Deadlift: Showing off Your Strengths in a Job Interview Test Project</title>
      <dc:creator>Alexey</dc:creator>
      <pubDate>Thu, 11 Mar 2021 13:57:52 +0000</pubDate>
      <link>https://forem.com/lxkuz/deadlift-showing-off-your-strengths-in-a-job-interview-test-project-3958</link>
      <guid>https://forem.com/lxkuz/deadlift-showing-off-your-strengths-in-a-job-interview-test-project-3958</guid>
      <description>&lt;p&gt;Hi everyone! In this article, I’m going to touch on the theme of how to get a job. I want to share with you some of the experience I’ve gained along the way as a programmer. This might be useful even if you’re not a developer, as the ideas I will share are really common for many spheres. &lt;/p&gt;

&lt;p&gt;So, you’ve got your CV ready, and somewhere on your LinkedIn profile there’s a list of all the companies that you used to work for - this list might be long or short. But potential employers will probably want to check your experience out for themselves too - in fact, 99% of the time this is going to be the case. For most jobs, there will be multiple stages to the selection process, but in this article, I’m going to speak about the test project part only. Often, recruiters will set a difficult coding task for applicants, to give them a chance to show off their programming skills. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why Should You Trust Me?
&lt;/h3&gt;

&lt;p&gt;I’m not afraid to admit that I’ve had several failed attempts at test projects in the past. After that, I had great feedback for my last five completed test projects, from five different companies. In four cases, I got a job offer as a direct result. So now I understand how to do it right, and I think I can safely say that all my subsequent test projects are likely to be successful as well.&lt;/p&gt;

&lt;p&gt;To be honest, I had some doubts myself about whether my ideas would work for less experienced developers. So, just to be totally sure, I ran an experiment (we all know how important it is to test stuff, right?) I introduced all these ideas to a friend of mine, who is a less experienced developer, before she attempted to solve a test question. She followed my advice, and sure enough, she got the job, thanks in a large part to solving a test project. So I’m sure that there’s value in what I’m talking about here because it’s a tried and tested strategy! &lt;/p&gt;

&lt;p&gt;Alright! I can’t wait to share all that I know on this, so let’s get on with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13a9xrysf4pnlrl85iwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13a9xrysf4pnlrl85iwj.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Read the Task Several Times
&lt;/h3&gt;

&lt;p&gt;You should do this every single time, even if the task looks simple. It’s possible that the task includes some pitfall or hidden information that you might miss, even after a second read. While you’re reading it through, you’ll probably be thinking about implementation already. Don’t get ahead of yourself, though - you’ll have enough time to work it all out. Taking your time is actually a pretty good rule of thumb for most of the future tasks you’ll undertake in your dream job. &lt;/p&gt;

&lt;h3&gt;
  
  
  Wrong Requirements? Make Your Own!
&lt;/h3&gt;

&lt;p&gt;Sometimes while reading the task, you might notice that there are some inaccuracies or even some negligence on the part of the task author. Remember, skewed problems will lead to skewed solutions and you won’t be proud to show off such a solution. So feel free to make some modifications and go in the right direction. This might even be part of the test. Of course, you should logically explain your decision and make it clear that you didn’t just change it because it was too hard for you to do it as originally requested. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa365k4o801n1olqx3dun.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa365k4o801n1olqx3dun.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Read the Vacancy Description Again and Research the Company Thoroughly
&lt;/h3&gt;

&lt;p&gt;You can get a lot of information about the company you’re hoping to work for by reading public sources. You’ll be able to find out what the perfect candidate looks like, what sort of problems they will be solving, and in what particular ways. Very often your test project will be the same sort of thing but in miniature. It means that you should try to make your solution as close as possible to the original one. &lt;/p&gt;

&lt;p&gt;That’s why it’s so important to understand this kind of background information about the company. This knowledge will definitely help you to address some of the questions about base architecture and tech stack picking and makes sure that your answers will be convincing. This way, when your future employer is reviewing your solution, they’ll just exclaim, “This is it!”  &lt;/p&gt;

&lt;p&gt;Let’s take a basic example. If the company you are applying to work for is a huge enterprise, I would recommend that you pick a mainstream stable technologies set, to show you are aware of the importance of using a reliable product. On the other hand, if it's a small startup company, you’d be better off using brand new technologies. This shows that you’re open to using any modern approaches and that you’re adaptable to change, so that they will feel that you’re on the same wavelength as them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Balance
&lt;/h3&gt;

&lt;p&gt;Let’s move on to some advice that is a bit more specialist and focused on programming. Let me share some code examples to show what I’m talking about. &lt;/p&gt;

&lt;h4&gt;
  
  
  University Programming
&lt;/h4&gt;

&lt;p&gt;This is the amateur style of programming that everybody uses when they’re just starting to learn programming. It’s the type of code that is just about good enough to solve the problem, but nothing more. Here is an example on Ruby but I guess everyone will understand what I mean, even if they’re not super familiar with Ruby.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_order_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shipments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coupon&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply_coupon?&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is a straightforward approach to trying to calculate an order summary. It doesn’t follow code style rules, including constants and the ABC metric. We probably all wrote this kind of code when we were trying to solve some programming projects at university. I would suggest that you should never write code like this in your test project. 0% of University programming in your test project&lt;/p&gt;

&lt;h4&gt;
  
  
  Industrial Programming
&lt;/h4&gt;

&lt;p&gt;We could also call this professional programming. Every solution algorithm that springs to mind will initially look like a university-programmed mess. But every professional programmer will rethink the idea and improve it, using best code practices to deliver high-quality code. So let’s briefly try to improve the code of the example above&lt;br&gt;
(FYI I do not pretend that this is the perfect implementation, I just want to show you the way of thinking).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_order_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calc_products_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calc_shipment_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_coupon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;normalize_order_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_products_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_shipment_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;FREE_SHIPMENT_ORDER_TOTAL&lt;/span&gt;
   &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shipments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;apply_coupon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply_coupon?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coupon&lt;/span&gt;
  &lt;span class="n"&gt;coupon_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;coupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;coupon_value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;COUPON_COVERAGE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="no"&gt;COUPON_COVERAGE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;coupon_value&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normalize_order_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully, you can see that this code is much easier to read and understand. It shows every step of the total order calculation, and you can manage the process by modifying constants, values, and concrete logic parts. Your employer is going to prefer this type of code, as it is much cheaper for businesses to maintain and modify. &lt;/p&gt;

&lt;p&gt;One more example of professional programming is the ability to use foreign code components instead of reinventing the wheel. We could have libraries or services available in our system that are already doing all of this, so let’s just use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calc_order_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;products_total&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="no"&gt;CalculateShipmentsTotal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;total: &lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;shipments: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shipments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;order_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ApplyCoupon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;total: &lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;order: &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;NormalizeOrderTotal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this type of code will show your employer how professional and valuable you are as a developer. &lt;/p&gt;

&lt;p&gt;It’s important to strike a good balance between using existing instruments, configuring them, and writing custom code. This part is important, as it shows how good you are as a developer and demonstrates that you can close off regular tasks. It doesn't matter if the task is simple or complex, big or small. This is probably the most important point, as this type of task will make up 90% of your future work.&lt;/p&gt;

&lt;p&gt;Here is the code balance rule: 90% of industrial programming in your test project. What about the remaining 10%?&lt;/p&gt;

&lt;h4&gt;
  
  
  Olympiad Programming
&lt;/h4&gt;

&lt;p&gt;This kind of code will demonstrate just how smart you are. It should include some indication of your wider skills. This might include a strong mathematical background, skills in performance optimization, or the ability to implement beautiful infrastructure solutions. And so on. But don’t go overkill on this. Too much use of olympiad programming code might make the employer think that you’ll use overly complex methods to solve simple tasks, which is bad for business. So the rule is this: 10% of olympiad programming in your test project.&lt;/p&gt;

&lt;p&gt;Sometimes, it’s just not possible for test projects to include any olympiad programming, due to the nature of the task. If that’s the case, you should just write 100% industrial programming code and leave it at that. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferg14n3oqij0g5ursmhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferg14n3oqij0g5ursmhj.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Deadlift Idea
&lt;/h3&gt;

&lt;p&gt;What if the task is too big? Or the task is too small? In weightlifting, you always need to pick the perfect weight to suit your abilities. Bigger is better, but make sure it’s not beyond your capabilities! I would recommend that you follow the same logic when you’re working on the test project. If the task is too big, you can underline the most important elements and implement those with high-quality solutions. If the task looks too simple, you can add some tech magic to show off your professional skills. But be careful! Don’t punch above your weight - you should find the right level and ensure that you can pull it off with a nice technique, using the code balance explained above. &lt;/p&gt;

&lt;h3&gt;
  
  
  Solve the Main Problem
&lt;/h3&gt;

&lt;p&gt;Now you know the list of subtasks you need to solve and you know that you need to research the nuances of the business so that you can easily identify which is the most important part of the test project task. This is the element that you should focus on implementing with the most style. Don’t be afraid to rewrite it a couple of times. &lt;/p&gt;

&lt;p&gt;This part of the code will definitely be reviewed, and its quality is what will reveal your main characteristics as a developer. Sometimes it will include the 10% of olympiad programming that I mentioned, but not always. &lt;/p&gt;

&lt;p&gt;You should be looking to use best practices and classical algorithms in solving these kinds of problems; this will give good results, and make your employers sit up and take notice. You’re saying to them, “Hey! I’m the guy you’re looking for!” This part of the project is very important, so don’t be afraid of skipping some low-priority elements in order to spend more time on this. &lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Commits in Good Shape
&lt;/h3&gt;

&lt;p&gt;Your git history shows your thought process. Inconsistent naming and code changes in your commits reflect a mess in your head. So you should be ready to put a lot of work into your git history. I would say at least 30% of the time you have available for the project should be spent on beautiful code changes in your git history. First commits are about infrastructure changes, project init, and adding in some of the most basic stuff. Then, as you get deeper into solving the problem and move from simple to hard, each commit shows each step you have taken. &lt;/p&gt;

&lt;p&gt;Apart from anything else, your git commits prove it’s your own work. Something to consider is that a long commits list shows your motivation to work in the company - for some employers, this is really important and will help you to stand you out amongst the other candidates.&lt;/p&gt;

&lt;p&gt;You should use conversions like this &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/"&gt;https://www.conventionalcommits.org/en/v1.0.0/&lt;/a&gt; or this &lt;a href="https://seesparkbox.com/foundry/semantic_commit_messages"&gt;https://seesparkbox.com/foundry/semantic_commit_messages&lt;/a&gt; to keep consistent commits messages style.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Code Linters
&lt;/h3&gt;

&lt;p&gt;Write clean, readable, scalable, maintainable, secure code. This is obvious advice, but it’s worth mentioning because it’s so important. The code you write shows the level of your skill, and if you don’t demonstrate the required level to meet the requirements of the job, then you may not pass the test. Use code linters to help you avoid any sloppy moments in your code. This will improve the overall impression that you make on the employer when they’re reviewing your test. &lt;/p&gt;

&lt;h3&gt;
  
  
  Write Tests
&lt;/h3&gt;

&lt;p&gt;Writing tests is important. The way you cover your code with tests shows how professional you are. Enterprise project developers usually spend more time writing tests than writing actual code. So imagine that you’re already working on the enterprise. Cover everything you know how to cover in the right way. I would even recommend using the TDD approach. Actually, I think you should do this anyway, even if it’s not specifically required or requested in the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selectively Fix Bugs
&lt;/h3&gt;

&lt;p&gt;The main usage scenario should 100% work. This is actually good advice for QA specialists as well: do test the positive flow. Don’t waste time on fixing tricky bugs and edge effects. You definitely have more important stuff to work on. P.S. Got issues with bugs? Read &lt;a href="https://dev.to/lxkuz/the-art-of-war-how-to-beat-the-bugs-faster-and-harder-2e4g"&gt;my previous article&lt;/a&gt; ;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28a7b8h8x50t8gok5mjf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28a7b8h8x50t8gok5mjf.png" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Readme Is Important
&lt;/h3&gt;

&lt;p&gt;When you deliver your test project solution, you should be 100% sure that the inspecting person will see the results and will appreciate them. Well-composed Readme is a key factor in achieving this. Here’s a list of things I usually include in the Readme file:&lt;br&gt;
Step-by-step instructions on how to start the project and see the results. I always assume that the checking person is not a programmer at all, so my steps are quite detailed and accurate. Anyone should just be able to blindly follow the steps and get results. After I finish the project, I test all these steps one more time to make sure that they still work. This is good advice to follow, as I can’t remember a single time when I didn’t update some of the steps after that very last check.&lt;br&gt;
I always include a list of the tech stack I’ve used. This helps to highlight some of the better solutions in the project, as I don’t believe that every line of code will be read. So this helps to prevent the scope of the project from being underestimated. &lt;br&gt;
I might mention some of the best ideas and tactics I’ve used. Don’t be shy - there’s no harm in giving yourself a bit of good PR. I also explain any non-transparent solutions, especially if I had any reason to change the test project conditions. Once again, I am pretty much sure nobody will read ALL your code, so when you explain some of these things, it gives a better understanding and helps the reviewer to appreciate the best elements of the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Last Words Before You Go
&lt;/h3&gt;

&lt;p&gt;There are no cast-iron guarantees here I’m afraid. You could follow all the advice above, and still not get the job if there’s someone else even better than you. But there’s always an opportunity for learning. &lt;/p&gt;

&lt;p&gt;This might not work in every scenario, but don’t be afraid to try something new. When I’m doing a new test project, I often use it as an opportunity to try out different things that I’ve always wanted to do but never had the time before. &lt;/p&gt;

&lt;p&gt;I use modern code style approaches that are popular in the tech stack. I make sure I’m familiar with all the latest versions of the programming language and all libs, frameworks and technologies. I use the latest features and read changelogs looking for new stuff to play with and try new ways of solving known issues. That's how I discover new things. And it helps to keep me interested in my work too. &lt;/p&gt;

&lt;p&gt;If you do everything as perfectly as possible, you’ll fall in love with your project. Even if nobody notices it and nobody calls you back, you know that you can be proud of it anyway. Shit happens, but you’ll have no regrets about the project you created. See it as an opportunity for growth, and success will follow! Good luck!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS: Many thanks for illustrations to my friends from &lt;a href="https://pixelpoint.io"&gt;Pixel Point&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>jobs</category>
      <category>interview</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Art of War - How to Beat the Bugs, Faster and Harder</title>
      <dc:creator>Alexey</dc:creator>
      <pubDate>Thu, 05 Nov 2020 09:31:23 +0000</pubDate>
      <link>https://forem.com/lxkuz/the-art-of-war-how-to-beat-the-bugs-faster-and-harder-2e4g</link>
      <guid>https://forem.com/lxkuz/the-art-of-war-how-to-beat-the-bugs-faster-and-harder-2e4g</guid>
      <description>&lt;p&gt;Imagine how much time developers from all over the world spend on dealing with bugs and issues that arise in code. In fact, it might feel like your abilities in this area can define how valuable you are as a professional developer. &lt;/p&gt;

&lt;p&gt;Experienced developers usually end up helping juniors out in difficult code fixes. So, if you’re a junior developer and you feel like you’re always getting stuck and begging your seniors for help, you might be wondering - just how on earth do they do it? &lt;/p&gt;

&lt;h3&gt;
  
  
  What’s The Answer?
&lt;/h3&gt;

&lt;p&gt;The answer here isn’t totally straightforward. You might think that the reason your senior colleagues can help with all your queries is that they have more experience or better debugging skills. But I would say that’s only half the story. The other 50% is all about psychological advantage, for the following reasons:&lt;/p&gt;

&lt;p&gt;You asked ‘em! You’ve shown that you believe in their professional abilities and this positive reinforcement is powerful. This can actually make a person smarter - that vote of confidence gives them a real life intelligence boost. &lt;br&gt;
It’s not their problem, so they don’t have any fear of failure. Without this anxiety, it’s much easier to focus 100% of their brain capacity on finding the actual solution to the problem. &lt;br&gt;
Even though they have nothing to lose, your colleague knows that if they solve the problem, it will give them an added psychological bonus, as you will be in awe of their superiority and high levels of professional skill. &lt;/p&gt;

&lt;p&gt;You see, there’s no stick for them, just a big bunch of carrots. &lt;/p&gt;

&lt;p&gt;Let’s think about some ways that you can grow your own skill set. I’ve tried to pull together here some useful thoughts and ideas that work for me. I believe that reading this list and applying the advice will push your skills forward, until you’re a fine match for those gurus who you usually turn to for help. &lt;/p&gt;

&lt;h3&gt;
  
  
  Do Not Call for Help
&lt;/h3&gt;

&lt;p&gt;This is an incredibly important point that will really help your development. You should ask for help only after you’ve methodically worked through all of the points explained below and you’re still well and truly stuck - and I mean banging your head against the wall kind of stuck. Some of the best growth I’ve ever experienced is when I’ve been in situations where nobody could really help me with my problem. I had no choice but to figure it out by myself. &lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Give in to Hate
&lt;/h3&gt;

&lt;p&gt;Getting emotional is never going to be helpful in resolving bugs. You shouldn’t have bugs you hate. It only makes them more difficult to solve. Every bug is a great opportunity to hone your skills, so it’s much better to try to learn to love them all. &lt;/p&gt;

&lt;h3&gt;
  
  
  Do You Believe in Magic?
&lt;/h3&gt;

&lt;p&gt;I believe that if you’re really stuck on a debugging problem for a long time, this is likely to be at least 50% for psychological reasons, or maybe even more. &lt;/p&gt;

&lt;p&gt;A voice in your head says, “It can’t be like this! It must be black magic!” You feel as if the world has gone mad, and it can’t possibly be your fault. You feel like all you can do is run away from the problem. &lt;/p&gt;

&lt;p&gt;Don’t listen to this voice! Everything in code always happens for a reason! There’s no black magic breaking your code, and I’m sorry to break it to you, dude, but there’s no magic wand to fix it either!  You just need to find the specific line of code that’s working in the wrong way, and fix it. Simple. &lt;/p&gt;

&lt;h3&gt;
  
  
  Read the Error
&lt;/h3&gt;

&lt;p&gt;Please don’t just copy and paste the error into Google or Stack Overflow straight away. You should take the opportunity to learn something from every bug and develop your skills - this is particularly important when you’re stuck with a difficult bug to fix. &lt;/p&gt;

&lt;p&gt;It’s best to carefully read the error and try to understand the process. Often the reason for the error is right there in front of you - you just need to look at it properly. &lt;/p&gt;

&lt;h3&gt;
  
  
  Read the Code
&lt;/h3&gt;

&lt;p&gt;Don’t panic. Usually, the code is already telling you what is wrong. What’s the worst thing that can happen? You waste a bit of time reviewing the code and you don’t find the answer. &lt;/p&gt;

&lt;p&gt;But actually, that time won’t be wasted, because you will know more about the project. Until you are 100% familiar with it, there’s always work to be done. Plus, it’s always helpful to practice your code reading skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Army Rule
&lt;/h3&gt;

&lt;p&gt;This simple rule was told to me by an air defense officer during military training. When you service a complex piece of machinery and something goes wrong, or is not functioning in the same way as it used to, you should focus your attention on the modules that you worked on in the latest fix or check.&lt;/p&gt;

&lt;p&gt;This is 100% applicable to programming as well! So you need to look at any piece of code that was updated or fixed recently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Achieve Instant Bug Replay
&lt;/h3&gt;

&lt;p&gt;When you realize that the issue is hard and you’re going to need to do a lot of tests, you should pause for a while in order to improve the testing process. In a perfect world, your bugfix checking process would be totally automated. &lt;/p&gt;

&lt;p&gt;If you can figure out a way to recreate the error more quickly, then you can test multiple solutions much more efficiently. This will help you to concentrate on the problem and find a rapid fix. You can even temporarily simplify existing code logic to make every test much faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deductive Reasoning
&lt;/h3&gt;

&lt;p&gt;I found out about this approach from a school physics tournament called SYPT. This method is used in scientific research and can also be used to resolve hard programming issues. So here is the science approach: &lt;/p&gt;

&lt;p&gt;1) Inspect the process and observe what is happening.&lt;br&gt;
2) Try to formulate a theoretical explanation for what’s going on. Define all the possible factors that could be causing the problem.&lt;br&gt;
3) Then you should check these theories one by one, starting with the one that seems to be the most plausible. Make sure you are asking the right questions. Every check should encapsulate the essence of the problem. Do not test several theories at once. This will interfere with the full picture and won’t lead you to the right conclusions.&lt;/p&gt;

&lt;p&gt;Every reason or theory should be either proved or rejected by the test results. These same principles can be applied to solving complex bug problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5l4y8hi1r8hriew5qkx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5l4y8hi1r8hriew5qkx2.png" alt="Rubber Duck Debugging" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rubber Duck Debugging
&lt;/h3&gt;

&lt;p&gt;This is a famous method, based on the story of a programmer who used to carry a rubber duck around and force himself to explain the coding problem to the duck. This would help him to unlock the problem. &lt;/p&gt;

&lt;p&gt;Sometimes I find myself telling somebody about a bug, even though I know that they won’t be able to help me at all! But it’s useful, just the same. Often I discover the right solution while I’m talking. When you’re trying to talk someone through the issue, your mind is organizing it and putting it into the right order to be explained. Sometimes this can be just what you need to unlock the next logical steps that you need to take.&lt;/p&gt;

&lt;p&gt;I know that this seems in conflict with the previous advice, Do Not Call for Help, but this is a fallacy. The Rubber Duck method makes you work harder to solve the problem yourself. It’s definitely not a sign of madness here to talk through the problem with people, animals, plants or even inanimate objects like the famous rubber duck.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Code Bisect
&lt;/h3&gt;

&lt;p&gt;This is the best rule! It works even if you don’t completely understand what is happening in a huge piece of code. I guess you might have got the point from the title already, but let me explain it in more detail anyway. Let's say to start off with that the code is falling, but the reason is unclear. &lt;/p&gt;

&lt;p&gt;You can bisect the code by commenting out a section of it, then repeating the check. If the error has disappeared, then you know that it was in the part of the code that you commented out. If not, then you repeat the process with other sections of code. &lt;/p&gt;

&lt;p&gt;The problem will be in one exact line, and you need to repeat the test until you isolate the piece of code where the problem is. &lt;/p&gt;

&lt;p&gt;Of course, you have to inspect the whole code to fully understand it and make decisions to prevent the error, but it’s much faster if you don’t have to read all of the suspected code when you’re looking for the error itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error on PROD!
&lt;/h3&gt;

&lt;p&gt;Ok, first thing’s first - don’t panic! Panicking won’t help to resolve the problem quickly. Here’s what you can do instead to handle production errors - ask yourself this question before doing anything else: &lt;/p&gt;

&lt;p&gt;Can I reproduce the error on my local? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;YES? All good, let’s debug it and understand the reason for the problem. Fix, deploy, go home, kiss your wife (your own wife, please!)&lt;/li&gt;
&lt;li&gt;NO? You know, people tend to freak out when something is OK locally but fails on production. I would say, let’s try to see both the negatives and the positives in this situation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This challenge already gives us some clues as to how to find a solution. What is the difference between the local and production environments? Possibly we have a different configuration or different web server settings, or some other issue that could be applicable to the problem. It’s mostly a matter of logic. &lt;/p&gt;

&lt;h3&gt;
  
  
  Slow and Steady Wins the Race
&lt;/h3&gt;

&lt;p&gt;Even if you need to fix something ASAP, it does not mean you should test your fix straightaway on production! I can’t tell you how many times I’ve seen double or even triple deployments having to take place, all because of some stupid typo during the hotfixing. Check local tests and try to keep high code quality. One gradual fix with one deploy is better than three hotfixes with three deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvo8hyuo4z361cqiggeu7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvo8hyuo4z361cqiggeu7.png" alt="Carry Some Blue Duct Tape" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Carry Some Blue Duct Tape!
&lt;/h3&gt;

&lt;p&gt;Imagine that you’re working on a particularly painful bug. The company is losing money right now because of this problem. You’ve discovered the reason for the bug, and realized that the fix would be a huge piece of work and would obviously require extra unit testing and so on. What should we do in situations like these? &lt;/p&gt;

&lt;p&gt;Let’s work to provide some possible temporary hotfix. It’s ok if it’s not perfect, but it needs to be fast and to prevent the company from losing more money while you’re working on the definitive solution. &lt;/p&gt;

&lt;p&gt;If some new feature that we’re trialling is buggy, we can roll it back first to protect the main process. So we can just apply the stable version of the code while we take our time in figuring out how to fix the bug properly. &lt;/p&gt;

&lt;h3&gt;
  
  
  Flaky Tests
&lt;/h3&gt;

&lt;p&gt;Sometimes your CI shows failing tests for no reason, even if they aren’t failing on your local interface. These kinds of test failings are a separate theme for a separate article… or even a book. &lt;/p&gt;

&lt;p&gt;The reason for failing is definitely the order in which your tests are running. But even if you know the right order, that’s not necessarily the answer, as you can have thousands of tests running and it’s impossible to even identify which exact test is the reason for the failure. &lt;/p&gt;

&lt;p&gt;Some testing tools (such as ruby rspec) have smart bisect functionality that helps to minimize the number of tests involved in the count. However, this can be a really slow process and will not necessarily give a definitive result. &lt;/p&gt;

&lt;p&gt;So it’s better to read the issue and recognize what common resources have been touched before the test that has affected it. Then you can predict what tests are the reason for the failure. After that, all you need to do is run target tests in the right order to prove your theory. &lt;/p&gt;

&lt;p&gt;Yeah, I know this sounds like a hard process, but the fixing of such tests always leads to an improvement in their structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: How To Write Code Without Bugs?
&lt;/h3&gt;

&lt;p&gt;I don't want to brag, but these days my code has a lot fewer bugs than it used to have. I learned to be more attentive and compose correct code structures with good architecture that will force bugs to surface. You most likely won’t face so many or such serious bugs if you understand the process at a very high level and in a lot of detail.&lt;/p&gt;

&lt;p&gt;Your own brain can function in the same way as your programming code runner. Apart from that, I try to use TDD and end-to-end testing if there is enough time. It’s impossible to avoid 100% of bugs, but you can decrease the number of bugs significantly by working in this way. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Final Words
&lt;/h3&gt;

&lt;p&gt;Try to enjoy your bug fixing! Maybe to start with, it feels less satisfying than writing new code, but it has its own advantages. &lt;/p&gt;

&lt;p&gt;For instance, some hard bugs will turn you into a true detective and you will really enjoy the thrill of the chase when you’re on the right path. &lt;/p&gt;

&lt;p&gt;So, the harder the bug, the more pleasure you will get when you win! Thank you for reading! And good luck beating those bugs! &lt;/p&gt;

&lt;p&gt;PS: Big thanks for illustrations to my friends from &lt;a href="https://pixelpoint.io"&gt;Pixel Point&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
