Sunday, July 30, 2023

The road is still long. 😀

 


I had a good time chit chat at the weekend with a friend who was also a developer. He told me that he had a feeling like if you were not constantly studying in software development, you were falling out of software development.


So, he got burned out, mental illness, experience low motivation. Eventually, he changed the career.

Sometimes it feels like that. Sometimes. A software developer's job is stressful and can affect their mental health. We shouldn’t be too hard on ourselves. Especially, those that want to have a life outside of coding. I highly recommend it. Does wonders for your mental health. I see people on Twitter who seemed to have no life. It’s no good to do a bunch of coding then go home and do a few hours more. Unless you are studying for a cert, of course. Get some hobbies. Don’t forget you have a family or SO, if that’s the case.

Coding is not a lifestyle; Coder is just a normal occupation like the others - no more noble, no more superiority; it’s paycheck, a future. Don’t let it define you anymore than those that separated or retired from the military should let their service completely define them. That will lead to mental health issues. I’ve heard of a few situations.

Wednesday, July 19, 2023

System Design 101 - CAP Theorem

CAP Theorem - When you can not desire everything at once

This theorem states that any distributed system can only provide two of the following three guarantees simultaneously:
  • Consistency: all nodes in a distributed system see the same data at the same time
  • Availability: every request receives a response, without guarantee that it is up-to-date (RUN 24/7 - no downtime)
  • Partition tolerance: system continues to function even when network partitions occur. (Machines are in different network)

 

Suppose we have to design a simple system of 2 ATMs that link together. When the user withdraws from ATM1, the amount of money must update to ATM2 as well.

We cannot design a system that concludes CAP because, to have C (consistency), data must be updated at once between ATM1 and ATM2. But if the link between ATM1 and ATM2 is broken, when a user withdraws on ATM1, ATM2 will be out of date, and then C(consistency) is violated. To solve it, we have to stop ATM1 and ATM2 operations to make sure that all is available to update the data; this violates A (Availability) of the system.

Now, We engineers will have to trade off one element. In the case of the ATM, we have the following combinations:

  • CA: Not considering taking this case into account since in distributed systems, Partition tolerance is a must. Due to mis-synchronization, missing Partition tolerance in an ATM situation will cause Consistency to violate.
  • CP: Due to the constraint that Consistency is a must, Partition tolerance will make the system unavailable since it cannot guarantee consistency.
  • AP: Prefer Availability and Partition tolerance over Consistency. The ATMs always work, even when the connection between 2 ATMs is broken Partition tolerance. It's not consistent but can be solved later when 2 ATMs are connected again. So, this is the best solution.

Designing a system is not an easy task: vague, abstract, requires estimation, and requires thinking about something before it happens. In the real world, even after picking 2 elements out of 3, it's not always balance (50-50) between 2 factors. Sometimes, we have to trade off making one factor more important than the other to reduce complexity. Example: There is no 100% availability, and Partition tolerance may take time to become active and make synchonization.


#systemdesign101

Friday, June 16, 2023

Boost performance and security with modern networking

Hey there, fellow developers! I had a chance to participate in a session of “Boost performance and security with modern networking” in the Apple WWDC. Here is the quick summary I think I should share: 



Do you want to make your app faster, safer and smarter so that it can deliver more value to the client business? Of course, you do! That's why you need to know about the latest and greatest networking technologies that can boost your app's performance and security. In this post, I'll give you a quick overview of some of the most important networking protocols that you should be using in your app: IPv6, HTTP/2, TLS 1.3 and Encrypted DNS. Let's dive in! 

1. Using IPv6. 
IPv6 has a number of benefit that you should consider:
- Larger Address Space: 3.4 x 10^38 unique IP addresses on v6 vs 4.3b on v4  
- Improved Security: IPv6 comes with built-in security features including IPsec, which offers data integrity, authentication, and encryption for internet traffic.
- Simplified Header Format: compared to IPv4, IPv6 features a simpler and more effective header structure, which lowers processing costs and boosts the speed of the internet connection
- Prioritize: IPv6 offers stronger support for QoS features, allowing internet service providers to priorities traffic and guarantee that essential applications, like voice and video, receive the required bandwidth and low latency
- Improved Support for Mobile Devices: smartphones and tablets could gain a lot of benefits from IPv6 with quicker and more efficient in term of connection


