<?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>DEV Community: Gerard</title>
    <description>The latest articles on DEV Community by Gerard (@geclos).</description>
    <link>https://dev.to/geclos</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%2F232648%2Feec32f5b-5d7c-4458-aaed-5ce933795457.jpeg</url>
      <title>DEV Community: Gerard</title>
      <link>https://dev.to/geclos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geclos"/>
    <language>en</language>
    <item>
      <title>Write Faster SQL With AI</title>
      <dc:creator>Gerard</dc:creator>
      <pubDate>Wed, 01 Feb 2023 15:24:40 +0000</pubDate>
      <link>https://dev.to/geclos/write-faster-sql-with-ai-54aa</link>
      <guid>https://dev.to/geclos/write-faster-sql-with-ai-54aa</guid>
      <description>&lt;h2&gt;
  
  
  Act today, not next quarter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://latitude.so"&gt;Latitude&lt;/a&gt; was born with a clear focus: help companies extract value from data by improving the way you interact with it. Our team has worked (and struggled) with data for years now, and we are aware of the day-to-day challenges and issues that technical teams have been facing when it comes to working with data.&lt;/p&gt;

&lt;p&gt;Different spreadsheet versions, manually connecting databases, fragmented data, building and maintaining pipelines, crashed BI reports, never-ending requests in queue… you name it. All of these scenarios make getting value out of data incredibly slow and inefficient.&lt;/p&gt;

&lt;p&gt;We firmly believe that the biggest value of data interaction comes from how fast you can answer a question with reliable data. People at companies need to make decisions. Based on data. Today. Not next quarter.&lt;/p&gt;

&lt;p&gt;Data “duties” end up more often than not at the Tech team’s table. And developers are busy with guess what… making sure the roadmap is happening and that all systems are up and running. It’s hard to navigate this sea of changing priorities and make sure that everything works fine.&lt;/p&gt;

&lt;p&gt;That’s why any major improvement in the data process can save tons of dev resources and accelerate the decision-making inside an organization. And today, Latitude is happy to announce a major one with our new SQL AI Assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the new AI SQL Assistant
&lt;/h2&gt;

&lt;p&gt;We get it. Every other day, a new AI-based product comes from nowhere with the promise of “revolutionizing the way you do X or Y”. But in this case, it’s true. If you’ve been using Github Copilot for the last few months, we bet that you’ll be using this one too.&lt;/p&gt;

&lt;p&gt;Some CTOs or Engineering Leads are not writing SQL queries every day. Some people in Product or Marketing know a few SQL functions here and there but they are not fluent. In all of these cases, data exploration takes longer than expected. But now, with our new AI SQL Assistant, these processes will be faster.&lt;/p&gt;

&lt;p&gt;Latitude’s AI SQL Assistant uses Open AI’s GPT-3 Models to suggest code and entire SQL functions in real-time, based on your prompts and right from your data project canvas. Let’s see some examples of what you can achieve with it.&lt;/p&gt;

&lt;p&gt;You need to filter the records on one of your tables by score, but you don’t feel like typing the whole query:&lt;/p&gt;

&lt;p&gt;Or let’s say you have a table with your Net Promoter Score data, and you want to quickly calculate the average score. Just ask our AI Assistant and the query will be there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---g2f-LSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1o9iomt7fpr6mkdxlk2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---g2f-LSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s1o9iomt7fpr6mkdxlk2.gif" alt="demo" width="880" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From zero to insight in minutes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Sign up for an account
&lt;/h3&gt;

&lt;p&gt;You can sign up and &lt;a href="https://latitude.so/"&gt;try Latitude&lt;/a&gt; without any commitment. It’s completely free, and no credit card is required. As simple as that.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Connect your Data Sources
&lt;/h3&gt;

&lt;p&gt;Latitude connects to your database, data warehouse, and other data sources such as Google Sheets or your CRM. More than 100 data sources are supported.&lt;/p&gt;

