<?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: kevin074</title>
    <description>The latest articles on DEV Community by kevin074 (@kevin074).</description>
    <link>https://dev.to/kevin074</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%2F449375%2Fe634acbc-8cdb-426b-9d0a-5dea427d4eb0.png</url>
      <title>DEV Community: kevin074</title>
      <link>https://dev.to/kevin074</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevin074"/>
    <language>en</language>
    <item>
      <title>On to effective frontend testing</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Fri, 13 Sep 2024 16:15:14 +0000</pubDate>
      <link>https://dev.to/kevin074/effective-frontend-testing-3e5h</link>
      <guid>https://dev.to/kevin074/effective-frontend-testing-3e5h</guid>
      <description>&lt;p&gt;Have been interviewing for quite a while. What stood out to be in this painful process was that the interview is doomed if the question of testing was raised at all. This is because my experiences have been primarily in frontend development and the two companies I have stayed in were very poor in frontend testing. &lt;/p&gt;

&lt;p&gt;--- Skip if you want to go straight to the discussion ---&lt;/p&gt;

&lt;p&gt;My lack was, in some sense, a byproduct of industry culture. Frontend testing has always been a thing, but back a decade ago company structure has been separating testing concerns from development process. So we had a dedicated QA team who would write E2E/automated tests for us developers. So testing was not even in the job description. Also the unfortunate truth of small startup is delivery is always above everything else, so since testing hinders productivity, we developers didn't test. We didn't even have any testing librarie (Jasmine/Mocha/PhantomJS...) installed in the repo. &lt;/p&gt;

&lt;p&gt;I got my second job in a much bigger company (consumer platform team had like 150 developers?). However, there was no testing too essentially speaking. Each team (teams divided by feature like checkout, loyalty, registration...) again had dedicated QA member(s) who would write those E2E test. Once that culture set in and QA was cut from the budget, no one was picking them up because there was no one to learn it from. I tried to pick up some E2E testing for our team, but the code left behind wasn't even functional and full of obvious bugs (lots of WTFs). Combined with tight deadlines AGAIN, testing fell behind. The only time people talked about testing was for utility functions and custom react hooks.&lt;/p&gt;

&lt;p&gt;--- discussion starts ---&lt;/p&gt;

&lt;p&gt;Being plagued by the no-testing culture, I have to at least come up with something that I can say during interviews about testing abstractly. I'll skip over the usual bullshits of not testing styles or implementation what not. &lt;/p&gt;

&lt;p&gt;Feel free to add to the discussion. This affects at least 300 of my past coworkers! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.) test global states:&lt;/strong&gt;&lt;br&gt;
In my experiences one of the most gnarly feature is "if this happens, we'll do this for you automatically" type of behavior. For example, one app I had was a graph visualization dashboard that was heavily configurable. One configuration change can cause other configurations to change as well, depending on the data returned and what not. Some configuration side effects are not straight forward. So you'll want to test automatic configuration changes and whether the state is persisted/unchanged/consistent across the board. So if you have testing around this type of behavior, aligned with PM, managers, design, and QA team is immensely vaulable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.) don't spend much time testing the integrity of UI input:&lt;/strong&gt; &lt;br&gt;
I see quite a few tutorials talking about testing inputs, like when I type "taylor swift" into the search bar and press enter, then our search function will get taylor swift as input. &lt;/p&gt;

&lt;p&gt;This is straight up unhelpful. If your data binding is broken it'll either be very obvious that you should have caught it yourself while development or it's not automatically testable because something was hindering the functionality, like an invisible div above search bar so users can't type in search.&lt;/p&gt;

&lt;p&gt;if you are being paid by lines of code though, go ahead :) &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.) test inputs as side effect of inputs though is desirable:&lt;/strong&gt;&lt;br&gt;
contrary to number 2, you'll want to test functional calls that are completely side effects to user interaction. For example, when user clicks on a button, a request should be called to register this user action for data analysis. This type of side effect that are completely separate from the core functionality, should be automatically tested so that we won't be caught off guard by some unintentional changes. Non-core side effect can be essential to other teams, I was on one of such other teams :D &lt;/p&gt;

&lt;p&gt;So how do you architect these testing requirements? &lt;br&gt;
let's break down the frontend architecture: MVC (you can say you are MVVM or what not, it doesn't really matter). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V - view (html/jsx):&lt;/strong&gt; This is great for E2E/headerless browser testing and is an industry standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C - controller (business logic):&lt;/strong&gt; spend some time making sure the functions are correct. For example, if you have/abstract to pure functions, does the expected input-output process still in tact? Somewhat industry standard, but people don't usually bother making stateful functions into pure functions and test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;M - model (api calls/states):&lt;/strong&gt; this is what I want to focus on the most. your (non-rendering) states should be global and singleton per concept. Not new idea, since Redux is basically it. However it doesn't have to be Flux for our testing purposes. You can have jotai atoms but you can code a wrapper so that you can expose your centralized setter functions for testing.&lt;/p&gt;

&lt;p&gt;the similar thing should be done on your api calls/third party libraries. It should be global and singleton so that you can confidently tests "when I do this, is a core/noncore api call made in the application". This is done routinely in, my limited experience, backend applications. It should be done in frontend applications too.&lt;/p&gt;

&lt;p&gt;How does this sound? I am sure someone already does this already, what's your experience? what can be improved? I'd love to hear from folks where frontend testing just go beyond E2E/headless browser and braindead simple unit testing.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Building long lasting relationship with PMs (the good ones at least)</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Wed, 10 Jul 2024 16:13:15 +0000</pubDate>
      <link>https://dev.to/kevin074/building-long-lasting-relationship-with-pms-the-good-ones-at-least-38o2</link>
      <guid>https://dev.to/kevin074/building-long-lasting-relationship-with-pms-the-good-ones-at-least-38o2</guid>
      <description>&lt;p&gt;Just between developers, we don't like Product Managers. Too often they are simply a monitor on our progress. However, these roles exist for good reasons and it's unfortunate too many bad PMs exist because they saw a tiktok about big tech and jumping ship into the industry, thanks you weird big tech lifestyle influencers... why do these people exist anyways????&lt;/p&gt;

&lt;p&gt;Product Managers have a critical role in the company. They are the bridge between managers, C-suites and us, the little cogs in their money printer. There are a lot of abstractions between what the leaderships wants to do and the product in the end. Your typical MBA graduates doesn't even know what the hell bubble sort is (even Obama knows come on!) so there is a mountain of details to filled in between. &lt;/p&gt;

&lt;p&gt;The best PMs I have worked with have some decent technical understanding. One can write SQL queries, which me as a primarily frontend developer can't do well :) ... Another had a QA background, which meant we were getting QAed every step of the way :( &lt;/p&gt;

&lt;p&gt;Good PMs do attend meeting with more technical details, to the point that although they sure as hell don't know what you are talking about, they at least see 10 inches beneath the waterline. &lt;/p&gt;

&lt;p&gt;All that said, &lt;strong&gt;it's important to always remember that PMs inherently speaking suffers a lot of anxiety on how the project is doing&lt;/strong&gt; because they don't know what the progress is REALLY like and how it can go wrong. We all know how a feature develops. First few days you are flying through 80% of the progress and the sky is blue. Then the next morning you wake up finding a hidden dragon in the abyss and now you are questioning whether you are even the person to do the job! Imagine the surprise, but from someone who can even see less than you and in an hour later have to tell the CEO that the project has to be delayed and the team now don't even know where they stand. Oh my god, I can't even imagine having to speak those words out... &lt;/p&gt;

&lt;p&gt;&lt;u&gt;Back to the topic: how do you work with PMs?&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;1.) First and the most important thing: build trust. &lt;br&gt;
this means you basically &lt;strong&gt;you try to be a good little boy at first&lt;/strong&gt;. Excruciating yes, but remember that they are realistically your superior and even though they technically aren't, they will be speaking to your manager and your manager's managers and all the way up 100000x more often than you ever will. communicating with the entire chain of command is their job! So you at least want PMs, and by proxy everyone in the chain, to know that you are a decent employee at the very least.&lt;/p&gt;