2. Upgrade to HTTP/2
HTTP/2 attempts to solve many of the shortcomings and inflexibilities of HTTP/1.1
- Multiplexing and concurrency: many requests can be sent and getting responses with just one connection
- Header compression: HTTP header size is drastically reduced
- Server push: The server can send resources the client has not yet requested
You can see how fast HTTP/2 much faster compared to HTTP/1 in here

2.1 Upgrade to HTTP/3
HTTP/3 will be the first major upgrade to the hypertext transfer protocol since HTTP/2 was approved in 2015. An important difference in HTTP/3 is that it runs on QUIC, a new transport protocol. QUIC is designed for mobile-heavy Internet usage in which people carry smartphones that constantly switch from one network to another as they move about their day. Some benefits
- Developing a workaround for the sluggish performance when a smartphone switches from WiFi to cellular data (such as when leaving the house or office)
- Decreasing the effects of packet loss
- Faster connection establishment: QUIC allows TLS version negotiation to happen at the same time as the cryptographic and transport handshakes
- Zero round-trip time (0-RTT): For servers they have already connected to, clients can skip the handshake requirement
- More comprehensive encryption: QUIC’s new approach to handshakes will provide encryption by default — a huge upgrade from HTTP/2 — and will help mitigate the risk of attacks. More info

3. Upgrade to TLS 1.3
TLS 1.3 is the latest version of the TLS protocol. TLS 1.3 dropped support for older, less secure cryptographic features, and it sped up TLS handshakes, among other improvements. So, it is considered to be better and safer than TLS 1.2. 
The benefits:
- Improved Performance and Efficiency: TLS 1.3 handshake is faster than TLS 1.2 due to one round trips instead of two.
- More Robust Security: 
-- Perfect Forward Secrecy - discard the encryption keys for every session (no more static like TLS 1.2)
-- Simple and Stronger Cipher Suites:

4. Encrypted DNS
Traditionally, DNS queries and replies are performed over plaintext. They are sent over the Internet without any kind of encryption or protection, even when you are accessing a secured website. This has a great impact on security and privacy, as these queries might be subject to surveillance, spoofing and tracking by malicious actors, advertisers, ISPs, and others. To prevent this and secure your connections, your server communication should support DNS over TLS (DoT) and DNS over HTTPS (DoH), two standards developed for encrypting plaintext DNS traffic. This prevents untrustworthy entities from interpreting and manipulating your queries.
#happycoding

Tuesday, February 14, 2023

Being laid off or jobless is that bad?

One question I started asking myself a few years ago is what are the purposes of my life in other words, what motivates me daily when I wake up in the morning?

... and do you know that question kept unanswered during recent years. The reason is having a 9-to-5 job keep me busy, since I focus on working to deliver best possible outcomes to the company. It turns out that having a job to secure monthly pay check does not help me feel good even though it helps me cover my monthly expenses.

Until 2 months ago, I decided to move out of the comfort zone, and to come back to VN, and again the rush of having a pay-check job put me into that loop again until I finally moved out of it again. During last 2 weeks I am jobless, but I am so happy. I believe a lot of people will think it is crazy, but it actually is. After many years continuously working I didn't have time to think about this biggest question of my life, and find my life's goals.

Since being jobless, I don't need to care about company works, and I have more time to do these things:

- Read books. I've read so many books until now, and I started with some small books (less than 150 pages per book). I read 5 of them already.

- Watch dozens of videos about life's advices on YouTube.

- Enroll a course to find meaningful of life.

- Join some communities to get more motivations.

Fortunately, after few weeks I finally see the light at the end of the turnel, I somehow feel that I found the direction in my life. I don't mean goals are crazy but they show me how my life is going to be.

Will I open to work again? Definitely yes, but perhaps not right now :)

.