&lt;p&gt;The cool thing is that you can join multiple data sources in the same data exploration. Let’s say you want to create a table that merges data from your production database in PostgreSQL and your Hubspot CRM. That’s possible with Latitude.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Start exploring your data
&lt;/h3&gt;

&lt;p&gt;With Latitude, teams can unlock the power of data through our AI SQL Assistant, manually writing SQL queries and visual programming on an infinite canvas.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Visualize your data
&lt;/h3&gt;

&lt;p&gt;At Latitude, explore and visualize data simultaneously in one convenient place. Pick between charts or tables to add them directly to your canvas for effortless integration. Now your organization can start making the right decisions and moving forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;We are barely scratching the surface of the possibilities of AI applied to data exploration and analytics. Our team is working hard on finding and developing new ways to use artificial intelligence in this landscape, so you can benefit from it and spend your time where’s most convenient.&lt;/p&gt;

&lt;p&gt;At the end of the day, we keep thinking about the following question: What can we do so our users are able to answer questions with reliable data faster than ever before? And also they can do it without spending huge dev resources and time in the process.&lt;br&gt;
That’s our commitment, so stay tuned to see upcoming developments with AI in SQL from Latitude. And we are always open to getting feedback from our users.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://latitude.so/"&gt;try Latitude&lt;/a&gt; today completely free and reach out to us &lt;a href="https://p6w2fhp8xzy.typeform.com/to/jlIyoaE7"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>gpt3</category>
      <category>ai</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Why most developers fail their first tech interviews</title>
      <dc:creator>Gerard</dc:creator>
      <pubDate>Mon, 11 May 2020 07:32:50 +0000</pubDate>
      <link>https://dev.to/factorial/why-most-developers-fail-their-first-tech-interviews-28jn</link>
      <guid>https://dev.to/factorial/why-most-developers-fail-their-first-tech-interviews-28jn</guid>
      <description>&lt;p&gt;In the last 4 years interviewing candidates for development roles, I've come to realize the cohort with the highest rejection rate is applicants to entry-level positions.&lt;/p&gt;

&lt;p&gt;What pains me to see is that most of them fall off the recruitment funnel for the simplest of mistakes, which often have nothing to do with their professional skills and could easily be avoided. These aren't failures of skill, but of communication.&lt;/p&gt;

&lt;p&gt;In this post, we will go over the developer recruitment process at&lt;br&gt;
&lt;a href="https://factorialhr.com"&gt;Factorial&lt;/a&gt;, mostly as an excuse for me to explain what is it that makes so many entry-level candidates flop their interviews, and how you can avoid it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The process
&lt;/h2&gt;

&lt;p&gt;The recruitment process is simple: two interviews, one more generic &lt;em&gt;let's-meet&lt;/em&gt; type of interview, and another more technical. After the second meeting, you&lt;br&gt;
either get rejected or get a job offer.&lt;/p&gt;

&lt;p&gt;The first meeting is mostly innocuous: an opportunity for us and the candidate&lt;br&gt;
to assess whether we are a good match. The only piece of advice I can give you&lt;br&gt;
at this point is to be honest, not be a jerk and ask as many questions as you&lt;br&gt;
can. Ideally, you want to leave this encounter convinced whether you want this&lt;br&gt;
job or not. We will answer almost any question you might have, and you should be&lt;br&gt;
wary of any company that isn't willing to do the same.&lt;/p&gt;

&lt;p&gt;Once introductions have been made, you will be asked to submit a take-home&lt;br&gt;
exercise that will require you to write a representative chunk of your own&lt;br&gt;
code. If you are prolific enough, we will gladly accept another program you&lt;br&gt;
might have already developed. The second interview basically consists of you&lt;br&gt;
going through your own code with some devs from our tech team. You'll get asked&lt;br&gt;
technical questions about your submission and some more general aspects, if the&lt;br&gt;
conversation takes us down that path.&lt;/p&gt;