&lt;p&gt;Keep in mind they aren't responsible for the technical, just the communication. So &lt;strong&gt;they aren't afraid to say "the project is messed up because Joe couldn't..." and crack in your reputation&lt;/strong&gt;. Speak your name enough times and you will be on first name basis with your CTO and pip will be your last name.&lt;/p&gt;

&lt;p&gt;2.) When things don't go well, take ownership. &lt;br&gt;
your project won't be a smooth sailing, it rarely ever does. And no one really expects it to be too! So relax when things go south. Regardless, You will want to be the one that PMs turn to. Remember you are the developer with the closest look into what's going on inside the giant black box machine that YOU maintain. When things go south, immediately let PMs know you are aware and that you will inform them what's wrong, what's the fix, and what's the ETA. If you do this repeatedly, you will become the technical rockstar in their mind and &lt;strong&gt;they will learn to lean on you and scrutinize you less&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;Of course try your best to not mess up in the first place, bug free la la land is still the world we all want to live in.&lt;/p&gt;

&lt;p&gt;3.) communicate! &lt;br&gt;
Because that's the only thing PMs know how to get the job done. &lt;strong&gt;To them communicating is everything&lt;/strong&gt;. This can be done either in person, over slack, or even through Jira updates. One way or another, your relationship with PMs are built entirely on what you say and what you write. Unlike your engineering manager who can look at your code and assess base on the quality of your code, &lt;strong&gt;your PMs assess you entirely on the quality of your communication.&lt;/strong&gt; This may be a hard lesson for many engineers, because we would have never chosen this career path if we like communicating so much. However communication is sadly the best way to build a mutual a long lasting relationship with PMs.&lt;/p&gt;

&lt;p&gt;4.) communicate concisely and precisely! &lt;br&gt;
Work on your writing and speaking skills. Start with writing, because writing allows you to edit, read back what was written, and improve upon. Eventually your writing skill level will bleed into your speaking skills. This is important because &lt;strong&gt;PMs ain't got no time to listen to you talk about something in 50 words when it can really be said in 5&lt;/strong&gt;. Remember they don't care about a lot of details, and they want just enough details so that they can go back and not bullshit the leadership. &lt;strong&gt;You aren't in high school anymore and HAVE to write a 500 words essay, lose that habit!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One thing I like to do is that I first write the most important details like what's wrong, what's the ETA, what's the one sentence describing the fix. Then I would write a "tech note below" to jog down what's going on in the best level of detail I could provide. This helps you as the person fixing it to document and brain storm, it helps the PMs to take in whatever detail they want to know if any, and it helps your engineering manager to weigh in and vouch for you that what you provided (reason, eta, and fix) is reasonable and the path forward.&lt;/p&gt;

&lt;p&gt;5.) when conflicts happen remember: &lt;strong&gt;we are striving for the best product possible.&lt;/strong&gt;&lt;br&gt;
Inevitably conflicts arises and communications appear personal. However, remember that whatever comes out your mouth it should always about how the team can produce the best product and best solutions. Keep that also in mind this is what the product managers are striving for so that you can keep your cool. Feel free to vent about it afterwards with your tech coworkers of course :) I do that very often and that person's name became a verb among friends&lt;/p&gt;

&lt;p&gt;6.) Push back reasonably and provide alternatives:&lt;br&gt;
this is really the badge of mastery, which is why this is the last point. You don't want to be JUST a good little pet doing everything they ask. They won't respect you this way in the long term and will step over you like a doormat you are. &lt;/p&gt;

&lt;p&gt;When you see a possible alternative solution, speak. PMs are communicators and solution-wannabe, but really they are just the communicators. Sorry not sorry. They don't build the product so they won't know how else the product can be built. Sure they'll do market analysis and compare what other companies do for the same feature and what other standards should be kept in mind, but in the end the creativity CAN also be coming from you as the owner and builder of the feature. &lt;/p&gt;

&lt;p&gt;They are often so deep in their own jungle that they can't see the tree in the forest. So don't be afraid to speak, remember, &lt;strong&gt;all they want is the best feature to be built, and if you see another way, that's VERY welcomed!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;You want to do this occasionally and just often enough so that they know that keeping you in meetings is worthwhile, because you are listening, thinking, and &lt;em&gt;speaking&lt;/em&gt; in the meetings. You are a participant and not simply an yes-man. &lt;/p&gt;

&lt;p&gt;This also means that when their ask is unreasonable, communicate that too. However, &lt;strong&gt;remember that for one push back, also provide one solution&lt;/strong&gt;. You are the solution provider in the end so you can't just reject. Just rejecting is what your CEO does for a living!&lt;/p&gt;

&lt;p&gt;Hopefully this was helpful, feel free to let me know I am full of shits.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>developer</category>
    </item>
    <item>
      <title>Leetcode diary: Remove Duplicates from Sorted Array II</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Thu, 27 Jun 2024 20:25:16 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-remove-duplicates-from-sorted-array-ii-1cnp</link>
      <guid>https://dev.to/kevin074/leetcode-diary-remove-duplicates-from-sorted-array-ii-1cnp</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii" rel="noopener noreferrer"&gt;LINK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Worst day. Was stuck on this problem for 2+ hours then 1+ today after sleeping on it :( .... &lt;/p&gt;

&lt;p&gt;Something just didn't click with me on this problem so I'll write it down for my sake, hope it'll help you too! &lt;/p&gt;

&lt;p&gt;the &lt;a href="https://leetcode.com/problems/remove-duplicates-from-sorted-array" rel="noopener noreferrer"&gt;easy version of this question&lt;/a&gt; is actually easy with a twist so we'll start from there:&lt;/p&gt;

&lt;p&gt;how do we &lt;strong&gt;in-place&lt;/strong&gt; reassign values in an &lt;strong&gt;sorted&lt;/strong&gt; array such that the first K elements of the array are all unique. Anything after K is ignored. &lt;/p&gt;

&lt;p&gt;Being sorted is important because then all the same numbers are in a row so you CAN do something better than using a set/hashmap.&lt;/p&gt;

&lt;p&gt;the in-place part just make this question hard enough to be easy-level leetcode.&lt;/p&gt;

&lt;p&gt;To solve this problem, you'll need two concept:&lt;/p&gt;

&lt;p&gt;1.) An index that points at the actual index of the array that you'll return (the k value)&lt;/p&gt;

&lt;p&gt;2.) Swap function that doesn't swap values of two indexes, but rather just swap in the value from one index to the other. This is &lt;strong&gt;critical&lt;/strong&gt; because if you do a regular i&amp;lt;-&amp;gt;j index swap, you'll end up having to deal with having to persistently skip the swapped-backward index&lt;/p&gt;

&lt;p&gt;you can do this question looking forward or looking backward of the current index, I elected backward. Here is the pseudo code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.) init kIndex=1, currentIndex
2.) for loop on currentIndex and inputArray
3.) if the nums[currentIndex] !== nums[currentIndex-1], swap(inputArray, kIndex, currentIndex); kIndex++; 
4.) else skip 
5.) return kIndex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;kIndex=1 part is a bit tricky, but remember that k is both "the number of elements in inPutArray that contains unique values after function run" and "index where you would swap"&lt;/p&gt;

&lt;p&gt;It is impossible for the "number of unique elements" to be 0 and it's also impossible for "index to swap" to be 0 (since 0-index value should always be the unique one anyways). &lt;/p&gt;

&lt;p&gt;you'll have to get into a habit of understanding the question and initialize accordingly to the question. Cant always just start at 0. I see there are some solution that start at 0, but then in the end they'd need to return k+1, so you'll have to adjust one way or another. &lt;/p&gt;

&lt;p&gt;4th step, else skip, is also the tricky part. you skip because you only want to increment the currentIndex value and not the kIndex. This way you are programming the behavior "increment until we find the next unique value in the array" &lt;/p&gt;

&lt;p&gt;For 3rd step, you are programming "I found a new unique number and I made sure it's pushed to the front of the array, then made sure we know where the next possible unique number index should be"&lt;/p&gt;

&lt;p&gt;Now let's start doing the question we were here for :) ... &lt;br&gt;
the second version is exactly the same, but each number can have 2 copies in the final array now instead of 1 only.&lt;/p&gt;