I believe in worse situations you can still find your ways to get out of it, and to be a better version of yourself. Thus, I would recommend anyone was laidoff or being jobless not to be frustrated, but be optimistic.

Remember you always have a choice, and having a choice is a powerful right.

Monday, February 13, 2023

Flutter 3.7: What’s New

2023 has just begun with a new exciting release for Flutter i.e version 3.7. As it continues to evolve, there is no doubt that Flutter will continue to be one of the widest used cross-platform development frameworks. 

Let’s take a quick look at the improvements that come along with the new version:

Improved Material 3 Support:

Photo by Kevin Chisholm on Medium

Migration of certain widgets has improved the Material3 experience. Some of these widgets include Badge, Bottombar, Menus, DropdownMenu, Snackbar and TabBar.

In order to use the new features you just need to turn on the useMaterial3 flag in the app’s ThemeData widget.

Menu Bars and Cascading Menus:

This release of Flutter introduces the ability to create menu bars and cascading context menus. For macOS, developers can use the PlatformMenuBar widget to create a menu bar that is rendered by macOS natively, instead of by Flutter. 

Additionally, for all platforms, developers can use the Material Design menu that provides cascading menu bars (MenuBar) or standalone cascading menus triggered by another user interface element (MenuAnchor). 

These menus are fully customizable, and the menu items can be custom widgets or use the new menu item widgets (MenuItemButton, SubmenuButton).

Impeller Preview:

A new Impeller rendering engine that is now available for preview on iOS on the stable channel. The performance of Impeller is believed to be comparable or better than the Skia renderer for most apps, and it implements all but a small number of rarely used corner cases.

iOS release validation:

The flutter build ipa command now includes a feature that checks and validates certain settings for iOS apps before submission to the App Store. 

This helps ensure that the app is ready for release by informing the developer of any changes that need to be made before submission. 

This new feature is a checklist of settings to update which helps developers to prepare the app for release.

DevTools Updates:

This new SDK includes several new tooling features and improvements for developers using Flutter. One of the major improvements is in the DevTools Memory debugging tool, which has undergone a complete overhaul and includes three new feature tabs: Profile, Trace, and Diff. These tabs support all the previously supported memory debugging features and add more for ease of debugging. 

The new features include the ability to analyze current memory allocation for the app by class and memory type, investigate the code paths that are allocating memory for a set of classes at runtime, and compare memory snapshots to understand memory management between two points in time.

Photo by Kevin Chisholm on Medium

Custom Context Menus:

The new context menu feature in Flutter allows developers to create custom context menus for different parts of their app, giving them more control over the user experience. This feature works by adding a new contextMenuBuilder parameter to existing widgets that already show a context menu by default, such as TextField.

Developers can return any widget they want from the contextMenuBuilder, including modifying the default platform-adaptive context menu. This feature can also be used outside of text selection, such as creating an Image widget that shows a Save button when right-clicked or long-pressed.

CupertinoListSection & CupertinoListTile widgets:

Cupertino has two new widgets, CupertinoListSection and CupertinoListTile, for showing a scrollable list of widgets in the iOS style. They are the Cupertino versions of ListView and ListTile in Material.

Scrolling Improvements:

This change will allow users to return null from the itemBuilder and indicate the end of the list, making it easier for them to work with scrolling widgets like ListView. 

Additionally, the new Scrollbars and DraggableScrollableSheet widgets will provide more control and customization options for scroll views, and the improved handling for text selection within scrolling contexts will make it easier to select text in scrolling views.

Internationalization Tools and Docs:

Internationalization support has been completely revamped.  The gen-l10n tool now supports:

  • Descriptive syntax errors.
  • Complex messages involving nested/multiple plurals, selects, and placeholders.

Text magnifier:

The magnifying glass that appears during text selection on Android and iOS now works in Flutter. This is enabled out of the box for all apps with text selection, but if you want to disable or customize it, see the magnifierConfiguration property.

Reduce animation lag on iOS devices:

Animation quality has greatly improved with the new version of Flutter, thanks to open source contributors.

Font asset hot reload:

Including new fonts to the pubspec.yaml file previously required the app to be rebuilt, unlike other assets which could be hot reloaded. This problem has been solved in Flutter 3.7.

Custom Shader Support Improvements:

Custom shaders can now be hot reloaded and the new Flutter SDK contains a shader compiler that is responsible to correctly compile the listed shader in pubspec.yaml to the relevant backend-specific format for the target platform.

toImageSync:

This release adds new methods, Picture.toImageSync and Scene.toImageSync, to dart:ui. These methods are similar to the asynchronous methods, Picture.toImage, and Scene.toImage, but they synchronously return a handle to an Image. 

The rasterization for the Image takes place in the background and the image is kept as GPU resident when a GPU context is available, which makes it faster to draw compared to images produced by toImage. 

These new toImageSync APIs are useful for quickly snapping off an expensive-to-rasterize picture for reuse across multiple frames, applying multi-pass filters to a picture, and applying custom shaders.

Support discontinuation for macOS 10.11-10.13:

Flutter has announced that it will no longer support macOS versions 10.11, 10.12, and 10.13. This decision was made after further analysis revealed that removing support for these versions would have limited additional impact, and would simplify the codebase.

 This means that apps built against stable Flutter SDKs with this release and onward will no longer work on these versions, and the minimum macOS version supported by Flutter increases to 10.14 Mojave.

Consequently the OpenGL backend has been removed from both the iOS and macOS embedders which has reduced the compressed size of the Flutter engine by about 100KB.

Memory Management

This release of Flutter includes several improvements to memory management that aim to reduce lag caused by garbage collection pauses, lower CPU utilization due to allocation velocity and background GC threads, and reduce the overall memory footprint. 

One example of this is expanding the existing practice of manually deallocating native resources that back certain dart:ui Dart objects. Benchmarks of the Flutter framework migrated to this API have shown that these improvements can reduce 90%-ile frame build times by up to more than 30%, resulting in smoother animations with less jank. 

Photo by Kevin Chisholm on Medium

Additionally, the Flutter engine no longer registers the size of GPU images with the Dart VM, which eliminates synchronous GC work while building frames when a widget creates GPU resident images. The Flutter Engine also does a better job of dynamically updating the Dart VM with information about Flutter application state. 

Finally, for add-to-app Flutter applications, the Flutter engine now informs the Dart VM when the Flutter view is no longer displayed, this causes the Dart VM to trigger a final major GC for the Isolate associated with the view which reduces Flutter's memory footprint when no Flutter views are visible.

Saturday, February 11, 2023

Common Mistakes That Junior Developers Should Avoid

A career as a developer in any sector is pretty challenging. The profession can appear even more daunting when you are a junior developer. The lack of formal training about real-world software development scenarios during college days leaves the developers to learn on their own. Hence, they make many novice mistakes that stick for a long time. Without proper guidance, the initial habits can slow down the junior developer’s career progression.

Everyone makes several of these beginner’s mistakes during the initial phases of their career. If you are passionate about making it big in your development sector, here is a list of the top ten common mistakes you need to be aware of as a junior developer.


Focusing on Code Instead of the Big Picture

It’s easy to get bogged down in the details when you’re starting out. But it’s important to remember that code is only a small part of the development process. Focusing on the big picture will help you understand the overall goal of your project and help you make better decisions. To come up with good solutions, you need to spend time thinking. You have to remember that the author of React did not come up with the idea for the framework in a day. You have to focus on your target and follow up on whatever you need to get to that target.

Not Knowing Their Self Worth

When developers are fresh out of their institutions or when they are out in the market looking for a job, they most likely have no idea about their worth. Depending on individuals, they either overestimate their capability or underestimate it. In either case, not knowing is not helpful to get the right start to their career.

Developers who overestimate their capabilities tend to have high expectations from their first job. They feel they are doing the company a favor. This mindset reflects in the interviews and, later, in their work.

Again, developers who underestimate their abilities tend to take the very first offer they get. They do not try to find out if they are paid as per the market standard. They also prefer not to ask what kind of work they will be offered or whether the work culture is flexible and a good fit for them.