&lt;p&gt;The purpose of this exercise is many-fold, from evaluating general technical&lt;br&gt;
abilities to assessing reasoning capabilities but, mostly, the purpose of this&lt;br&gt;
exercise is to evaluate how well would you do the job we want you to do.  Most&lt;br&gt;
of these aspects are correlated, but if you fail at the latter you won't get&lt;br&gt;
hired.&lt;/p&gt;

&lt;p&gt;This is, unsurprisingly, where most candidates flop. Let's see why.&lt;/p&gt;
&lt;h2&gt;
  
  
  All candidates look alike
&lt;/h2&gt;

&lt;p&gt;Truth is, for entry-level positions, there's little variance in the candidates'&lt;br&gt;
technical skills.&lt;/p&gt;

&lt;p&gt;We get candidates with brilliant exercises that cannot defend it accordingly&lt;br&gt;
during the interview, candidates with lesser code that fair rather well during&lt;br&gt;
questioning, candidates obsessed with CS theory, others more of the&lt;br&gt;
learn-as-you-go type, variant degrees of experience, creativity,&lt;br&gt;
resourcefulness... In the end, all these aspects average out, painting the&lt;br&gt;
portrait of the default entry-level applicant who is capable of writing a fairly&lt;br&gt;
decent program involving frontend and backend code, sometimes with some extra&lt;br&gt;
sprinkles of infrastructure code on top.&lt;/p&gt;

&lt;p&gt;Put another way, statistics say that if you made it to the tech interview portion&lt;br&gt;
of the recruitment process you probably have the technical skillset required to get&lt;br&gt;
hired. This won't always be the case but, generally, the rule holds true.&lt;/p&gt;

&lt;p&gt;Now, if all candidates look alike, what is it that distinguishes them apart? What&lt;br&gt;
makes recruiters pick one over the many others?&lt;/p&gt;

&lt;p&gt;I'm convinced it's communication. More specifically, &lt;strong&gt;knowledge communication&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The success of a tech candidate is a function of their knowledge and how well&lt;br&gt;
they can communicate said knowledge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given that we have established most junior candidates have similar technical&lt;br&gt;
knowledge and that, unsurprisingly, most developers suck at communicating, you&lt;br&gt;
can see how this ends up with a high rejection rate of entry-level applicants.&lt;/p&gt;

&lt;p&gt;Let's explore further this notion of knowledge communication, and see how you can&lt;br&gt;
exploit it to improve your odds at your next tech interview.&lt;/p&gt;
&lt;h2&gt;
  
  
  Know your code
&lt;/h2&gt;

&lt;p&gt;Mind you, when I speak about communication I'm not implying you can talk your&lt;br&gt;
way through the recruitment process and end up at a cushy dev job with no&lt;br&gt;
technical skills to show for. At the tech interview, the beans will get spilled&lt;br&gt;
and your knowledge boundaries will be put to bare. Knowledge communication&lt;br&gt;
requires, well, knowledge; You have to do the work and learn your computer&lt;br&gt;
&lt;em&gt;sciency&lt;/em&gt; stuff first.&lt;/p&gt;

&lt;p&gt;Problem is, often developers spread their knowledge surface large and thin,&lt;br&gt;
sometimes too thin. They learn from repetition, which leads to a lack of&lt;br&gt;
understanding, which results in poor knowledge communication.&lt;/p&gt;

