Sunday, December 11, 2022

Frontend system design interview notes

First of all, _make sure you understand the whole picture_. This means you need to ask _many_ questions before jumping on actually hatching out a plan.

Also very important note is that 99% of the time any solution will have PRO-s _and_ CON-s. This is very important from a designing perspective as (the more senior the role is) we will need to weigh in both sides.

Here is a pretty good mock interview: https://www.youtube.com/watch?v=VM2_4IXkMZ0

Also from the same author here is a textual version of the above video: https://www.feinfra.com/ 

Questions about the product:

  • liveness of the data
    • REST
    • websockets
  • who is the audience (users)
    • how well educated are they in terms of the app
    • will the product allow users's users (kinda admin)
  • what kind of team do we already have? are they already familiar with e.g. React?
  • how long is the project plan? (6 months? 2 years?)
  • what kind of user audience size do we expect? should we worry about scaling our product at this stage?

Important topics

  • bare minimum html/js vs Next.JS SSR vs SPA
  • CI/CD
  • testing
  • optimization
    • minifying css/js
    • optimize media assets
  • monitoring
    • DataDog / Sentry / Google Analytics / ...
  • security
    • XSS, CSRF, SQL injection, ...
  • A/B testing
  • CDN
    • Content Delivery Network (I keep forgetting this name..)
  • code infrastructure setup
    • monorepo / multiple repos
    • shared UI component library
    • service-oriented architecture: teams focusing on each part of the domain, pro-s / con-s
  • related to the previous point: do we have a design system already?
    • css framework like tailwind?
  • sharing types between FE and BE
  • API contracts
    • OpenAPI, GraphQL, etc..
    • ProtoBuff - code generation like React hooks (wow)
  • state management
    • React Context
    • zustand / jotai / Redux / ...
  • router
    • react router e.g.
  • do we have OKR-s set?
  • SLA-s
    • contenful paint
  • (Google's) Core Web Vitals
    •  (source)
    • The Largest Contentful Paint (LCP) checks the render time of a page’s main content when it starts loading. The main content is generally the largest image or a text block in the viewport – a visible area of a web page on a user’s device.
    • The First Input Delay (FID) measures input latency – how long it takes for a site to respond to a user’s input. This includes key presses, taps, and clicks on buttons, links, and videos or audios on a page.
    • The Cumulative Layout Shift (CLS) measures visual stability and checks whether there is an unexpected layout shift in the page.
  • wireframing?
  • styling guidelines
    • styled components
    • css modules

Monday, December 5, 2022

JS can surprise me still to this day (Array toString() is join())

I didn't know but these expressions yield the same result in JavaScript:

const a = [1,2,3];

console.log(a.join(','));

console.log(`${a}`);

I think it makes sense, but still, the language still today can surprise me.

Thursday, September 15, 2022

Jest test array with objects without order

Hello internet!

As I was doing my regular weekday I met a surprisingly unsolved problem in Jest, namely what if I wanted to test an array's _content without order_?

So e.g. these 2 arrays should equal

[{cat: 'Takira'}, {cat: 'Inari'}]

and

[{cat: 'Inari'}, {cat: 'Takira'}].

There is an SO post about this, but it doesn't care about objects, but only primitives. Also it points to Jasmine (which does have this as a native feature), but not Jest.

So here is my generic solution to the problem

for (obj in array) {

    expect(obj).toEqual(

        expect.arrayContaining([

            expect.objectContaining(obj)

        ])

    );

}

Let's go through this step by step!

So we are looping through the array (so far so good) and then we simply expect that object to be in the array.

That's literally it.

Thank You For Coming to My TED Talk.

Sunday, September 11, 2022

A painful lesson I learned while putting out fire

Imagine you have a service that's unresponsive, yet you can see in your production environment it yields 500-s for every request. SLO-s are fine, no alert is being invoked, everything seems to be normal.

What do you do?

At first, I didn't know what to do, but after the first shock I had the - not that imaginative - idea to restart the service. For our production evnironment we use shipit as a helper for these kind of situations. As a long time software engineer I am familiar with a lot of tool, but this was the first time looking at the shipit user interface. So I went back to my roots where we restarted services by a new deployment. That was arguably not the best decision I admit, yet there I was trying to put out fire. The new deployment went through! Everything should be back up again and running smooth like a sailboat! Right. Right? Right??

Well, this should've been the case, but when I went back to check on the service, it showed still the same error. Bummer.

What to do now?

Let's check logs.

OK, logs show practically nothing. I mean, nothing for the past 10 minutes.

That's not good.

How will I know what's happening inside the container?

OK, calm down. This is a great challenge that you can solve. Embrace it.

Cool, let's have a look what was the last thing the container logged!

Maximum call stack size exceeded.

That's not good. What could possibly cause that so badly that the service stops reporting?

Let's check the stacktrace.

Something-something.. loggerInstace .. something-something.. winston..

Ok, so something's wrong with logging? 

Ouch.

So we don't know anything about the inner parts of the service, because the _logging_ has issues.

In the meantime I tried to redeploy again, same result - 500-s after the deployment.

This is not looking good.

BUT! Teammates are there for you when you them the most! Sergei taught me that Shipit has a "restart" feature!

OK, let's do that.

It works.

WHAT.

Damn.

So when we deployed shipit didn't actually do any changes? Weird.

Let's check the kubernetes pods.

They are old. They definitely didn't restart when I redeployed.

Saturday, February 12, 2022

Cancellable Promises

 Have you ever been in a situation where React tried to update a component that has been already unmounted?

This can be easily witnessed when your business logic is relying on some asynchronous code that would update the state once a promise resolved.

How can we prevent that from happening?

Meet cancellable.


So why is this so cool? And how can I use this?

Do you remember that useEffect has a cleanup method? That's the function that's returned inside the useEffect's callback method. You can take care of situations when components are unmounted e.g.

Sounds familiar? That's the problem we started with!

So basically, if you return a cancellable inside a useEffect, it takes care automatically of the cleanup as it's gonna set the cancelled variable, and later when trying to do some state updates, our logic will prevent that because of this peace of code: .then((v) => cancelled || ok(v)). cancelled will prevent from calling the ok method (in our case it could be a setState).

And that's it! Now you have a neat little function that is taking care of Promises that are still unfinished by the time the component has already been unmounted!