&lt;p&gt;test cases (always start with these in an interview, get in a habit now): &lt;br&gt;
[1,2,3,4,5] -&amp;gt; no change&lt;br&gt;
[1,1,2,3,4,5] -&amp;gt; no change&lt;br&gt;
[1,1,1,2,3,4,5] -&amp;gt; [1,1,2,3,4,5]&lt;br&gt;
[1,1,1,2,2,3,4,5] -&amp;gt; [1,1,2,2,3,4,5]&lt;br&gt;
[1,1,1,2,2,2,3,4,5] -&amp;gt; [1,1,2,2,2,3,4,5]&lt;br&gt;
[1,1,1,2,2,2,3,4,5,5] -&amp;gt; [1,1,2,2,2,3,4,5,5]&lt;br&gt;
[1,1,1,2,2,2,3,4,5,5,5] -&amp;gt; [1,1,2,2,2,3,4,5,5]&lt;/p&gt;

&lt;p&gt;the first thing that should come in mind is that &lt;br&gt;
well who's the source of truth? who knows which numbers that are actually duplicated as we loop through the array and do all the swapping, skipping, and incrementing the indexes?&lt;/p&gt;

&lt;p&gt;the answer is that the kIndex actually holds the value and of course now we need its side kick: kIndexMinus1 so that we know whether the number has already showed twice and we need to skip until the next unique number.&lt;/p&gt;

&lt;p&gt;why kIndex? because we are always swapping into the kIndex position, so as the code handles different usecases, it's always the kIndex that keeps track of what's going on. &lt;/p&gt;

&lt;p&gt;With this in mind, we should go back to the easy-level question again, sorry just one last time, and update our code so that we can practice coding "the kIndex holds the source of truth"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapInOnly (nums, swapInIndex, swappedFromIndex) {
    if (swapInIndex === swappedFromIndex) return
    nums[swapInIndex] = nums[swappedFromIndex]
}

function removeDuplicates (nums) {
    let kIndex = 0
    for (let index=1; index&amp;lt;nums.length; index++) {
        const num = nums[index]
       if (num !== nums[kIndex]) {
            swapInOnly(nums, kIndex+1, index)
            kIndex++
        }
    }
    return kIndex+1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;okay so the interesting part and difficult part is actually over. This is made simple because we choose to use kIndex as the truth holder on what is the current state of the array. Feel free to scroll down to my attempts when I did not do that.&lt;/p&gt;

&lt;p&gt;we would now:&lt;br&gt;
1.) initialize kIndex=2&lt;br&gt;
2.) start looping with currentIndex=2&lt;br&gt;
3.) at each iteration init variables for &lt;br&gt;
const num = nums[currentIndex]&lt;br&gt;
const oneBefore = nums[kIndex-1]&lt;br&gt;
const twoBefore = nums[kIndex-2]&lt;br&gt;
4.) if num === oneBefore === twoBefore, do nothing and continue loop&lt;br&gt;
5.) else swap currentIndex and kIndex, kIndex++&lt;/p&gt;

&lt;p&gt;That's it! &lt;br&gt;
the solution is very simple because we use kIndex as source of truth on what is the current state of the array, does the array have 2 or less copies of each unique number?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can think of this as a stack question&lt;/strong&gt; where we are adding to the stack IF less than 2 copies of the number in the array. &lt;/p&gt;

&lt;p&gt;Full code below with extra handling on an edge case&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swapInOnly (nums, swapInIndex, swappedFromIndex) {
    if (swapInIndex === swappedFromIndex) return
    nums[swapInIndex] = nums[swappedFromIndex]
}

function removeDuplicates (nums) {
    if (nums.length &amp;lt; 3) return nums.length
    let kIndex = 2
    let oneBefore
    let twoBefore

    for (var i=2; i &amp;lt; nums.length; i++) {
        const number = nums[i]
        oneBefore = nums[kIndex-1]
        twoBefore = nums[kIndex-2]

        if (number === oneBefore &amp;amp;&amp;amp; number === twoBefore) {
            continue
            //or you can write the code so it doesn't need this do nothing block, but I think the logic is a little counter-intuitive.
        } 


        if (i=== nums.length-1 &amp;amp;&amp;amp; nums[i] === oneBefore &amp;amp;&amp;amp; nums[i] === twoBefore) {
            continue
        } 

        swapInOnly (nums, kIndex, i)
        kIndex++
    }
    return kIndex
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;~~ below are my other attempts to NOT use kIndex as truth-holder ~~&lt;/p&gt;

&lt;p&gt;okay so why is this important? why can't we just look back to two indexes from currentIndex and see what's up? &lt;br&gt;
this is because you'll have to complicate the kIndex incrementing logic unnecessarily...and probably just get it wrong&lt;br&gt;
consider this example:&lt;br&gt;
[1,1,1,2,2,3,4]&lt;br&gt;
when we get to this place [1,1,&lt;strong&gt;1&lt;/strong&gt;,2,2,3,4]&lt;br&gt;
we should increment currentIndex until the next number&lt;br&gt;
(and do nothing with kIndex === 2, which stays at the bolded index too)&lt;br&gt;
next: [1,1,1,&lt;strong&gt;2&lt;/strong&gt;,2,3,4]&lt;br&gt;
this is when we do the swapping to: [1,1,2,&lt;strong&gt;2&lt;/strong&gt;,2,3,4], kIndex=3&lt;br&gt;
next: [1,1,2,2,&lt;strong&gt;2&lt;/strong&gt;,3,4]&lt;br&gt;
notice that because of the swapIn that was done, the ex-second-2, the bolded one, is now a third occurrence of 2, what should we do?&lt;br&gt;
leave kIndex until we get to integer 3? &lt;br&gt;
we can't, because remember kIndex = 3? &lt;br&gt;
this means we'd get back [1,1,2,3,2,&lt;strong&gt;3&lt;/strong&gt;,4]&lt;/p&gt;

&lt;p&gt;we could say that when nums[i] === nums[i-1] === nums[i-2]&lt;br&gt;
we make kIndex = i and continue &lt;br&gt;
however consider: [1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,4]&lt;br&gt;
if we do this, we'll do a first swap at&lt;br&gt;
[1,1,2,1,1,1,1,1,1,&lt;strong&gt;2&lt;/strong&gt;,2,2,2,2,3,4]&lt;br&gt;
then the next one &lt;br&gt;
[1,1,2,2,1,1,1,1,1,2,&lt;strong&gt;2&lt;/strong&gt;,2,2,2,3,4]&lt;br&gt;
however when the next one comes&lt;br&gt;
[1,1,2,2,1,1,1,1,1,2,2,&lt;strong&gt;2&lt;/strong&gt;,2,2,3,4]&lt;br&gt;
we have 3 twos so the code would make kIndex to the bolded index.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>career</category>
    </item>
    <item>
      <title>Leetcode Diary: Move Zeros</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Mon, 10 Jun 2024 16:02:08 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-move-zeros-4p8d</link>
      <guid>https://dev.to/kevin074/leetcode-diary-move-zeros-4p8d</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/move-zeroes/"&gt;https://leetcode.com/problems/move-zeroes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the question is super easy if you solve it by using an extra array, using built-in methods to mutate the array via splice and then push.&lt;/p&gt;

&lt;p&gt;However if you were to solve it in place like the question says, it isn't so easy anymore. This question is probably medium really because it requires some smart insights then. &lt;/p&gt;

&lt;p&gt;I'll discuss my solution then another solution from the discussion section, which is actually much better, but very unintuitive (which is why I am writing this article) &lt;/p&gt;

&lt;p&gt;My soultion was relatively simple: using two pointers, one for indexes that tracks zeros, and another for tracking non-zeros. &lt;br&gt;
You write a while loop and while both indexes are less than the array length, you do: &lt;br&gt;
1.) increment zeroIndex until you find the a 0 in the array&lt;br&gt;
2.) increment the integerIndex while it's less than zeroIndex and the current number is a 0.&lt;br&gt;
3.) both increments should stop if it is at array length&lt;br&gt;
4.) swap these two indices &lt;br&gt;
5.) repeat&lt;/p&gt;