&lt;p&gt;Let's say you, as a candidate, learn about the new fancy framework &lt;em&gt;du jour&lt;/em&gt;,&lt;br&gt;
follow its documentation examples and, with today's tools, you quickly get a&lt;br&gt;
pretty decent app up and running. You already look like 99.9% of the other&lt;br&gt;
candidates. You even got &lt;em&gt;professional&lt;/em&gt; stuff out of the box: JSON Web Token&lt;br&gt;
authentication, cross-site scripting protection, WebSocket support, and whatnot.&lt;br&gt;
You start feeling confident and end up submitting an exercise that contains code&lt;br&gt;
that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;protect_from_forgery&lt;/span&gt; &lt;span class="ss"&gt;unless: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json?&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;This is the candidate's code. If I &lt;code&gt;git blame&lt;/code&gt; it, their name will show up. And,&lt;br&gt;
yet, most entry-level candidates have but a vague idea what this code does.&lt;br&gt;
The result is candidates communicating their lack of knowledge about their own&lt;br&gt;
code. They cannot answer &lt;em&gt;what&lt;/em&gt; their software does and, what's worse, &lt;em&gt;why&lt;/em&gt; it&lt;br&gt;
does it.&lt;/p&gt;

&lt;p&gt;You have to know your code.&lt;/p&gt;

&lt;p&gt;To tackle this issue, I recommend candidates take a much more deliberate&lt;br&gt;
approach and think in terms of knowledge communication. If you are an applicant,&lt;br&gt;
run over every line of your exercise before you submit it and ask yourself: "Can&lt;br&gt;
I explain this line of code?". This will immediately beg questions about the&lt;br&gt;
&lt;em&gt;what&lt;/em&gt;, &lt;em&gt;why&lt;/em&gt;, and &lt;em&gt;how&lt;/em&gt; of every piece of your program you didn't really grasp,&lt;br&gt;
deepening your knowledge.&lt;/p&gt;

&lt;p&gt;What's more important, this approach will set you down a path of reinforced&lt;br&gt;
learning: Discovering how XSS protection works will take you through HTTP&lt;br&gt;
headers, the different types of HTTP verbs and codes, maybe you'll understand&lt;br&gt;
how your framework uses JWTs to manage your users' sessions and what this pesky&lt;br&gt;
CORS error is all about.&lt;/p&gt;

&lt;p&gt;At this point, you will arrive at the tech interview with knowledge not only on&lt;br&gt;
how to build a program with a particular framework, but on how the underlying&lt;br&gt;
infrastructure of the internet works to support the many features your framework&lt;br&gt;
provides and your app makes use of. You will be able to communicate your&lt;br&gt;
knowledge about your code and even respond to some extra curveballs the&lt;br&gt;
interviewer might throw at you. Your skills will be immediately more&lt;br&gt;
transferable, as all frameworks rely on the same underlying infrastructure.&lt;br&gt;
You'll be a better engineer.&lt;/p&gt;

&lt;p&gt;Sadly, you won't be able to answer everything, since the purpose of the tech&lt;br&gt;
interview is precisely to test the limits of your knowledge, so let's see what&lt;br&gt;
you can do about that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum: Other examples of poorly understood code I often encounter are JWTs,&lt;br&gt;
OAuth, Polymorphism, db indexes &amp;amp; foreign keys, HTTP basics, React component&lt;br&gt;
lifecycle methods, JS Promises, async/await &amp;amp; generators. You don't need to know&lt;br&gt;
all of these but, if it's in your code, you should.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Know your unknowns
&lt;/h2&gt;

&lt;p&gt;If you follow the aforementioned prescription, you'll quickly reach the second layer of your &lt;a href="https://fs.blog/2013/12/circle-of-competence/"&gt;circle of competence&lt;/a&gt;: things you know you don't understand very well.&lt;/p&gt;

&lt;p&gt;For example, you might feel brave and make use of the new &lt;code&gt;useEffect&lt;/code&gt; hook from React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CatCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`I have counted &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cats so far!`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;useEffect&lt;/code&gt; is hard — otherwise, its creator wouldn't have written a&lt;br&gt;
&lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/"&gt;gazillion-line blog post&lt;/a&gt; about it — and you probably don't understand very well why you have to put that empty array as a second argument. You know, though, that if you don't the counter does not seem to refresh with every new cat you pass it as an argument. You have a thin knowledge of this piece of your code, and this is a problem.&lt;/p&gt;

