AI 资讯
I Thought Open Source Was About Code. I Was Wrong.
The biggest lessons I learned from open source contributions weren't found in the code itself. Communication, collaboration, and workflows matter more than I expected. For a long time, I hesitated to contribute to open source. Part of it was because I assumed that contributing meant writing code. As a self-taught developer, that felt intimidating. The other part was "Git anxiety." Forks, branches, pull requests, merge conflicts, and CI checks all seemed like a lot to understand before I could even make a contribution. Eventually, I started small. Instead of focusing on code, I looked for opportunities to improve documentation, README files, and learning materials. What surprised me was that writing the actual change was often the easy part. Most of my learning happened outside the code itself: understanding contribution guidelines, repository workflows, automation, and review expectations. Over time, I realized that modern open source contribution is about much more than just writing code. Contribution Model Has Changed When many people think about open source contributions, the mental model is still fairly simple: Find Bug ↓ Write Code ↓ Open PR In reality, I realized that most modern repos involve much more than that. Before making a change, contributors often need to understand project workflows, CI pipelines, automated checks, contribution guidelines, and review expectations. The code change itself might only take a few minutes, while understanding how the repo operates can take much longer. A modern contribution often looks more like this: Understand Repository ↓ Understand Workflow ↓ Understand Automation ↓ Make Change ↓ Open PR ↓ Respond to Review It looks intimidating, but I think this flow helps projects stay maintainable as communications grow. What I've learned from contributing to different projects is that open source is not just a coding skill. It's also a collaboration skill. The faster you can understand how a project works, the easier it becomes to
开发者
C# 14: The `field` Keyword — Cleaner Properties, Zero Boilerplate
C# 14: The field Keyword — Cleaner Properties, Zero Boilerplate Every C# developer has been there. You start with a clean auto-property, then requirements change and you need to add a tiny bit of validation. Suddenly that one-liner explodes into six lines of boilerplate — a private backing field, a getter that just returns it, a setter that assigns it. The logic is two words. The ceremony is everything else. C# 14 fixes this with the field keyword: a contextual keyword that refers to the compiler-synthesized backing field of a property, letting you write custom accessor logic without ever declaring an explicit field. The Problem: Boilerplate Tax on Simple Properties Auto-properties are one of C#'s best quality-of-life features. This is clean: public string Username { get ; set ; } But the moment you need to trim whitespace on assignment, that cleanness evaporates: private string _username = string . Empty ; public string Username { get => _username ; set => _username = value . Trim (); } You now have six lines — and four of them exist only to hold the shape of the pattern together. The backing field _username is not carrying any meaningful design weight. Its only job is to be a storage slot that Username uses privately. You already know the compiler creates one for auto-properties. You are just forced to make it visible so you can reference it. This is the boilerplate tax. You pay it every time you add even the smallest piece of logic to a property. Why field Exists The C# language team has discussed this friction for years. The challenge was finding syntax that is: Unambiguous — no conflict with existing identifiers Familiar — consistent with how value works in setters Scoped — only meaningful inside a property accessor The solution landed in C# 14: the contextual keyword field . Just like value refers to the incoming assignment in a setter, field refers to the hidden backing storage the compiler manages for the property. It is contextual, which means it only acts
AI 资讯
🔥 The Sales Call Is Not a Performance — It's a Diagnosis
I have watched founders lose sales calls they should have won. Not because they lacked skill. Not because the offer was wrong. Because they walked in to prove they were smart — instead of finding out whether the pain was real. Sales Is Diagnosis Plus Decision The call is not there for you to pitch. The call is there to find out: Is the pain real? Does the buyer have urgency? Does the budget exist? Can a fixed-scope sprint create a clear win? That is it. Four questions. Everything else follows from those. Sales is not pressure. Sales is diagnosis plus decision. 1️⃣ The Call Structure That Works Frame the call in the first 60 seconds: "I'll understand the current state, ask what is costing you, then tell you whether a sprint makes sense. If it doesn't, I'll say so." That sentence does 3 things: Sets expectations — no pressure, no hard close Signals competence — you have done this before Removes the buyer's guard — they can be honest about what is broken Then run this flow: 1️⃣ Current state — what exists now? 2️⃣ Pain — what is broken or slow? 3️⃣ Cost — what does it cost in time, money, trust, or delay? 4️⃣ Urgency — why now? 5️⃣ Decision — who approves? 6️⃣ Success — what would make this worth paying for? 7️⃣ Close — recommend the sprint or walk away 2️⃣ The Questions That Reveal Money These are the 6 questions I use to find whether a sprint is worth recommending: "What happens if this stays broken for another 30 days?" — reveals urgency and cost "What have you already tried?" — reveals how serious they are "Where does the current process lose leads, users, time, or trust?" — reveals the money leak "Who feels this pain most inside the business?" — reveals whether the buyer is also the decision-maker "What would make this an obvious win?" — reveals success criteria before you price "If we fixed only one thing first, what would matter most?" — reveals scope Listen for the answer with the money in it. That is the thing you fix. That is what you price. That is the sprin
产品设计
Building a Liquidity Monitoring Engine for a Polymarket Trading bot: Architecture, Strategy, and Real-Time Market Intelligence
In every successful Polymarket Trading bot, liquidity monitoring is one of the most overlooked yet...
AI 资讯
Stop Whispering to the Model, Start Furnishing Its Brain
Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is...
开发者
Implementing Protected Routes and Authentication in React (2026 Edition)
This is an updated rewrite of my 2021 article on protected routes . A lot has changed in the React ecosystem since then. React Router moved from v5 to v7, class components have faded out, and the patterns we use for authentication state have matured. This version reflects how protected routes are built in modern React applications. Almost every web application requires some form of authentication to prevent unauthorized users from accessing parts of the application meant for signed-in users only. In this tutorial, I'll show how to set up an authentication flow and protect routes from unauthorized access using modern React patterns: function components, hooks, React Router v6+, and the Context API. First things first Install the dependency: npm i react-router-dom That's it. React Router v6 and above ships as a single package, so you no longer need to install react-router and react-router-dom separately. It is worthy of note that we will not be using Redux for authentication state in this version. For something as simple as "is the user logged in?", React's built-in Context API is the standard approach today. Redux still has its place, but it is overkill here. The Auth Context Instead of writing to localStorage directly from components and reading it in random places, we centralize authentication state in a context. This gives us a single source of truth and a clean useAuth() hook we can call anywhere in the app. Create ./src/auth/AuthContext.jsx : import { createContext , useContext , useState } from " react " ; const AuthContext = createContext ( null ); export function AuthProvider ({ children }) { const [ user , setUser ] = useState (() => { // Rehydrate on page refresh const saved = localStorage . getItem ( " user " ); return saved ? JSON . parse ( saved ) : null ; }); const login = async ( username , password ) => { // In a real app, this is an API call to your backend. // We simulate it here with hardcoded credentials. if ( username . toLowerCase () === " admin
AI 资讯
Virtualization in Cloud Computing: Definition, Types, and Practical Guide
If you've ever spun up an EC2 instance for a side project, accessed a remote work desktop from your personal laptop, or stored files on Google Drive without thinking about the physical hard drive it lives on, you've used virtualization. As the foundational technology behind all modern cloud computing, virtualization transformed how we build, deploy, and manage IT infrastructure—cutting hardware costs significantly for enterprises and making on-demand scalability a reality for teams of all sizes. In this guide, we'll break down exactly what virtualization is, how it powers the cloud, the 6 core types of virtualization, and best practices to implement it safely and efficiently. Table of Contents What is Virtualization in Cloud Computing? Core Virtualization Concepts You Need to Know Role of Virtualization in Cloud Computing 6 Key Types of Virtualization (With Use Cases) Top Benefits of Virtualization for Teams of All Sizes Virtualization vs. Related Technologies Virtualization vs. Cloud Computing Virtualization vs. Containerization Common Virtualization Challenges and Mitigations Real-World Virtualization Use Cases Virtualization Best Practices Conclusion References What is Virtualization in Cloud Computing? Virtualization is a technology that creates virtual, software-based representations of physical hardware (servers, storage, networks, etc.) and abstracts these resources from the underlying physical machine. A software layer called a hypervisor separates operating systems and applications from physical hardware, allowing multiple isolated, self-contained systems called Virtual Machines (VMs) to run simultaneously on a single physical host. Each VM has its own virtual CPU, memory, storage, and network interface, and operates independently of other VMs on the same host. For cloud providers, this technology is the backbone of all on-demand infrastructure services, allowing them to share physical hardware across thousands of customers securely and efficiently. Core Vi
开发者
Local Time, UTC, Offset και Epoch: Ο απόλυτος οδηγός για developers
Το πρόβλημα της ώρας Η ώρα είναι από τα πιο ύπουλα προβλήματα στην ανάπτυξη λογισμικού. Αν ένας χρήστης στην Αθήνα δημιουργήσει μια παραγγελία στις 20:00 και ένας άλλος στη Νέα Υόρκη τη δει στις 13:00, ποια είναι η "σωστή" ώρα; Αν μια εφαρμογή αποθηκεύσει μόνο το 20:00, χωρίς να γνωρίζει τη ζώνη ώρας, τότε η πληροφορία είναι πρακτικά άχρηστη. Αυτός είναι ο λόγος που υπάρχουν έννοιες όπως: Local Time UTC UTC Offset Epoch / Unix Timestamp Δεν δημιουργήθηκαν για να μας μπερδεύουν. Δημιουργήθηκαν για να λύνουν το πρόβλημα της παγκόσμιας διαχείρισης χρόνου. Local Time Το Local Time είναι η ώρα που βλέπει ο χρήστης στη χώρα του. Παραδείγματα: Αθήνα: 2026-06-09 20:00 Λονδίνο: 2026-06-09 18:00 Νέα Υόρκη:2026-06-09 13:00 Όλες οι παραπάνω ώρες μπορεί να αντιστοιχούν στην ίδια ακριβώς χρονική στιγμή. Συνέβει ένα γεγονός μία ενέργεια στον πλανίτη γη ακριβώς αυτή την στιγμή που όμως για διαφορετικές γεωγραφικές περιοχές αντιστοιχεί σε διαφορετικές ώρες. Πότε χρησιμοποιούμε Local Time; Μόνο για εμφάνιση στον χρήστη. Παραδείγματα: Ημερομηνία παραγγελίας Ώρα δημιουργίας post Ημερολόγιο συναντήσεων Reports προς τον χρήστη Πότε ΔΕΝ το αποθηκεύουμε; Σχεδόν ποτέ ως μοναδική πηγή αλήθειας. Αν αποθηκεύσεις: 2026-06-09 20:00 δεν γνωρίζεις: Σε ποια χώρα δημιουργήθηκε Σε ποια ζώνη ώρας ανήκει Αν ίσχυε θερινή ώρα (DST) UTC (Coordinated Universal Time) Το UTC είναι η παγκόσμια αναφορά χρόνου. Όλες οι ζώνες ώρας υπολογίζονται σε σχέση με αυτό. Παράδειγμα: UTC: 2026-06-09 17:00 Την ίδια στιγμή με βάση την UTC ώρα μπορούμε να έχουμε: στην Αθήνα UTC+3 -> 20:00 στο Λονδίνο UTC+1 -> 18:00 στη Νέα Υόρκη UTC-4 -> 13:00 Πότε χρησιμοποιούμε UTC; Σχεδόν πάντα στο backend. Αποθηκεύουμε: 2026-06-09 T 17 : 00 : 00 Z Το Z σημαίνει UTC. Γιατί; Επειδή: Δεν αλλάζει με DST Δεν εξαρτάται από χώρα Είναι παγκόσμιο σημείο αναφοράς Ένας κανόνας που ακολουθούν σχεδόν όλες οι μεγάλες εταιρείες: Store in UTC, display in Local Time. UTC Offset Παραδείγματα: UTC+3 UTC+2 UTC-5 UTC+9 Για την Αθήνα: Χειμώνας -> UTC+2 Καλοκα
AI 资讯
Deploying a Dockerized Node.js Application on Kubernetes 🚀
After containerizing an application with Docker, the next logical step is deploying it on Kubernetes. Kubernetes helps automate application deployment, scaling, networking, and management of containerized workloads. Instead of manually running containers, Kubernetes ensures your application remains available and can easily scale when needed. In this guide, we'll deploy a Docker image of a Node.js application on Kubernetes using a Deployment and a Service. Prerequisites Before starting, make sure you have: Docker installed Kubernetes cluster running (Docker Desktop Kubernetes, Minikube, Kind, EKS, etc.) kubectl configured A Docker image pushed to Docker Hub In my case, the image was: madhavnaks/node-app:latest Why Kubernetes? Running a container using Docker is straightforward: docker run -p 3000:3000 madhavnaks/node-app:latest However, in production environments we need much more than simply running a container. Kubernetes provides: High availability Self-healing containers Load balancing Service discovery Horizontal scaling Rolling updates This makes it the industry standard for container orchestration. Understanding the Kubernetes Architecture for This Deployment For this deployment, we'll use two Kubernetes resources: Deployment A Deployment is responsible for: Creating Pods Maintaining desired replica count Recreating failed Pods automatically Managing updates and rollbacks Service A Service provides a stable network endpoint for Pods. Since Pod IPs change frequently, Services allow applications and users to communicate reliably with Pods. Deployment and Service Manifest Create a file named: app.yaml Add the following configuration: apiVersion : apps/v1 kind : Deployment metadata : name : node-app spec : replicas : 2 selector : matchLabels : app : node-app template : metadata : labels : app : node-app spec : containers : - name : node-app image : madhavnaks/node-app:latest ports : - containerPort : 3000 --- apiVersion : v1 kind : Service metadata : name : node-a
开发者
From Blank Terminal to Shipping a Real Client Project: My First Year of Coding
Exactly one year ago, my terminal was a blank slate. I started where almost everyone does , wrestling with HTML, CSS, and JavaScript, trying to understand the web pixel by pixel. What began as curiosity quickly turned into a full obsession. I went from building simple static pages to diving deep into full-stack development. Here’s what that intense first year of constant building, breaking things, and shipping real projects has looked like. The Leap into Modern Frameworks Once vanilla JavaScript started feeling limiting, I jumped into React . Component-based thinking completely changed how I approached interfaces. Then came Next.js — it bridged client-side beauty with server-side power and pushed me into a true full-stack mindset. The Ultimate Test: Lynvista Safaris The biggest challenge was building lynvistasafaris.com , a live travel booking platform for a real client. This project forced me far beyond tutorials and into real engineering problems. I had to implement: Payment infrastructure from scratch with Daraja API (M-Pesa STK pushes) and Paystack for international transactions. A robust database layer using Drizzle ORM + MySQL. Custom business logic , including a multi-currency pricing system with special validation rules for currencies like GBP. It was messy , many late nights debugging webhooks, schema mismatches, and edge cases , but shipping it taught me more than any course ever could. What One Year Taught Me Syntax is just a tool. The real skill is learning how to break down complex problems, debug effectively, and keep iterating even when things break in production. I’m incredibly proud of the progress I’ve made in 365 days (402 contributions later), but I know I’m still at the very beginning. For the next phase, I’m focused on shipping more projects, writing about the crazy bugs I encounter, and deepening my architectural and full-stack skills. If you want to see what I’m building right now, check out my GitHub .
AI 资讯
I built a Spring Boot + Angular + JWT Full Stack Starter Kit — here's what I learned
Why I built this Every time I started a new Java full stack project I was spending 2-3 days just on setup — JWT configuration, Spring Security, CORS, connecting Angular to backend. So I decided to build a reusable starter kit once and never do that setup again. What I built A complete full stack starter kit with: Spring Boot 3.5 REST API Angular 19 frontend connected to backend MySQL database with User table ready JWT Authentication working out of the box Spring Security configured Full CRUD operations Clean layered architecture (Controller → Service → Repository) The Tech Stack Backend: Java 17, Spring Boot, Spring Security, JWT, JPA Frontend: Angular 19, TypeScript Database: MySQL How it works User registers via POST /api/users User logs in via POST /api/auth/login Backend returns JWT token Frontend stores token in localStorage All protected routes require valid token Invalid or missing token returns 401 Unauthorized What I learned JWT configuration in Spring Security is confusing at first CORS needs to be configured in SecurityConfig not just main class Angular HttpClient needs provideHttpClient() in app.config.ts Service layer keeps code clean and testable GitHub Full source code is available here: https://github.com/shindebuilds/springboot-angular-starter-kit Feel free to clone it, use it, improve it. If you want the packaged version with setup instructions: https://hanumant4.gumroad.com/l/caopgu Happy building!
开发者
The Most Valuable Thing I Found in Tech Wasn't an Opportunity
TL;DR As an international student in the United States, I joined tech communities hoping to find...
AI 资讯
Learnings about authentication and authorization.
At the beginning of my Engineering career, I worked in a place where I had a lot of freedom to implement and experiment any technology I found interesting. I tried many technologies like PHP, Java, EJBs, SOAP, Rest and JavaScript. This gave me a lot of perspective, but I lacked the guidance and mentoring from more experienced developers. One of the most problematic things I built was a login. I would like to share in this document things that I did in the past so you understand why it is problematic and how I would build them today. Earlier Mistakes My First PHP Login. This is not a terrible option when using a single host, small project, but the biggest problem comes when we need to scale horizontally. Session variables exist only on the servers they are created. If you add more servers + Load Balancer, there is no guarantee that your requests go to the same server. In terms of vulnerabilities, if somebody manages to read your session id, they can impersonate you, act on your behalf. This is not really different from other methods like JWT so it is important to set up SameSite cookies or CSRF tokens, but do you think I did that for my first login ? of course NOT! My first Password storage. If you are thinking on implementing a login please NEVER do what I am about to describe: The first time I implemented a password, I was worried that somebody would find out the "actual" password. I wasn't actually thinking about using HTTP (instead of HTTPs), so my take on this was "encrypting" the password into MD5. Then the password was saved in MD5, but I was NOT doing anything different than just sending the password AS is. Let me explain the problems with this approach: Over HTTP an MD5 password can be read, and anybody can simply replicate the request with the same MD5 MD5 was actually NOT encrypting, it was a hashing. There are databases all over the internet mapping MD5 and other hashed passwords available so finding an MD5 can actually be translated to an actual password
开源项目
GitHub for Beginners: Answers to some common questions
Find the answers to some of the most common GitHub-related questions. The post GitHub for Beginners: Answers to some common questions appeared first on The GitHub Blog .
开发者
Build a Cloud-Connected Weather Station with Arduino UNO R4 WiFi
Learn how to build a real IoT weather station using the Arduino UNO R4 WiFi and BME280 sensor, sending live temperature, humidity, and pressure data to Arduino IoT Cloud — with full code, wiring diagrams, and dashboard. What We're Building In this project, you'll build a cloud-connected weather station that measures: Temperature (°C / °F) Humidity (%) Atmospheric Pressure (hPa) All three readings will be streamed live to the Arduino IoT Cloud , where you can monitor them from anywhere in the world via a browser or the free Arduino IoT Remote app on your phone. Components Required Component Qty Notes Arduino UNO R4 WiFi 1 Built-in ESP32-S3 WiFi module BME280 Sensor Module 1 Measures temp + humidity + pressure via I²C Breadboard 1 Full or half size Jumper Wires (M-M) 4 For I²C connections USB-A to USB-C Cable 1 For power & programming Why BME280 over DHT22? The BME280 gives you three measurements (including barometric pressure) over a single I²C bus using just 2 wires, making it more capable and cleaner to wire. The DHT22 only gives temperature and humidity. Wiring the BME280 to Arduino UNO R4 WiFi The BME280 uses the I²C protocol , so it only needs 4 wires: BME280 Pin → Arduino UNO R4 WiFi Pin ────────────────────────────────────── VCC → 3.3V GND → GND SDA → A4 (I²C Data) SCL → A5 (I²C Clock) Important: The BME280 runs on 3.3V , not 5V. Connecting it to the 5V pin can damage the sensor permanently. Here's the schematic overview: ┌────────────────────────────┐ │ Arduino UNO R4 WiFi │ │ │ │ 3.3V ──────────────► VCC │ │ GND ──────────────► GND │ ← BME280 │ A4 ──────────────► SDA │ │ A5 ──────────────► SCL │ └────────────────────────────┘ ☁️ Step 1 — Set Up Arduino IoT Cloud Before writing any code, you need to configure the Arduino IoT Cloud . It's free for up to 2 devices. 1.1 Create a Free Account Go to cloud.arduino.cc and sign up or log in. 1.2 Create a New "Thing" Click Things in the left sidebar Click + Create Thing Name it WeatherStation 1.3 Add Your Device Click
AI 资讯
Game Jams no Browser: Você Não Precisa de Unity
Se você já fez algum front-end interativo, já tem 80% do que precisa pra fazer um jogo simples. Game jams como a June Solstice são desculpa perfeita pra testar isso — três semanas, tema aberto, e você descobre que canvas + requestAnimationFrame levam longe. Por Que Desenvolvedores Web Deviam Fazer Game Jams A maioria dos devs que conheço nunca tentou fazer um jogo porque acha que precisa aprender Unity ou Unreal. Mas se você já mexeu com animações CSS, state management ou physics simulators básicos pra UI, você já cruzou metade da ponte. Game jams forçam escopo pequeno — você não vai fazer Elden Ring em três semanas, vai fazer um Snake com twist. E isso cabe perfeitamente no que o browser oferece. Além disso, jogos web rodam em qualquer lugar. Sem instalador, sem App Store review, sem build pra cinco plataformas. Você manda um link e qualquer um joga. Pra um jam onde o pessoal precisa testar dezenas de jogos rápido, isso importa. Canvas API: Seu Motor Gráfico Embutido O <canvas> existe desde 2010 e faz exatamente o que você precisa: desenhar pixels, shapes e imagens num loop de 60fps. A estrutura básica de qualquer jogo 2D cabe em 30 linhas: const canvas = document . querySelector ( ' canvas ' ); const ctx = canvas . getContext ( ' 2d ' ); const gameState = { player : { x : 50 , y : 50 , speed : 2 }, enemies : [] }; function update ( deltaTime ) { // Input handling if ( keys [ ' ArrowRight ' ]) gameState . player . x += gameState . player . speed ; if ( keys [ ' ArrowLeft ' ]) gameState . player . x -= gameState . player . speed ; // Game logic gameState . enemies . forEach ( enemy => { enemy . x += Math . sin ( Date . now () / 1000 ) * 0.5 ; }); } function render () { ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ); // Draw player ctx . fillStyle = ' #00ff00 ' ; ctx . fillRect ( gameState . player . x , gameState . player . y , 20 , 20 ); // Draw enemies gameState . enemies . forEach ( enemy => { ctx . fillStyle = ' #ff0000 ' ; ctx . fillRect ( enemy .
AI 资讯
Developer vs Engineer : How I Stopped a Memory Problem by Thinking Differently
The main difference between a developer and an engineer is not just the code they write. It's how they think about building a system. How they optimize. How they use resources. I learned this from a real project. I had to read 10,000 JSON requests and write them into a file. Simple enough. I wrote the program the way I always did the developer way. Read all 10,000 requests, store everything in memory, then write to the file. Done. When I tested it, my memory usage was much higher than normal. Way higher than it should have been. The developer in me would have just moved on. It works, right? But something made me stop and ask why is this consuming so much memory? I dug into it. And I found the problem. What I was doing was basically doubling my memory usage without realizing it. First, I was loading all 10,000 records into memory to store the data. Then, I was holding all of it again in memory while writing to the file. Two copies of the same data sitting in memory at the same time. That's the thing about this approach it's not reliable when you're dealing with a large number of requests. It doesn't scale. It just quietly eats your resources. That's when I found streams. The idea behind streaming is simple but powerful. Instead of loading everything at once, you break the data into small chunks. At any given moment, only one chunk lives in memory. You read it, transform it, write it and move on to the next one. The transform step is the interesting part. It's not just about moving data from one place to another. Transform lets you validate each chunk, check if the structure is correct, clean it if needed before it ever reaches the file. So you're not just being efficient with memory, you're also processing your data with more control. And because you're always working on one small piece at a time, the memory usage stays low and consistent no matter if you're processing 100 requests or 100,000. That one question am I using my resources in a reliable way? is what pushe
AI 资讯
Same Hardware, Different Experience: Why Linux Feels Faster
A few weeks after switching from Windows to Linux, I noticed something interesting. The hardware had not changed. The processor was the same. The RAM was the same. The SSD was the same. And yet, the laptop felt noticeably faster. Not necessarily because applications were completing tasks dramatically quicker, but because the entire system felt more responsive. Keyboard input felt immediate. Windows opened faster. Terminal commands appeared instantly. The desktop experience felt smoother. This raised a question: How can the same hardware feel different simply because the operating system changed? While I'm still learning, this is the mental model I've built so far. The Hardware Didn't Change Consider a laptop with: AMD Ryzen processor 16 GB DDR5 RAM NVMe SSD Modern integrated graphics When switching operating systems, none of these components change. The CPU does not suddenly become faster. The RAM does not magically increase. The SSD remains identical. From a hardware perspective: ```text id="u3m9xd" Before → Same Hardware After → Same Hardware So the difference must come from somewhere else. --- ## An Operating System Is Not Just a User Interface Many people think of an operating system primarily as the desktop they see. But an operating system does far more than display windows and icons. It manages: * Memory * CPU scheduling * Processes * Storage * Networking * Device drivers * Background services In other words: > The operating system decides how hardware resources are used. Two operating systems can therefore create very different experiences using the same hardware. --- ## Perceived Performance vs Raw Performance One thing I have learned is that performance is not always about benchmarks. A system can have excellent benchmark scores and still feel sluggish. Why? Because users experience responsiveness, not benchmark numbers. Examples include: * How quickly a window opens * How fast a menu appears * How responsive typing feels * How quickly applications launch
AI 资讯
Learning DevOps from First Principles: MAC Addresses vs IP Addresses — The Difference Finally Clicked
One of the first networking concepts that confused me was this: Why does a computer need both a MAC address and an IP address? At first glance, they seem to solve the same problem. Both appear to identify a device. Both show up in networking tools. Both appear in packet captures. So why do we need two different addresses? While exploring Linux networking tools and Wireshark, the distinction finally started making sense. This article summarizes the mental model that helped me understand the difference. Looking Inside the Machine Before discussing addresses, it helps to understand where they come from. If you open a typical laptop, you will usually find components such as: Battery RAM Storage Processor Cooling system Network interfaces One of those network interfaces is typically: A Wi-Fi card An Ethernet controller These components are responsible for network communication. They are the parts of the machine that actually send and receive data across a network. Every Network Interface Has an Identity A network interface needs a way to identify itself. This is where the MAC address comes in. A MAC address is associated with a network interface card (NIC). Example: ```text id="q3d9nm" 2C:9C:58:8B:2D:7B Think of it as the identity of the network interface itself. Not the operating system. Not the browser. Not the application. The network hardware. --- ## What Is a MAC Address? MAC stands for: **Media Access Control** A MAC address operates at the **Data Link Layer** of the OSI model. Its primary purpose is to help devices communicate within a local network. Examples include: * Laptop to router * Router to switch * Switch to printer In other words: > MAC addresses help devices find each other on the same local network. --- ## What Is an IP Address? An IP address serves a different purpose. Example: ```text id="g8x4tc" 192.168.1.20 or ```text id="v6u7mz" 2405:201:8000::1 IP addresses operate at the **Network Layer**. Their job is to identify where a device exists within a
AI 资讯
Git & Collaboration: A Beginner's Guide (With Real Analogies)
🌐 Read this post in Bahasa Indonesia here . 📝 A note on this article This post is based on my personal study notes on version control and Git collaboration. To make these notes more readable and useful — for myself and for others — I worked with AI to help expand and structure them into a proper blog format. The ideas, learning journey, and understanding are mine; the AI helped with the writing and presentation. Learning Git doesn't have to be intimidating. In this article, I'll break down the essential concepts of version control and collaboration — using simple analogies that anyone can understand. What Is Git? Git is a version control system . Think of it as a save system for your code — like save points in a video game. Every time you save (commit), Git remembers the state of your project at that moment. If something goes wrong, you can always go back. Repository: Your Project's Warehouse A repository (or "repo") is the folder that Git watches. There are two types: Local repository : lives on your computer. Your personal workspace. Remote repository : lives on a server (GitHub, GitLab, Bitbucket). The "official" shared copy your team can access. They stay connected through a Remote URL, so you can push your local changes up and pull others' changes down. git init # Start tracking a folder git remote add origin <url> # Connect to a remote repo git push origin main # Send commits to remote git pull origin main # Get latest from remote Commit: Your Project's Save Point A commit is a snapshot of your project at a specific moment. Each commit has: A message describing what changed A unique ID (hash) A timestamp git add . # Stage all changes git commit -m "Add homepage layout" # Save a snapshot git log --oneline # View commit history Write meaningful commit messages. Future you will thank present you. Checkout, Reset, Revert: Traveling Through Time These three commands all interact with your commit history — but in very different ways: git checkout — Visit the Past (T