&lt;p&gt;code as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function swap (nums, i, j) {
    const temp = nums[i]
    nums[i] = nums[j]
    nums[j] = temp
}
var moveZeroes = function(nums) {
    let zeroIndex = 0
    let integerIndex = 0

    while (zeroIndex &amp;lt; nums.length &amp;amp;&amp;amp; integerIndex &amp;lt; nums.length) {
        while ( nums[zeroIndex] !== 0 &amp;amp;&amp;amp; 
            zeroIndex &amp;lt; nums.length
        ) {
            zeroIndex++
        }

        while (
            (
                nums[integerIndex] === 0 || 
                integerIndex &amp;lt; zeroIndex
            ) &amp;amp;&amp;amp;
            integerIndex &amp;lt; nums.length
        ) {
            integerIndex++
        }

        if (
            zeroIndex &amp;lt; nums.length &amp;amp;&amp;amp; 
            integerIndex &amp;lt; nums.length
        ) {
            swap(nums, zeroIndex, integerIndex)
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it's not great, especially with the number of conditions involved, but it works :) ... &lt;/p&gt;

&lt;p&gt;now here is the fun part... &lt;/p&gt;

&lt;p&gt;the intuition required to get the optimal solution is:&lt;br&gt;
you need to move all numbers by some number, this number is determined by &lt;strong&gt;how many 0s are in front of it to start with&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;therefore in the same two pointers approach a much easier way to do this is by having one pointer that tracks the current iteration and the other for tracking how many 0s have appeared in the iteration.&lt;/p&gt;

&lt;p&gt;for each 0, you increment the zero count&lt;br&gt;
for each non-zero you move it upward by the current zero count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const moveZeroes = function(nums) {
  let j =0;
  for(let i=0; i&amp;lt; nums.length;i++){
   if(nums[i] === 0){
      j++ ;
   } else { 
     [nums[i-j], nums[i]] = [nums[i], nums[i-j]] 
   }
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is much easier to read, but definitely harder to understand how it works.&lt;/p&gt;

&lt;p&gt;I think during an interview if you were with this problem, the best bet to get this intuition if you go through this question carefully, and count exactly how many 0s does the number need to move forward. &lt;br&gt;
I'd definitely be okay if you were to come up with some more complicated solution like the former though :) ...&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>learning</category>
      <category>coding</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>improving product manager relationship with you</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Fri, 31 May 2024 18:20:33 +0000</pubDate>
      <link>https://dev.to/kevin074/managing-product-manager-relationship-with-you-1gc6</link>
      <guid>https://dev.to/kevin074/managing-product-manager-relationship-with-you-1gc6</guid>
      <description>&lt;p&gt;It's very often that we, the developers, make fun of how useless product managers (PM) are. They aren't contributing to the feature actually, they constantly only care about the deadline, and they can't be held responsible while actually pointing fingers at you.&lt;/p&gt;

&lt;p&gt;Well, if your PMs are doing just bare minimum then yeah they will be pretty unhelpful. However, I've worked with a good PM and it's changed my view on how important product managers are and how do you keep a good relationship with them.&lt;/p&gt;

&lt;p&gt;the main functions of the product managers are:&lt;/p&gt;

&lt;p&gt;1.) managing expectations and request of high level stack holders.&lt;/p&gt;

&lt;p&gt;This is often about having meetings with all levels of hierarchy, including you the developer, about what is the current plan, what are the potential ideas, and whether the projects are still on track or at risk of delay. This also means that PMs are constantly in communication with high level employees like directors, vice presidents, and even the CEOs about the latest status update; it's very unpleasant when the meeting isn't a simple "all is fine" and you definitely don't want to be the one delivering that news.&lt;/p&gt;

&lt;p&gt;2.) filtering and prioritizing tasks. &lt;/p&gt;

&lt;p&gt;This is a collaboration with the engineering managers and leads as well. The difference is that product managers have a wider cast of net and have to be aware of what other teams are doing, what general company direction is going towards and whether the development is matching that direction.&lt;/p&gt;

&lt;p&gt;It also means that PMs sometimes have to deny requests from the high level employees; do you really want to be the one saying no to the CEO?&lt;/p&gt;

&lt;p&gt;3.) hold business knowledge about the team, the bigger organization, and the company in general. &lt;/p&gt;

&lt;p&gt;This is where the PMs really shine and it's why PMs are very valuable to the company too. &lt;/p&gt;

&lt;p&gt;if you don't understand how important this is, please &lt;a href="https://dev.to/kevin074/lessons-from-layoff-business-knowledge-all-3di7"&gt;see my recent article about it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here is the fun part, how do you manage your relationship with the PMs and how do you best leverage their role in the company.&lt;/p&gt;

&lt;p&gt;1.) &lt;strong&gt;communication is key&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you haven't noticed yet, all the PMs do are basically communicating. If you are the one who isn't replying to slack messages or giving them regular updates, you will be a pain to work with for them. &lt;/p&gt;

&lt;p&gt;this is hard especially in the world of hybrid/remote world that we are in today and I'll have an article about this too! &lt;/p&gt;

&lt;p&gt;2.) &lt;strong&gt;Be reliable and the one they can go to&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;PMs are super well aware that they can't actually give any solutions in a tech company. So if you want your PMs to like you, have a firm grasp on the features you are responsible for and more. If you are the one they can turn to when they have a question or when things go south, they'll definitely like you a lot better.&lt;/p&gt;

&lt;p&gt;Now this means more responsibilities for you, and some people hold the philosophy that you shouldn't do more than what you are paid for. However remember that PMs are always communicating? I am willing to bet my life that they talk to your managers and all chains above more than you ever will. They won't be afraid to use your name as reason why they can't communicate properly and soon your head could be on the guillotine :) &lt;/p&gt;

&lt;p&gt;Of course the opposite side is that if you are reliable, everyone will know you are a key player and your next promotion will be easier; &lt;em&gt;also remember no matter how hard you advocate for yourself, it's always going to mean less than how others advocate on your behalf&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;3.) &lt;strong&gt;keep an attitude that they are just trying to do what's the best for the team&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;conflict is absolutely inevitable with your PM. It can be that they are asking you too many questions while deadline is looming. Maybe they asked you for some feature that straight up doesn't make sense. Whatever it may be, just keep in mind that their job is to make sure the company is going in the right direction and your team is too. They aren't trying to sabotage your job or anything and in fact if the team isn't being perceived as valuable it is a failure on their part (unless your feature keeps triggering production alerts of course ;D).&lt;/p&gt;

&lt;p&gt;It'll be hard at times, but keeping in mind that they are trying to do the best by the team will help with your temper in checked. After all, you aren't the one having to answer to the CEO one hour later!!&lt;/p&gt;

&lt;p&gt;4.) &lt;strong&gt;show an interest in the project and the discussion around it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;everyone loves to be asked about their area expertise. For PMs, it is about the projects they manage and the talks leading up to it, including what was tried in the past and what business knowledge is around it. Showing more interest along will make the PM treat you more than just a jira bot, which will be great for your mental well-being too honestly. &lt;/p&gt;

&lt;p&gt;This will also help you understand why you are doing this project to start with and whether there are suggestions you can offer that also fit the overall goal. This will be invaluable too when something unexpected happens, a lot, and alternatives are easier for you to do but just need to be signed off. In this way, you also start exhibiting behaviors beyond just a developer (senior and + levels).&lt;/p&gt;

&lt;p&gt;If you like this article, please give a reaction or anything. Feel free to subscribe to me as I will be writing these higher level career articles for at least this week and more. &lt;/p&gt;

&lt;p&gt;Also I was just laid off :) ... so if your team is hiring remote please refer me!!!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>learning</category>
      <category>developer</category>
    </item>
    <item>
      <title>Lessons from layoff - business knowledge &gt; all</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Thu, 30 May 2024 15:08:20 +0000</pubDate>
      <link>https://dev.to/kevin074/lessons-from-layoff-business-knowledge-all-3di7</link>
      <guid>https://dev.to/kevin074/lessons-from-layoff-business-knowledge-all-3di7</guid>
      <description>&lt;p&gt;Hello, 2 years back I started a series of stories from my first job while looking for my new job, now that &lt;del&gt;new&lt;/del&gt; job laid me off... here it is again :)&lt;/p&gt;