&lt;p&gt;As a rule, do not try to hide your knowledge gaps in code. You'll open&lt;br&gt;
yourself to getting a question you will be playing guessing games against.&lt;br&gt;
Instead, simply admit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CatCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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="c1"&gt;// NOTE: I am not sure why I need this second argument but otherwise the&lt;/span&gt;
  &lt;span class="c1"&gt;// component does not seem to update on prop updates. Need to investigate.&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`I have counted &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cats so far!`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Communicating a lack of knowledge is also knowledge communication.&lt;/p&gt;

&lt;p&gt;You are admitting your knowledge gap, implying you know this is a problem but had to move on with it, and announcing your intention to fix it. It shows self-awareness, curiosity and the drive to improve; the kind of potential we look for in candidates at this level. It’s not a simple “I don’t know”, which would be lazy, it’s a reasonable utilitarian argument that tacitly admits failure of understanding.&lt;/p&gt;

&lt;p&gt;At this point, the interviewer can do little more than ask if you had time to follow on your investigation which, given the circumstances, is an excellent outcome.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum #2: Of course, if your exercise contains many comments like these you should reconsider whether you are ready to apply for the job. Nevertheless, do not be afraid to admit gray areas in your understanding.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Most entry-level candidates are very similar, and it’s highly unlikely you’ll be the exception. Instead, focus on deep knowledge vs thin understanding, specially about those concepts you know you might get questioned about. If you can, don’t answer only with “I don’t know” but don’t play guessing games either, state your knowledge gaps, what you think you know about them, and how you plan to improve on these gray areas.&lt;/p&gt;

&lt;p&gt;There are many more aspects we could explore in preparation for your first tech interviews, but these are the foundational aspects all candidates should be aware of. The rest, we'll explain in upcoming entries.&lt;/p&gt;

&lt;p&gt;Cheers, and good luck in your next interview.&lt;/p&gt;




&lt;p&gt;This post originally appeared at &lt;a href="https://gerardclos.com"&gt;https://gerardclos.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>developers</category>
      <category>codenewbie</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>A set of programming aphorisms at Factorial</title>
      <dc:creator>Gerard</dc:creator>
      <pubDate>Wed, 15 Apr 2020 09:33:54 +0000</pubDate>
      <link>https://dev.to/factorial/a-set-of-programming-aphorisms-at-factorial-3j0m</link>
      <guid>https://dev.to/factorial/a-set-of-programming-aphorisms-at-factorial-3j0m</guid>
      <description>&lt;p&gt;At &lt;a href="https://factorialhr.com/"&gt;Factorial&lt;/a&gt;, we maintain an engineering Handbook where we document aspects such as common abstractions, programming principles and documentation of our architecture.&lt;/p&gt;

&lt;p&gt;Among these, there are a set of aphorisms stemming from coding best practices and common pitfalls we have been encountering during the last 4 years building our product. Let's share some of these.&lt;/p&gt;

&lt;p&gt;Beware, these aphorisms are language-agnostic and, thus, you might find them more or less regularly in your day to day depending on the characteristics of your preferred programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depend on contracts rather than data structures
&lt;/h2&gt;

&lt;p&gt;This is my personal favorite because it's so simple yet so ubiquitous. Put&lt;br&gt;
bluntly, data structures make for &lt;a href="https://dev.to/factorial/some-reasons-to-avoid-hashes-in-ruby-and-some-alternatives-to-them-3j7n"&gt;lousy interfaces&lt;/a&gt;: they are often opaque, mutable and nullable, all characteristics you wouldn't want for an interface — and yet we use them as such constantly.&lt;/p&gt;