It is not always easy to negotiate during your first job search. Circumstances can compel you to start earning as early as possible. If that is the case, surely you can latch on to the first software job you get. Once you start making money, you can further your career in your own time and money. You can also find out if a position is suitable for you by doing a bit of research on the internet. Learn about the company culture from the reviews provided by employees on various sites.

Not Reading Documentation

Junior developers rarely read documentation, or they only read it superficially. They often skip it and start working on a subject or solving their problem. But the fact is that documentation is an important source of information. And you need to read it in-depth if you want to be a successful developer.

Documentation can help you learn the syntax and usage of a language or library, as well as how to use a tool or library properly. It can also help you understand the API for a particular software system. So, be sure to read the documentation.

Not Asking Questions

A common mistake junior developers often make is they do not ask questions proactively. Some developers are shy in asking questions. Others might be hesitant because they think their query might be a silly on.

Whichever might be the reason, they need to overcome the hurdle to be successful in their career. They should ask questions every time they do not understand. People will be more than happy to explain when they are on the topic.

Sometimes, the question will not have a straightforward answer. People might give their opinion based on their knowledge. If you are not satisfied, you can ask someone else to confirm your understanding. The idea is to clear out any doubt as quickly and as confidently as possible.

Lacking of Practice

Junior developers often underestimate the importance of practice. It’s not enough to just learn the theory — you also need to practice what you have learned.

Practice makes a man perfect, and the more you practice, the better you will become at your work. Try to find opportunities to practice your skills, whether it’s through tutorials, exercises, or projects. No one is born as a great developer. They become one by working hard and practicing‌.

They should practice according to their field of work. If you are a software developer, work hard on your problem-solving skills, programming languages, and accuracy and attention to details. These sometimes may seem very easy for you, but if you want to develop these skills, then you have to practice them. Everything takes practice!

Conclusion

This list summarizes experiences shared by other developers over the year and my experience as well. As a unique individual, your experiences might vary from others. If you remain vigilant and stay away from these mistakes, you can achieve a great start as a developer. Hence, understand the mistakes and take action based on your situation. I am sure, armed with the above knowledge and perseverance, you can achieve the professional and personal goals you set for yourself.

Source

Thursday, February 9, 2023

Copy-On-Write In Swift

 Types in Swift fall into one of two categories

* Value Type: where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple. 

* Reference types: each instances share a single copy of the data, and the type is usually defined as a class.

What is Copy On Write

Copy on write is a common computing technique that helps boost performance when copying structures. To give you an example, imagine an array with 1000 things inside it: if you copied that array into another variable, Swift would have to copy all 1000 elements even if the two arrays ended up being the same.

This problem is solved using copy on write: when you point two variables at the same array they both point to the same underlying data. Swift promises that structs like arrays and dictionaries are copied as values, like numbers, so having two variables point to the same data might seem to contradict that. The solution is simple but clever: if you modify the second variable, Swift takes a full copy at that point so that only the second variable is modified - the first isn't changed.

Warning: copy on write is a feature specifically added to Swift arrays and dictionaries; you don't get it for free in your own data types.

Implement Copy-on-Write for your custom value type

```

final class Ref<T> {

  var val : T

  init(_ v : T) {val = v}

}

struct Box<T> {

    var ref : Ref<T>

    init(_ x : T) { ref = Ref(x) }

    var value: T {

        get { return ref.val }

        set {

          if (!isUniquelyReferencedNonObjC(&ref)) {

            ref = Ref(newValue)

            return

          }

          ref.val = newValue

        }

    }

}

// This code was an example taken from the swift repo doc file OptimizationTips 

// Link: https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-use-copy-on-write-semantics-for-large-values

```

Summary

This subject isn’t simple but understanding it is pivotal for your advancement as an iOS designer. Copy-on-write is one of the foremost imperative dialect highlights of Swift and ought not to be underestimated.

Credit

* https://holyswift.app/copy-on-write-in-swift/

* https://viblo.asia/p/hieu-ve-copy-on-write-trong-swift-maGK7bkx5j2