&lt;p&gt;For today, the topic I want to focus on is the importance of business knowledge. &lt;/p&gt;

&lt;p&gt;If you are a junior developer or less than 5 years developer, this topic won't be too helpful to you right now. You should ABSOLUTELY focus on learning the tech stack at your job 100%. &lt;/p&gt;

&lt;p&gt;Our company recently went on a red wedding. Our headquarter teams were cut by 65%, which includes marketing, product managers, designers, and engineering. The biggest hit was on engineering with an around 75% cut; thanks Elon for proving the world you can run world class tech company doing that... &lt;/p&gt;

&lt;p&gt;All bitterness aside, the thing that I observed from the people who (luckily?) survived was that they were all business value holders: high level engineering managers, above senior-level developer, directors, and product managers. &lt;/p&gt;

&lt;p&gt;To be fair, all cuts before this blood path, yes we had like 6 layoffs before this, were mostly on engineering managers and product managers. When company are looking to simply adjust cost, they would definitely rather to cut excess managers rather than developers. &lt;/p&gt;

&lt;p&gt;However when the tough decision is to be made: who are TRULY important to the business, it's those who have great understanding of company decisions that survive. The number of product managers that survived was the enlightening to me. I didn't understand it at first, but if you really think about it: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;who are easier to replace? the coders whose work is completely engrained in the code and can be picked by others reading or the product managers who went through countless hours communicating, understanding the customer base, prioritizing, and have a wealth knowledge on what was tried, what worked, and what failed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this light, it looks like a simple, not easy, decision that you should retain more people who understand each piece of the business deeply than engineers who just receive Jira tickets and executes without knowing the numerous why. &lt;/p&gt;

&lt;p&gt;Of course you can just understand the situation more simply: the more important employees survive longer. However, as a developer, I did have some pride of my own value over product managers (Sorry I have learned better), so this was eye opening for many ways. &lt;/p&gt;

&lt;p&gt;Many senior developers that I worked with seemed to understand this point to some extend, but looking back to our company engineer performance rubric for all levels and this layoff, the worth of business knowledge/understanding REALLY hit me hard. &lt;/p&gt;

&lt;p&gt;Developers are often sidelined to the decision process and are truly just a cog or means to an end. So if you want to stand out among your peers, start doing these:&lt;/p&gt;

&lt;p&gt;1.) understand what metrics are important to your team. Of course generating more money is the ultimate end goal. However, your team might be interested in acquiring more new customers. How much is it to do different type of marketing? what's the bottleneck? what are the limits? Why are we keeping channels that don't make sense. What other alternatives do we have? What did we try in the past? What is the current direction for the team and why? There are a million question one could ask about the team and what are the decisions that were made along the way (without actually be in said billion meetings :D).&lt;/p&gt;

&lt;p&gt;2.) Understand the tech that help achieve these metrics. This is a high level understanding, not talking about we use a recursion on this function to do xyz leetcode results. This is about how are these metrics moved by tech. For example how do you know which user is new customer, how is that data propagated in the company, and whether this pipeline can be improved. &lt;/p&gt;

&lt;p&gt;3.) Keep a great relationship with your product managers. I'll write a separate post on how. However if you really understood the entire point of this post then this should be a no-brainer why: your product managers are your best proxy to understand the business that your team care about, so really they are your best friends! Okay maybe not best friends... &lt;/p&gt;

&lt;p&gt;Thanks for reading, if you feel this was helpful or I am completely full of shit feel free to comment and let me know :D! &lt;/p&gt;

&lt;p&gt;Also feel free to look back on my past posts. I tend to write these higher level takeaway lessons or about specific leetcode questions. &lt;/p&gt;

&lt;p&gt;Also if you think I'd be a fit for a role PPPPLEASE contact &amp;lt;3 &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>Leetcode Diary: Unique Email Addresses</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Sun, 04 Sep 2022 23:48:18 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-unique-email-addresses-4kc5</link>
      <guid>https://dev.to/kevin074/leetcode-diary-unique-email-addresses-4kc5</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/unique-email-addresses/submissions/"&gt;https://leetcode.com/problems/unique-email-addresses/submissions/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this is a good question to start with if you haven't had leetcode style interviews or it's been a while since you leetcoded.&lt;/p&gt;

&lt;p&gt;the problem is rather simple, to process email strings to eliminate certain characters. You should follow three rules:&lt;br&gt;
1.) leave the parts after @ sign untouched&lt;br&gt;
2.) ignore the parts after + but before @ &lt;br&gt;
3.) remove all dots&lt;br&gt;
the return value is how many unique emails are there after processing. &lt;/p&gt;

&lt;p&gt;below is the pseudo for the easy version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pseudo:
emailsSet = new Set()

for each email in emails
parts = email.indexOf("@")
local = parts[0]

noPlus = ignorePlus(local)
noPlusNoDot = removeDots(local)

returnEmail = noPlusNoDot + parts[1]

emailsSet.add(returnEmail)
return eamilsSet.length();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are aiming for an entry-level job. This is something you should be able to implement in full code without much problem. &lt;/p&gt;

&lt;p&gt;If you are more advanced than entry, think of an answer without using javascript built-in functions but the substring(). &lt;/p&gt;

&lt;p&gt;the thinking is like this:&lt;br&gt;
Q: is there any complex rule that need to refer to previous characters?&lt;br&gt;
A: no, okay then maybe all we need is a loop&lt;br&gt;
Q: how do we loop through?&lt;br&gt;
A: you provide conditions for add or ignore character&lt;br&gt;
Q: is that all there it is?&lt;br&gt;
A: well, you have to be careful about the + and @ conditions. You ignore until you hit the @ after hitting +.&lt;br&gt;
Q: how do you order the conditions, does it even matter?&lt;br&gt;
A: it matters, because once you hit @, you just append everything, so that's one good reason condition ordering matter. &lt;/p&gt;

&lt;p&gt;Additionally, once you hit a +, you do not add to the string, so adding to the string must be the final default condition. &lt;/p&gt;