&lt;p&gt;The most common example is accepting a hash as a method argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:foo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:bar&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# This can print something, null or raise an unexpected error.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: This is especially prevalent in languages that make it easier to work with data structures and nullables such as Ruby or Javascript.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Using a data structure introduces an implicit dependency between your method and the data structure's shape, a dependency that could have been easily avoided by simply passing the expected value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;bar: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="c1"&gt;# This can print something or null&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In cases where the dependency with the data structure cannot be avoided, isolate it behind an API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;HashAccessor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This can print something or null&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HashAccessor&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hash&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Although this might come across as a superfluous refactor it minimizes the spread of the dependency and paves the way for a future refactor in which we would get rid of this data structure dependency altogether.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid null values
&lt;/h2&gt;

&lt;p&gt;Hardly a surprise. All the new &lt;a href="https://www.rust-lang.org/"&gt;cool kids&lt;/a&gt; in the block are using it.&lt;/p&gt;

&lt;p&gt;The problem with null values was already hinted at in the previous aphorism: it's a very hard contract to enforce. This will result in errors happening far away from the underlying issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
&lt;span class="no"&gt;ROLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;admin: &lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;manager: &lt;/span&gt;&lt;span class="s1"&gt;'manager'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ROLES&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="nf"&gt;role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;user_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# user_presenter.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'Admin'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;ROLES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="no"&gt;ManagerRolePresenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# manager_role_presenter.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;manager_role_presenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; – Lead"&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;&amp;lt; Unexpected `capitalize` message for `nil`! This is very far from the origin of the `nil` and hard to fix&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To avoid null values you can enforce types (if your language supports it), implement the &lt;a href="https://doc.rust-lang.org/std/option/"&gt;optional pattern&lt;/a&gt;, use a custom contract with data validation (such as a Struct) or directly raise an exception closer to the null source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code should be &lt;em&gt;greppable&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Or, put another way, do not be too smart for your own good.&lt;/p&gt;

&lt;p&gt;As a rule of thumb, your teammates should be able to easily navigate your code using only a pattern-matching tool like &lt;code&gt;grep&lt;/code&gt; (or &lt;code&gt;ctrl-f&lt;/code&gt; for those using fancier editors).&lt;/p&gt;

&lt;p&gt;If that weren't the case it probably means your code is not explicit enough and is hiding dependencies with dangerous techniques like meta-programming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Jon&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Snow&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# main.rb&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;
    &lt;span class="s2"&gt;"Jon::&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;constantize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;# This can blow up&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As if the potential error wasn't bad enough, this technique obfuscates the&lt;br&gt;
author's intention and makes navigating your code more difficult than necessary.&lt;/p&gt;

&lt;p&gt;To avoid these pitfalls and improve code quality make extensive use of &lt;a href="https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis"&gt;static analysis tools&lt;/a&gt;&lt;br&gt;
such as linters or static type analysis.&lt;/p&gt;

&lt;p&gt;In the particular case of meta-programming, replace it with a good ol' Map or switch statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depend on abstractions rather concretions
&lt;/h2&gt;

&lt;p&gt;Lastly, a general principle. If you take a look at most of our previous examples and their proposed solutions, they all share a common property: the solution implements an abstraction.&lt;/p&gt;

&lt;p&gt;Do not depend on data structures, depend on an abstraction that gives you access to the underlying data. Do not depend on nullable values, depend on an abstraction that handles the nullable state for you... You can see the pattern.&lt;/p&gt;

&lt;p&gt;The advantage of abstractions over concretions is that they change less often, and this is good for code maintainability:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TFAfGF-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kixnj602be1rptpr6t5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TFAfGF-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kixnj602be1rptpr6t5f.png" alt="Diagram changes v effects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You often cannot control the amount of changes over time, but you can control the number of dependencies. Stay away from zone B and you will be fine.&lt;/p&gt;

&lt;p&gt;That's it! We hope you will find some useful tips from this list that you can put to good use in your daily coding practice.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
  </channel>
</rss>