&lt;p&gt;With that in mind you should be able to come up with a code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var numUniqueEmails = function(emails) {
    const emailsSet = new Set();
    for (let email of emails) {
        let finalString = ''
        let facedPlus = false;

        for (let i=0; i &amp;lt; email.length; i++) {
            const current = email[i];
            if(current === '@') {
                finalString += email.substring(i)
                break;
            } else if (current === ".") {
                continue;
            } else if (current === "+") {
                facedPlus = true;
                continue;
            } else if (facedPlus) {
                continue;
            } else {
                finalString += current;
            }
        }

        emailsSet.add(finalString);
    }

    return emailsSet.size

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please let me know if I missed something that's unclear, thank you!&lt;/p&gt;

&lt;p&gt;Please hit me with a follow if you’d like to see more content, I’ll update irregular but somewhat frequently.&lt;/p&gt;

&lt;p&gt;If you’d like a 1-1 conversation with me going over your resume or your career trajectory in general, please reach out to me at &lt;a href="https://www.fiverr.com/kevtseng"&gt;https://www.fiverr.com/kevtseng&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Socials:&lt;br&gt;
&lt;a href="http://www.twitter.com/KevinTseng1991"&gt;www.twitter.com/KevinTseng1991&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/kevintseng1991/"&gt;https://www.linkedin.com/in/kevintseng1991/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>leetcode</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Leetcode diary: Merge Sorted Array</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Thu, 01 Sep 2022 12:53:55 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-merge-sorted-array-205j</link>
      <guid>https://dev.to/kevin074/leetcode-diary-merge-sorted-array-205j</guid>
      <description>&lt;p&gt;&lt;a href="https://leetcode.com/problems/merge-sorted-array"&gt;https://leetcode.com/problems/merge-sorted-array&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;problem is: given two sorted arrays, how do you produce a sorted array. One array have m count of numbers and the other has n count. The first array has m+n length so you don't need to worry about changing the array length.&lt;/p&gt;

&lt;p&gt;This problem is easy if you just put the result in another array and mutate the m+n array in the end. So we'll opt in the hardest route &lt;code&gt;O(m+n)&lt;/code&gt; with in place mutation only. &lt;/p&gt;

&lt;p&gt;The first thing you have to accept is that the m and n values matter. It's a bit deceptive because the easy route doesn't really require it so people might overlook that and go down a terrible route. &lt;/p&gt;

&lt;p&gt;The second is that you have to use the count as is, don't try to do m-- for some clever trick, just have a usual index loop through and you'll be just fine.&lt;/p&gt;

&lt;p&gt;However you have to account for the fact that you can't just use for loops. This is because you have two arrays and aim for &lt;code&gt;O(m+n)&lt;/code&gt;, regular for loops can't do that.&lt;/p&gt;

&lt;p&gt;So it's a while loop with conditions.&lt;/p&gt;

&lt;p&gt;What are the conditions? It's easy to start out with something like:&lt;br&gt;
&lt;code&gt;while (indexM &amp;lt; m || indexN &amp;lt;n)&lt;/code&gt;&lt;br&gt;
but that wouldn't really work because the final length is m+n, so it's more than that probably. &lt;/p&gt;

&lt;p&gt;Then my thinking was:&lt;br&gt;
Q: when the loop end?&lt;br&gt;
A: it ends when all the numbers are in-place mutated&lt;br&gt;
Q: how many numbers are there? &lt;br&gt;
A: m+n&lt;br&gt;
Q: but how do I represent that in code?&lt;br&gt;
A: count until m+n?&lt;br&gt;
Q: that doesn't feel right ... &lt;/p&gt;

&lt;p&gt;If you ever get this feeling, it means something is missing for you to come up with the feels-right answer. You must step back and look at the other pieces of the problem. &lt;/p&gt;

&lt;p&gt;I looked back at the in-place part of the question. In-place mutation of an array should immediately trigger you to need a third array to hold the values for; an extension of having a third variable for swapping two values in an array.&lt;br&gt;
let's say it's: &lt;code&gt;const holdM = [];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With that in mind, it should be apparent that the loop will end when:&lt;br&gt;
&lt;code&gt;indexN === n || hold.length ==0&lt;/code&gt;, which translates to:&lt;br&gt;
&lt;code&gt;while(indexN &amp;lt; n || holdM.length) {&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now we can finally move on to writing the core code! &lt;/p&gt;

&lt;p&gt;Given the problem we have two parts to the code:&lt;br&gt;
1.) find current min value&lt;br&gt;
2.) mutate array with current min &lt;/p&gt;

&lt;p&gt;the first one is simple, we have 3 values:&lt;br&gt;
1.) current value of array[m]&lt;br&gt;
2.) of array2[n]&lt;br&gt;
3.) holderM value&lt;/p&gt;

&lt;p&gt;However we have to take care of each case because&lt;br&gt;
1.) array[m] can be undefined since array length = m+n and only have value in the first m length&lt;br&gt;
2.) array2 only have n values, you have to represent "array2 is exhausted" in code.&lt;br&gt;
3.) holderM may or may not have values, also may have more than one values in the array.&lt;/p&gt;

&lt;p&gt;to take care of that we can translate the code into:&lt;br&gt;
&lt;code&gt;const valM = indexM &amp;lt; m ? nums1[indexM] : Number.MAX_SAFE_INTEGER;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;const valN = indexN &amp;lt; n ? nums2[indexN] : Number.MAX_SAFE_INTEGER;&lt;/code&gt;&lt;br&gt;
&lt;code&gt;valHold = holdM.length ? holdM[0] : Number.MAX_SAFE_INTEGER;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;why only holdM[0]? it's because the smallest value is in the beginning of the array (you can also opt-in for last, doesn't matter). &lt;/p&gt;

&lt;p&gt;so we finally have:&lt;br&gt;
&lt;code&gt;minVal = Math.min(valHold, valM, valN);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now we need to do something with the min value. &lt;br&gt;
We have 3 cases to cover:&lt;br&gt;
1.) minVal = current val of M&lt;br&gt;
2.) minVal = current val of N&lt;br&gt;
3.) minVal = current val of holdM&lt;/p&gt;

&lt;p&gt;if it's &lt;br&gt;
1.) we don't need to do anything, the current value is already in the array in its right place!&lt;br&gt;
2.) it means values of N needs to be in place of M, therefore you'd need to push the M value to the holdM.&lt;br&gt;
Then mutate the array to put in N value&lt;br&gt;
3.) you need to push M value to hold M as do number 2 and mutate holdM value in.&lt;/p&gt;

&lt;p&gt;The last thing to take care in this big explanation is that you have to have indexM and indexN. You will only increment indexN when N is the smallest value (case 2) and you'll always increment indexM, because you are always mutating on M. &lt;/p&gt;

&lt;p&gt;full code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var merge = function(nums1, m, nums2, n) {
    const oriM = m;
    const oriN = n;
    let indexM=0, indexN=0, valM, valN, valHold, minVal;
    const holdM = [];
    while(indexN &amp;lt; n || holdM.length) {
        valHold = holdM.length ? holdM[0] : Number.MAX_SAFE_INTEGER;
        valM = indexM &amp;lt; m ? nums1[indexM] : Number.MAX_SAFE_INTEGER;
        valN = indexN &amp;lt; n ? nums2[indexN] : Number.MAX_SAFE_INTEGER;
        minVal = Math.min(valHold, valM, valN);

        if(minVal === valM) {
            indexM++; 
            continue; 
        }
        if (minVal === valN) {
            if (indexM &amp;lt; m) holdM.push(valM);
            nums1[indexM] = valN;
            indexN++;
        } 
        else if(minVal === valHold) {
            if (indexM &amp;lt; m) { holdM.push(valM); }
            nums1[indexM] = holdM.shift();
        }


        indexM++; 
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One last thing to note, the interviewer might be picky and ask what's the big O of this algorithm. It's not TRULY O(m + n) because of shift(). Shift() mutates the whole holdM at once. You should be fine if you acknowledge that caveat and say this could be easily remedied if we have a third variable indexHoldM and use that instead... Then god forbids that they talk about the length of the array. You'll need to then explain that you can just initiate the array with length m+n. Hopefully not...and hopefully that interviewer won't be on your team lol ...&lt;/p&gt;

&lt;p&gt;Please hit me with a follow if you’d like to see more content, I’ll update irregular but somewhat frequently.&lt;/p&gt;

&lt;p&gt;If you’d like a 1-1 conversation with me going over your resume or your career trajectory in general, please reach out to me at &lt;a href="https://www.fiverr.com/kevtseng"&gt;https://www.fiverr.com/kevtseng&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Socials:&lt;br&gt;
&lt;a href="http://www.twitter.com/KevinTseng1991"&gt;www.twitter.com/KevinTseng1991&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/kevintseng1991/"&gt;https://www.linkedin.com/in/kevintseng1991/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>algorithms</category>
      <category>devjournal</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Getting out of the junior level comfort zone ...</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Wed, 31 Aug 2022 21:01:23 +0000</pubDate>
      <link>https://dev.to/kevin074/getting-out-of-the-junior-level-comfort-zone--4o5p</link>
      <guid>https://dev.to/kevin074/getting-out-of-the-junior-level-comfort-zone--4o5p</guid>
      <description>&lt;p&gt;Boy it's been quite a couple of months for me. I am back from months of inactivity due to just being completely overwhelmed. &lt;/p&gt;

&lt;p&gt;My new team is great, wouldn't have asked for a better start. There is nothing to complain about, but just that the job has been above my previous scope by a significant margin and just took a lot of getting used to. &lt;/p&gt;

&lt;p&gt;My current team work on marketing technology, so it's a bit of an odd ball since we aren't directly working on the main app functionality, and not exactly a typical backend role either.&lt;/p&gt;

&lt;p&gt;Here are the challenges I've faced since getting out of my one-man show at my first job. Hope it helps putting somethings to perspective.&lt;/p&gt;

&lt;p&gt;The scale of the project is incredibly larger. There are just so many freaking technologies that we have to use it's insane. The first months it's literally me trying to get used to the terminologies and wrapping my head around what's going on without failing too much. There are so many techs that revolve around getting user data and consuming those data. Even after 5 months I am just able to scratch below the first layers. &lt;/p&gt;

&lt;p&gt;Talking to so many people, SO MANY PEOPLE. We work cross functionally since we are reliant on many floating pieces before we can do our work. So if we want something done, we might need to talk to 2 or 3 teams to get the pipeline going. Since we support marketing efforts, we are also actively in discussions with the marketing team and the data team. It's quite different from just talking to the manager/PM. &lt;/p&gt;

&lt;p&gt;The process is 100000x slower. I used to be able to dish out 4 tickets, up to 10, per day and still be watching hours of youtube during my time. Now I am spending so much time on non-coding related tasks that maybe I get a PR out once a week. The tempo is so different that I was on the verge of mental breakdown thinking my productivity is absolutely shit. &lt;/p&gt;

&lt;p&gt;Never thought I'd have to do presentations. We have to an Engineering Research Documentation (ERD) that explains a design for a feature. Then we will have to schedule a meeting where people on you team, and those under the larger org umbrella, participate and discuss the pros and cons. It was nerve-wracking to say the least and I was just glad questions could be answered. &lt;/p&gt;

&lt;p&gt;As you can imagine, life has been hard. On most days all I do is wake up, work, and sleep at 10pm (10PM!!!!!!!), because I am just so exhausted that I can do anything else. The past few weeks I've been able to get more breathing room and get some exercise down. It's great to finally see pieces come in together not just at work but also in my life.&lt;/p&gt;

&lt;p&gt;It's been a great journey, follow me on here and other sites so that I can show you what's it like to be an average coder trying to break it big in the developer world. Thank you! &lt;/p&gt;




&lt;p&gt;If you’d like a 1-1 conversation with me going over your resume or your career trajectory in general, please reach out to me at &lt;a href="https://www.fiverr.com/kevtseng"&gt;https://www.fiverr.com/kevtseng&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on socials:&lt;br&gt;
&lt;a href="http://www.twitter.com/KevinTseng1991"&gt;www.twitter.com/KevinTseng1991&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/kevintseng1991/"&gt;https://www.linkedin.com/in/kevintseng1991/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How do you have productive 1-1 with upper management?</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Tue, 07 Jun 2022 15:47:30 +0000</pubDate>
      <link>https://dev.to/kevin074/how-do-you-have-productive-1-1-with-upper-management-54mh</link>
      <guid>https://dev.to/kevin074/how-do-you-have-productive-1-1-with-upper-management-54mh</guid>
      <description>&lt;p&gt;I have regular meetings with my immediate supervisor, which I always take the opportunity to get/give some feedback. However, I am not sure what to say with managers above my supervisor. &lt;/p&gt;

&lt;p&gt;I don't have regular interactions with them and they don't really get involved with the work I do. I am also just Software Engineer II, so not involved with high level projects. &lt;/p&gt;

&lt;p&gt;So I don't really know what to have a good discussion with them, but I really want to since I know it's a rare opportunity that the company structure have.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>discuss</category>
      <category>help</category>
    </item>
    <item>
      <title>Leetcode Diary: I got an offer!!</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Fri, 04 Mar 2022 01:53:03 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-i-got-an-offer-1ad</link>
      <guid>https://dev.to/kevin074/leetcode-diary-i-got-an-offer-1ad</guid>
      <description>&lt;p&gt;HI everyone, I know there are a handful, literally only a handful of people who have been following through my journey with almost daily updates on here. &lt;/p&gt;

&lt;p&gt;However, I am very happy to report to you guys that I have gotten an official offer from a company! I was so happy that I couldn't sleep for hours until 4am my time. It's been a VERY long journey for me. I started the leetcode process end of 2021 and it's been 2 months. There were also a 4 months of gruesome amount of studying for my first classes at UPenn's online CS Master program. There were couple of potential health issues in the family, myself included, that would've easily pushed me over the edge.&lt;/p&gt;

&lt;p&gt;As for the actual interview prep, it may sound like 2 months is kinda short but I've been doing this for all my waking hours for these 2 months. So it probably translate to like 4 months or more depending on different individuals. There were many points where I was literally so burned out that I couldn't function for more than a day. &lt;/p&gt;

&lt;p&gt;Additionally the past month ish I have been talking to too many recruiters and gone through so many interviews, many of which I have failed. There were many embarrassing failures, because they were only phone interviews process where there was even no coding involved at all; which basically meant they couldn't even pass me as a person or something :( I have failed onsite with just react/html/css coding rounds just because I haven't worked for a full year now ... Also failed another phone technical screen where the task was just code some input boxes and have a search bar filter the options with react... There were many interviews I just shouldn't have failed, but honestly thinking back this past year, there were probably only like 2 to 3 months where I completely wasted and took a vacation to enjoy life (I have been in a situation that forced me to leave my job and move out of the country).&lt;/p&gt;

&lt;p&gt;Coming back to the offer, I didn't think they would offer me anything at all. When I was at the phone interview, I only had a decent start for the behavioral topics. But when he showed me a SIMPLE coding exercise, like literally programming 101 easy question, my brain literally just blew up. I couldn't do it to save my life like a switch just turned off. The interviewer had to walk me through the steps, I was embarrassed as fuck when that question was over. &lt;/p&gt;

&lt;p&gt;He then showed me another question, which is just adding two numbers and return the result as a string since the input values are too big. I blanked out a bit less for this question but was clearly having troubles despite having done string additions multiple times throughout my leetcode journey before this year. This was also a question on Stanford's algorithm series, so I should've known the answer immediately.&lt;/p&gt;

&lt;p&gt;However, I was shaking so much that it was hopeless. The interviewer obviously could see that I was just not there at all and asked me to talk through the basic ideas. Luckily since I struggled through this before, I knew exactly what the correct algorithm would entail. So I quickly talked through the logic of it, like how to handle the progression and handle cases when digit addition is more than 9. He liked what he heard and gave me the chance to code it after he hangs up, which is a complete surprise to me too; I finished within 5 minutes after he hung up. &lt;/p&gt;

&lt;p&gt;Luckily for me, the interviewer was kind enough to see that everything was just nerves and allowed me to go into the onsite rounds. This was a giant surprise to me, I literally told my girlfriend I bombed it more than a nuclear bomb can. &lt;/p&gt;

&lt;p&gt;The onsite was quite brutal too. The first interviewer asked me a classic system design question. However, I didn't prepare for system design at all since I am a frontend developer. So I told him about my lack of study on this and we did not spend much time on it. Then we moved on to a medium level leetcode question. I quickly came up with the simple iterative O(N) approach. He then asked me whether I could improve it. I thought that perhaps O(log N) via binary search could work, because the inputs were sorted and there were some things I could do to determine direction.&lt;/p&gt;

&lt;p&gt;However he said binary search wouldn't work; I really think it should, maybe he just wanted to see my reaction. We then move on with a couple more spin offs for the question and I thought I had some answers, but probably just not great answers. So I thought the most this interviewer would rate me was a barely passable.&lt;/p&gt;

&lt;p&gt;The second interviewer, was a real brain teaser. The question just gave me another mental boom, I couldn't even get started with the question. It was a true mental boom moment again for me and I could barely function. &lt;/p&gt;

&lt;p&gt;There was so much desire to just give up, but I had to crawl my way through it just for the sake of it. There were many moments where I went back and forth with the puseudocode I wrote and even got confused at what needs to be done multiple times. In the end I came up with a O(N^4) solution to the problem. Obviously just a brute force but it was the best I could muster at the moment. As I thought about the question today, I realized it is possible to get a little better O(N^3) with memoization...but the memoization itself would be complicated all on its own so I don't know. &lt;/p&gt;

&lt;p&gt;Thought this round was bombed too, honestly the only thing I knew was that the code would work given minimal tweaking and edge case catching. However, I didn't think a barely passable code would constitute a yes from the interviewer.&lt;/p&gt;

&lt;p&gt;The last round was much better for me. It's a blind75 question. I came up with the solution immediately since it's something I've done in the past two months. The interviewer added a small spin on it where he wants something a little bit more. The modification was very easy, the spin did not change the difficulty of the question in my opinion, but would test whether I simply memorized the solution or understood it perfectly. We ended the session with plenty of room to talk about things. I asked a question about the work experience only since I was just exhausted to the brink. &lt;/p&gt;

&lt;p&gt;The next day the recruiter asked me for a zoom meeting, this is always a good sign but I was too depressed to perceive that way. Additionally, a lot of recruiters just like to reconnect immediately after the onsite just to see the chances before he has a chance to get feed back from the team. He asked me how I thought the onsite was, I told him it was probably hopeless. However he immediately told me that the interviewers all gave me a yes and they thought I did well. &lt;/p&gt;

&lt;p&gt;I was shaking again lol... it was just too much of a surprise. He then started talking about the salary and gave a number higher than my original request, which is 150k as I have seen from most recruiter emails. I was super overwhelmed. It was truly unbelievable since I was SURE that it was doomed. &lt;/p&gt;

&lt;p&gt;He reassured me again that they will be giving an offer, but cannot do that without the financial approval. He then focused the discussion on how much they would have to offer to detract me from continuing to interview, which was flattering at the highest level to me. It was just all too much, all I remembered was the shaking. &lt;/p&gt;

&lt;p&gt;I did not say yes to the offer out of principle and told them that I have an Amazon and Google interview in the next two weeks; it's true I really do lol. Unfortunately I had to reject the Google interview since the offer letter expires on the day of the Google onsite. As for the Amazon one, I am somewhat optimistic but that's a story for next week when I hear back from them. &lt;/p&gt;

&lt;p&gt;Thanks for everyone who's been reading my articles. It's been really helpful to type out my thoughts for each question and get some positive feedback throughout these past months. Thank you all and hopefully next week I can title it: &lt;/p&gt;

&lt;p&gt;"Leetcode Diary: I am Amazonian!!!"&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>devjournal</category>
      <category>motivation</category>
      <category>career</category>
    </item>
    <item>
      <title>Leetcode diary: 33. Search in Rotated Sorted Array</title>
      <dc:creator>kevin074</dc:creator>
      <pubDate>Sun, 27 Feb 2022 09:53:39 +0000</pubDate>
      <link>https://dev.to/kevin074/leetcode-diary-33-search-in-rotated-sorted-array-1d4b</link>
      <guid>https://dev.to/kevin074/leetcode-diary-33-search-in-rotated-sorted-array-1d4b</guid>
      <description>&lt;p&gt;This is a new series where I document my struggles of leetcode questions hoping seeing however small of an audience I get gives me the motivation to continue.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/search-in-rotated-sorted-array/"&gt;link&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Binary search on steroids!! This is probably a good question to keep coming back to every so often so that you can check whether you have forgotten modified binary search problems.&lt;/p&gt;

&lt;p&gt;Given an array of sorted distinct integers, and the fact that each of them is rotated by some random constant K indices, find the index where the target resides or return -1. K is not given.&lt;br&gt;
The question specifies that you have to do this in log N time.&lt;/p&gt;

&lt;p&gt;Since it has to be log N, it must means binary search. So the questions is how do you do binary search in a rotated array?&lt;/p&gt;

&lt;p&gt;Recall that binary search requires the array to be sorted, but that's not really the case in a sorted array that was then &lt;em&gt;rotated&lt;/em&gt;. So we can have: [4,5,6,7,8,9,1,2,3]. How would we go about finding, say 6 in the array? &lt;/p&gt;

&lt;p&gt;scroll after you think you have some idea how to do binary search on rotated sorted array first ... &lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
The answer is that what if you find the inflection index, aka the index of the smallest value in the array, and then do &lt;strong&gt;2&lt;/strong&gt; binary search on this array? We can do one that starts from 0 and ends at inflection -1 and the other inflection to end of array.&lt;/p&gt;

&lt;p&gt;So how do we go about modifying the binary search ?&lt;br&gt;
recall that this is the general formula for binary search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function binarySearch (nums, target) {
    let start,mid,end;
    start = 0; end = nums.length-1;

    while (start &amp;lt;= end) {
        mid = Math.floor((start+end)/2);
        if(nums[mid] === target) return mid;

        if (mid &amp;gt; target) {
            end = mid-1;
        } else {
            start = mid+1 
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should definitely have this (or a version of this) memorized. The question then becomes how do we do this to find the inflection point? &lt;br&gt;
The binary search has two main parts:&lt;br&gt;
1.) what is the target&lt;br&gt;
2.) how do we move if mid != target&lt;br&gt;
We don't exactly have a target value for the array, since the inflection point number value can be anything. We only know that it is the smallest. However, we also know that this is a &lt;strong&gt;rotated sorted&lt;/strong&gt; array. This means that all elements are supposed to be smaller to bigger, but because of the rotation, &lt;strong&gt;some index somewhere goes from bigger to smaller&lt;/strong&gt;. &lt;br&gt;
So we can modify the mid check with:&lt;br&gt;
&lt;code&gt;if(nums[mid-1] &amp;gt; nums[mid]).&lt;/code&gt;&lt;br&gt;
If the array is actually unrotated, then can we still get the inflection point? The answer is yes. Technically the nice thing about this specific binary search formula is that the in the specific case of unrotated array, the start value will be the smallest value index, which is 0 of course.&lt;/p&gt;

&lt;p&gt;Now the question is how do we move without a target? The mental gap is that binary search relies on sorted array, but more technically, a sense of definitive direction. Would we have a definitive sense of direction? Technically yes, this what could happen&lt;br&gt;
1.) nums[mid] &amp;gt; nums[end]&lt;br&gt;
2.) nums[mid] &amp;lt; nums[end]&lt;/p&gt;

&lt;p&gt;nums[mid] &amp;gt; nums[end] happens when the rotation has past (nums.length/2), this means that the inflection is at the later half, like: [3,4,5,6,7,8,1,2]&lt;br&gt;
if not past half length rotation:&lt;br&gt;
[5,6,7,8,1,2,3,4]&lt;br&gt;
[7,8,1,2,3,4,5,6]&lt;/p&gt;

&lt;p&gt;nums[mid] &amp;lt; nums[end] means the rotation hasn't gone too far, so we can go left side to find the smallest value&lt;/p&gt;

&lt;p&gt;So what we should do to find inflection is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    let start, mid, end;
    start = 0; end = nums.length-1;

    while ( start &amp;lt;= end ) { //find inflection
        mid = Math.floor((start+end)/2);

        if(nums[mid] === target) { return mid } 
        if(nums[mid-1] &amp;gt; nums[mid] ) { start = mid; break; }

        if(nums[mid] &amp;gt; nums[end]) {
            start = mid+1; //find later half
        }
        else {
            end = mid-1; //find in first half
        }
    }

    const inflection = start;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in interview, you'll probably want to run through a simple case like [7,1] and prove that you'll get start as inflection.&lt;/p&gt;

&lt;p&gt;Now that we have the inflection done, that's literally 95% of the work! The rest is to run through 2 binary searches one ends with inflection-1 while the other starts at inflection and that's it! Full code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var search = function(nums, target) {
    let start, mid, end;
    start = 0; end = nums.length-1;

    while ( start &amp;lt;= end ) { //find inflection
        mid = Math.floor((start+end)/2);

        if(nums[mid] === target) { return mid } 
        if(nums[mid-1] &amp;gt; nums[mid] ) { start = mid; break; }

        if(nums[mid] &amp;gt; nums[end]) {
            start = mid+1;
        }
        else {
            end = mid-1;
        }
    }

    const inflection = start;

    start = 0;
    end = inflection - 1;
    while ( start &amp;lt;= end ) { //&amp;lt;= to not check start after while ends
        mid = Math.floor((start+end)/2);

        if(nums[mid] === target) { return mid }

        if(nums[mid] &amp;gt; target) {
            end = mid-1;
        }
        else {
            start = mid+1;
        }
    }

    start = inflection;
    end = nums.length - 1;
    while ( start &amp;lt;= end ) { //&amp;lt;= to not check start after while ends
        mid = Math.floor((start+end)/2);

        if(nums[mid] === target) { return mid }

        if(nums[mid] &amp;gt; target) {
            end = mid-1;
        }
        else {
            start = mid+1;
        }
    }

    return -1;

};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me know anything on your mind after reading through this, THANKS!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>algorithms</category>
      <category>devjournal</category>
      <category>motivation</category>
    </item>
  </channel>
</rss>
