Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

Deep Engineering

45 Articles
Divya Anne Selvaraj
26 Jun 2025
21 min read
Save for later

Deep Engineering #6: Imran Ahmad on Algorithmic Thinking, Scalable Systems, and the Rise of AI Agents

Divya Anne Selvaraj
26 Jun 2025
21 min read
How classical algorithms and real-world trade-offs will shape the next generation of software#6Imran Ahmad on Algorithmic Thinking, Scalable Systems, and the Rise of AI AgentsHow classical algorithms, system constraints, and real-world trade-offs will shape the next generation of intelligent softwareWorkshop: Unpack OWASP Top 10 LLMs with SnykJoin Snyk and OWASP Leader Vandana Verma Sehgal on Tuesday, July 15 at 11:00AM ET for a live session covering:✓ The top LLM vulnerabilities✓ Proven best practices for securing AI-generated code✓ Snyk’s AI-powered tools automate and scale secure dev.See live demos plus earn 1 CPE credit!Register todayHi Welcome to the sixth issue of Deep Engineering.A recent IBM and Morning Consult survey found that 99% of enterprise developers are now exploring or developing AI agents. Some have even christened 2025 as “the year of the AI agent”. We are experiencing a shift from standalone models to agentic systems.To understand what this shift means for developers we spoke with Imran Ahmad, data scientist at the Canadian Federal Government’s Advanced Analytics Solution Center (A2SC) and visiting professor at Carleton University. Ahmad is also the author of 50 Algorithms Every Programmer Should Know (Packt, 2023) and is currently working on his highly anticipated next book with us, 30 Agents Every AI Engineer Should Know, due out later this year. He has deep experience working on real-time analytics frameworks, multimedia data processing, and resource allocation algorithms in cloud computing.You can watch the full interview and read the transcript here—or keep reading for our take on the algorithmic mindset that will define the next generation of agentic software.Sign Up |AdvertiseFrom Models to Agents with Imran AhmadAccording to Gartner by 2028, 90% of enterprise software engineers will use AI code assistants (up from under 14% in early 2024). But we are already moving beyond code assistants to agents: software entities that don’t just respond to prompts, but plan, reason, and act by orchestrating tools, models, and infrastructure independently.“We have a lot of hope around AI – that it can eventually replace a human,” Ahmad says. “But if you think about how a person in a company solves a problem, they rely on a set of tools… After gathering information, they create a solution. An ‘agent’ is meant to replace that kind of human reasoning. It should be able to discover the tools in the environment around it, and have the wisdom to orchestrate a solution tailored to the problem. We're not there yet, but that's what we're striving for.”This vision aligns with where industry leaders are headed. Maryam Ashoori, Director of Product Management, IBM watsonx.ai concurs that 2025 is “the year of the AI agent”, and a recent IBM and Morning Consult survey found 99% of enterprise developers are now exploring or developing AI agents. Major platforms are rushing to support this paradigm: for instance, at Build 2025 Microsoft announced an Azure AI Agent Service to orchestrate multiple specialized agents as modular microservices. Such developments underscore the momentum behind agent-based architectures – which Igor Fedulov, CEO of Intersog, in an article for Forbes Technology Council, predicts will be a defining software trend by the end of 2025. Ahmad’s predicts this to be “the next generation of the algorithmic world we live in.”What is an agent?An AI agent is more than just a single model answering questions – it’s a software entity that can plan, call on various tools (search engines, databases, calculators, other models, etc.), and execute multi-step workflows to achieve a goal. “An agent is an entity that has the wisdom to work independently and autonomously,” Ahmad explains. “It can explore its environment, discover available tools, select the right ones, and create a workflow to solve a specific problem. That’s the dream agent.” Today’s implementations only scratch the surface of that ideal. For example, many so-called agents are basically LLMs augmented with function-calling abilities (tool APIs) – useful, but still limited in reasoning. Ahmad emphasizes that “a large language model is not the only tool. It’s perhaps the most important one right now, but real wisdom lies outside the LLM – in the agent.” In other words, true intelligence emerges from how an agent chooses and uses an ecosystem of tools, not just from one model’s output.The Practitioner’s Lens: Driving vs. Building the EngineEven as new techniques emerge, software professionals must decide how deep to go into theory. Ahmad draws a line between researchers and practitioners when it comes to algorithms. The researcher may delve into proofs of optimality, complexity theory, or inventing new algorithms. The practitioner, however, cares about applying algorithms effectively to solve real problems. Ahmad uses an analogy to explain this:“Do you want to build a car and understand every component of the engine? Or do you just want to drive it? If you want to drive it, you need to know the essentials – how to maintain it – but not necessarily every internal detail. That’s the practitioner role.”A senior engineer doesn’t always need to derive equations from scratch, but they do need to know the key parameters, limitations, and maintenance needs of the algorithmic “engines” they use.Ahmad isn’t advocating ignorance of theory. In fact, he stresses that having some insight under the hood improves decision-making. “If you know a bit more about how the engine works, you can choose the right car for your needs,” he explains. Similarly, knowing an algorithm’s fundamentals (even at a high level) helps an engineer pick the right tool for a given job. For example: Is your search problem better served by a Breath-First Search (BFS) or Depth-First Search (DFS) approach? Would a decision tree suffice, or do you need the boost in accuracy from an ensemble method? Experienced engineers approach such questions by combining intuition with algorithmic knowledge – a very practical kind of expertise. Ahmad’s advice is to focus on the level of understanding that informs real-world choices, rather than getting lost in academic detail irrelevant to your use case.Algorithm Choices and Real-World ScalabilityIn the wild, data is messy and scale is enormous – revealing which algorithms truly perform. “When algorithms are taught in universities… they’re usually applied to small, curated datasets. I call this ‘manicured pedicure data.’ But that’s not real data,” Ahmad quips. In his career as a public-sector data scientist, he routinely deals with millions of records and offers three key insights that shape how engineers should approach algorithm selection in production environments:Performance at scale requires different choices than in theory: Ahmad uses an example from his experience when he applied the Apriori algorithm (a well-known method for association rule mining). “When I used Apriori in practice, I found it doesn’t scale,” he admits. “It generates thousands of rules and then filters them after the fact. There’s a newer, better algorithm called (Frequent Pattern) FP-Growth that does the filtering at the source. It only generates the rules you actually need, making it far more scalable” A theoretically correct algorithm can become unusable when faced with big data volumes or strict latency requirements.Non-functional requirements often determine success: Beyond just picking the right algorithm, non-functional requirements like performance, scalability, and reliability must guide engineering decisions. “In academia, we focus on functional requirements… ‘this algorithm should detect fraud.’ And yes, the algorithm might technically work. But in practice, you also have to consider how it performs, how scalable it is, whether it can run as a cloud service, and so on.” Robust software needs algorithms that meet functional goals and the operational demands of deployment (throughput, memory, cost, etc.).Start simple, escalate only as needed:Simpler algorithms are easier to implement, explain, and maintain – valuable qualities especially in domains like finance or healthcare where interpretability matters. While discussing predictive models, Ahmad describes an iterative approach – perhaps begin with intuitive rules, upgrade to a decision tree for more structure, then if needed move to a more powerful model like XGBoost or an SVM. Jumping straight to a deep neural net can be overkill for a simple classification. “It’s usually a mistake to begin with something too complex – it can be overkill, like using a forklift to lift a sheet of paper,” he says.However, Algorithmic choices don’t occur in a vacuum – they influence and are influenced by software architecture. Modern systems, especially AI systems, have distinct phases (training, testing, inference) and often run in distributed cloud environments. Engineers therefore must integrate algorithmic thinking into high-level design and infrastructure decisions.Bridging Algorithms and Architecture in PracticeTake the example of training a machine learning model versus deploying it. “During training, you need a lot of data... a lot of processing power – GPUs, ideally. It’s expensive and time-consuming,” Ahmad notes. This is where cloud architecture shines. “The cloud gives you elastic architectures – you can spin up 2,000 nodes for 2 or 10 hours, train your model, and then shut it down. The cost is manageable…and you’re done.” Cloud platforms allow an elastic burst of resources: massive parallelism for a short duration, which can turn a week-long training job into a few hours for a few hundred dollars. Ahmad highlights that this elasticity was simply not available decades ago in on-prem computing. Today, any team can rent essentially unlimited compute for a day, which removes a huge barrier in building complex models. “If you want to optimize for cost and performance, you need elastic systems. Cloud computing… offers exactly that” for AI workloads, he says.Once trained, the model often compresses down to a relatively small artifact (Ahmad jokes that the final model file is “like the tail of an elephant – tiny compared to the effort to build it”). Serving predictions might only require a lightweight runtime that can even live on a smartphone. Thus, the hardware needs vary drastically between phases: heavy GPU clusters for training; maybe a simple CPU or even embedded device for inference. Good system design accommodates these differences – e.g., by separating training pipelines from inference services, or using cloud for training but edge devices for deployment when appropriate.So, how does algorithm choice drive architecture? Ahmad recommends evaluating any big design decision on three axes:CostPerformanceTime-to-deliverIf adopting a more sophisticated algorithm (or distributed processing framework, etc.) will greatly improve accuracy or speed and the extra cost is justified, it may be worth it. “First, ask yourself: does this problem justify the additional complexity…? Then evaluate that decision along three axes: cost, performance, and time,” he advises. “If an algorithm is more accurate, more time-efficient, and the cost increase is justified, then it’s probably the right choice.” On the flip side, if a fancy algorithm barely improves accuracy or would bust your budget/latency requirements, you might stick with a simpler approach that you can deploy more quickly. This trade-off analysis – weighing accuracy vs. expense vs. speed – is a core skill for architects in the age of AI. It prevents architecture astronautics (over-engineering) by ensuring complexity serves a real purpose.Classical Techniques: The Unsung Heroes in AI SystemsAhmad views classical computer science algorithms and modern AI methods as complementary components of a solution.“Take search algorithms, for instance,” Ahmad elaborates. “When you're preparing datasets for AI… you often have massive data lakes – structured and unstructured data all in one place. Now, say you're training a model for fraud detection. You need to figure out which data is relevant from that massive repository. Search algorithms can help you locate the relevant features and datasets. They support the AI workflow by enabling smarter data preparation.” Before the fancy model ever sees the data, classical algorithms may be at work filtering and finding the right inputs. Similarly, Ahmad points out, classic graph algorithms might be used to do link analysis or community detection that informs feature engineering. Even some “old-school” NLP (like tokenization or regex parsing) can serve as preprocessing for LLM pipelines. These building blocks ensure that the complex AI has quality material to work with.Ahmad offers an apt metaphor:“Maybe AI is your ‘main muscle,’ but to build a strong body – or a performant system – you need to train the supporting muscles too. Classical algorithms are part of that foundation.”Robust systems use the best of both worlds. For example, he describes a hybrid approach in real-world data labeling. In production, you often don’t have neat labeled datasets; you have to derive labels or important features from raw data. Association rule mining algorithms like Apriori or FP-Growth (from classical data mining) can uncover patterns. These patterns might suggest how to label data or which combined features could predict an outcome. “If you feed transaction data into FP-Growth, it will find relationships – like if someone buys milk, they’re likely to buy cheese too… These are the kinds of patterns the algorithm surfaces,” Ahmad explains. Here, a classical unsupervised algorithm helps define the inputs to a modern supervised learning task – a symbiosis that improves the overall system.Foundational skills like devising efficient search strategies, using dynamic programming for optimal substructure problems, or leveraging sorting and hashing for data organization are still extremely relevant. They might operate behind the scenes of an AI pipeline or bolster the infrastructure (e.g., database indexing, cache eviction policies, etc.) that keeps your application fast and reliable. Ahmad even notes that Google’s hyperparameter tuning service, Vizier, is “based on classical heuristic algorithms” rather than any neural network magic – yet it significantly accelerates model optimization.Optimization: The (Absolute) Necessity of Efficiency“Math can be cruel,” Ahmad warns. “If you’re not careful, your problem might never converge… If you accidentally introduce an exponential factor in the wrong place, it might take years – or even centuries – for the solution to converge. The sun might die before your algorithm finishes!” This colorful exaggeration underscores a serious point: computational complexity can explode quickly, and engineers need to be vigilant. It’s not acceptable to shrug off inefficiencies with “just let it run longer” if the algorithmic complexity is super-polynomial. “Things can spiral out of control very quickly. That’s why optimization isn't a luxury – it’s a necessity,” Ahmad says.Ahmad talks about three levels at which we optimize AI systems:Hardware: Choosing the right compute resources can yield massive speedups. For example, training a deep learning model on a GPU or TPU vs. a CPU can be orders of magnitude faster. “For deep learning especially, using a GPU can speed up training by a factor of 1,000,” Ahmad notes, based on his experience. So, part of an engineer’s algorithmic thinking is knowing when to offload work to specialized hardware, or how to parallelize tasks across a cluster.Hyperparameter tuning and algorithmic settings: Many algorithms (especially in machine learning) have knobs to turn – learning rate, tree depth, number of clusters, etc. The wrong settings can make a huge difference in both model quality and compute time. Traditionally, tuning was an art of trial and error. But now, tools like Google’s Vizier (and open-source libraries for Bayesian optimization) can automate this search efficiently.Ensuring the problem is set up correctly: A common mistake is diving into training without examining the data’s signal-to-noise ratio. Ahmad recommends the CRISP-DM approach – spend ample time on data understanding and preparation. “Let’s say your dataset has a lot of randomness and noise. If there's no clear signal, then even a Nobel Prize–winning scientist won’t be able to build a good model,” he says. “So, you need to assess your data before you commit to AI.” This might involve using statistical analysis or simple algorithms to verify that patterns exist. “Use classical methods to ensure that your data even has a learnable pattern. Otherwise, you’re wasting time and resources,” Ahmad advises.The cost of compute – and the opportunity cost of engineers’ time – is too high to ignore optimization. Or as Ahmad bluntly puts it, “It’s not OK to say, ‘I’m not in a hurry, I’ll just let it run.’” Competitive teams optimize both to push performance and to control time/cost, achieving results that are fast, scalable, and economically sensible.Learning by Doing: Making Algorithms StickMany developers first encounter algorithms as leetcode-style puzzles or theoretical exercises for interviews. But how can they move beyond rote knowledge to true mastery? Ahmad’s answer: practice on real problems. “Learning algorithms for interviews is a good start… it shows initiative,” he acknowledges. “But in interview prep, you're not solving real-world problems… To truly make algorithmic knowledge stick, you need to use algorithms to solve actual problems.”In the artificial setting of an interview question, you might code a graph traversal or a sorting function in isolation. The scope is narrow and hints are often provided by the problem constraints. Real projects are messier and more holistic. When you set out to build something end-to-end, you quickly uncover gaps in your knowledge and gain a deeper intuition. “That’s when you'll face real challenges, discover edge cases, and realize that you may need to know other algorithms just to get your main one working,” Ahmad says. Perhaps you’re implementing a network flow algorithm but discover you need a good data structure for priority queues to make it efficient, forcing you to learn or recall heap algorithms. Or you’re training a machine learning model and hit a wall until you implement a caching strategy to handle streaming data. Solving real problems forces you to integrate multiple techniques, and shows how classical and modern methods complement each other in context. Ahmad puts it succinctly: “There’s an entire ecosystem – an algorithmic community – that supports every solution. Classical and modern algorithms aren’t separate worlds. They complement each other, and a solid understanding of both is essential.”So, what’s the best way to gain this hands-on experience? Ahmad recommends use-case-driven projects, especially in domains that matter to you. He suggests tapping into the wealth of public datasets now available. “Governments around the world are legal custodians of citizen data… If used responsibly, this data can change lives,” he notes. Portals like data.gov host hundreds of thousands of datasets spanning healthcare, transportation, economics, climate, and more. Similar open data repositories exist for other countries and regions. These aren’t sanitized toy datasets – they are real, messy, and meaningful. “Choose a vertical you care about, download a dataset, pick an algorithm, and try to solve a problem. That’s the best way to solidify your learning,” Ahmad advises. The key is to immerse yourself in a project where you must apply algorithms end-to-end: from data cleaning and exploratory analysis, to choosing the right model or algorithmic approach, through optimization and presenting results. This process will teach more than any isolated coding puzzle, and the lessons will stick because they’re tied to real outcomes.Yes, 2025 is “the year of the AI agent”, but as the industry shifts from standalone models to agentic systems, engineers must learn to pair classical algorithmic foundations with real-world pragmatism, because in this era of AI agents, true intelligence lies not only in models, but in how wisely we orchestrate them.If Ahmad’s perspective on real-world scalability and algorithmic pragmatism resonated with you, his book 50 Algorithms Every Programmer Should Know goes deeper into the practical foundations behind today’s AI systems. The following excerpt explores how to design and optimize large-scale algorithms for production environments—covering parallelism, cloud infrastructure, and the trade-offs that shape performant systems.🧠Expert Insight: Large-Scale Algorithms by Imran AhmadThe complete “Chapter 15: Large‑Scale Algorithms” from the book 50 Algorithms Every Programmer Should Know by Imran Ahmad (Packt, September 2023).Large-scale algorithms are specifically designed to tackle sizable and intricate problems. They distinguish themselves by their demand for multiple execution engines due to the sheer volume of data and processing requirements. Examples of such algorithms include Large Language Models (LLMs) like ChatGPT, which require distributed model training to manage the extensive computational demands inherent to deep learning. The resource-intensive nature of such complex algorithms highlights the requirement for robust, parallel processing techniques critical for training the model.In this chapter, we will start by introducing the concept of large-scale algorithms and then proceed to discuss the efficient infrastructure required to support them. Additionally, we will explore various strategies for managing multi-resource processing. Within this chapter, we will examine the limitations of parallel processing, as outlined by Amdahl’s law, and investigate the use of Graphics Processing Units (GPUs).Read the Complete Chapter50 Algorithms Every Programmer Should Know by Imran Ahmad (Packt, September 2023) is a practical guide to algorithmic problem-solving in real-world software. Now in its second edition, the book covers everything from classical data structures and graph algorithms to machine learning, deep learning, NLP, and large-scale systems.For a limited time, get the eBook for $9.99 at packtpub.com — no code required.Get the Book🛠️Tool of the Week⚒️OSS Vizier — Production-Grade Black-Box Optimization from GoogleOSS Vizier is a Python-based, open source optimization service built on top of Google Vizier—the system that powers hyperparameter tuning and experiment optimization across products like Search, Ads, and YouTube. Now available to the broader research and engineering community, OSS Vizier brings the same fault-tolerant, scalable architecture to a wide range of use cases—from ML pipelines to physical experiments.Highlights:Flexible, Distributed Architecture: Supports RPC-based optimization via gRPC, allowing Python, C++, Rust, or custom clients to evaluate black-box objectives in parallel or sequentially.Rich Integration Ecosystem: Includes native support for PyGlove, TensorFlow Probability, and Vertex Vizier—enabling seamless connection to evolutionary search, Bayesian optimization, and cloud workflows.Research-Ready: Comes with standardized benchmarking APIs, a modular algorithm interface, and compatibility with AutoML tooling—ideal for evaluating and extending new optimization strategies.Resilient and Extensible: Fault-tolerant by design, with evaluations stored in SQL-backed datastores and support for retry logic, partial failure, and real-world constraints (e.g., human-evaluated objectives or lab settings).Learn more about OSS Vizier📰 Tech BriefsAI agents in 2025: Expectations vs. reality by Ivan Belcic and Cole Stryker, IBM Think: In 2025, AI agents are widely touted as transformative tools for work and productivity, but experts caution that while experimentation is accelerating, current capabilities remain limited, true autonomy is rare, and success depends on governance, strategy, and realistic expectations.Agent Mode for Gemini added to Android Studio: Google has introduced Agent Mode for Gemini in Android Studio, enabling developers to describe high-level goals that the agent can plan and execute—such as fixing build errors, adding dark mode, or generating UI from a screenshot—while allowing user oversight, feedback, and iteration, with expanded context support via Gemini API and MCP integration.Google’s Agent2Agent protocol finds new home at the Linux Foundation: Google has donated its Agent2Agent (A2A) protocol—a standard for enabling interoperability between AI agents—to the Linux Foundation, aiming to foster vendor-neutral, open development of multi-agent systems, with over 100 tech partners now contributing to its extensible, secure, and scalable design.Azure AI Foundry Agent Service GA Introduces Multi-Agent Orchestration and Open Interoperability: Microsoft has launched the Azure AI Foundry Agent Service into general availability, offering a modular, multi-agent orchestration platform that supports open interoperability, seamless integration with Logic Apps and external tools, and robust capabilities for monitoring, governance, and cross-cloud agent collaboration—all aimed at enabling scalable, intelligent agent ecosystems across diverse enterprise use cases.How AI Is Redefining The Way Software Is Built In 2025 by Igor Fedulov, CEO of Intersog: AI is transforming software development by automating tasks, accelerating workflows, and enabling more intelligent, adaptive systems—driving a shift toward agent-based architectures, cloud-native applications, and advanced technologies like voice and image recognition, while requiring developers to upskill in AI, data analysis, and security to remain competitive.That’s all for today. Thank you for reading this issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey we run monthly—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor-in-Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0

Divya Anne Selvaraj
19 Jun 2025
20 min read
Save for later

Deep Engineering #5: Dhirendra Sinha (Google) and Tejas Chopra (Netflix) on Scaling, AI Ops, and System Design Interviews

Divya Anne Selvaraj
19 Jun 2025
20 min read
Lessons on designing for failure and the importance of trade-off thinking#5Dhirendra Sinha (Google) and Tejas Chopra (Netflix) on Scaling, AI Ops, and System Design InterviewsFrom designing fault-tolerant systems at Big Tech and hiring for system design roles, Chopra and Sinha share lessons on designing for failure and the importance of trade-off thinkingHi Welcome to the fifth issue of Deep Engineering.With AI workloads reshaping infrastructure demands and distributed systems becoming the default, engineers are facing new failure modes, stricter trade-offs, and rising expectations in both practice and hiring.To explore what today’s engineers need to know, we spoke with Dhirendra Sinha (Software Engineering Manager at Google, and long-time distributed systems educator) and Tejas Chopra (Senior Engineer at Netflix and Adjunct Professor at UAT). Their recent book, System Design Guide for Software Professionals (Packt, 2024), distills decades of practical experience into a structured approach to design thinking.In this issue, we unpack their hard-won lessons on observability, fault tolerance, automation, and interview performance—plus what it really means to design for scale in a world where even one-in-a-million edge cases are everyday events.You can watch the full interview and read the transcript here—or keep reading for our distilled take on the design mindset that will define the next decade of systems engineering.Sign Up |AdvertiseJoin us on July 19 for a 150-minute interactive MCP Workshop. Go beyond theory and learn how to build and ship real-world MCP solutions. Limited spots available! Reserve your seat today.Use Code EARLY35 for 35% off!Designing for Scale, Failure, and the Future — With Dhirendra Sinha and Tejas Chopra“Foundational system design principles—like scalability, reliability, and efficiency—are remarkably timeless,” notes Chopra, adding that “the rise of AI only reinforces the importance of these principles.” In other words, new AI systems can’t compensate for poor architecture; they reveal its weaknesses. Sinha concurs: “If the foundation isn’t strong, the system will be brittle—no matter how much AI you throw at it.” AI and system design aren’t at odds – “they complement each other,” says Chopra, with AI introducing new opportunities and stress-tests for our designs.One area where AI is elevating system design is in AI-driven operations (AIOps). Companies are increasingly using intelligent automation for tasks like predictive autoscaling, anomaly detection, and self-healing.“There’s a growing demand for observability systems that can predict service outages, capacity issues, and performance degradation before they occur,” notes Sam Suthar, founding director of Middleware. AI-powered monitoring can catch patterns and bottlenecks ahead of failures, allowing teams to fix issues before users notice. At the same time, designing the systems to support AI workloads is a fresh challenge. The recent rollout of a Ghibli-style image generator saw explosive demand – so much that OpenAI’s CEO had to ask users to pause as GPU servers were overwhelmed. That architecture didn’t fully account for the parallelization and scale such AI models required. AI can optimize and automate a lot, but it will expose any gap in your system design fundamentals. As Sinha puts it, “AI is powerful, but it makes mastering the fundamentals of system design even more critical.”Scaling Challenges and Resilience in PracticeSo, what does it take to operate at web scale in 2025? Sinha highlights four key challenges facing large-scale systems today:Scalability under unpredictable load: global services must handle sudden traffic spikes without falling over or grossly over-provisioning. Even the best capacity models can be off, and “unexpected traffic can still overwhelm systems,” Sinha says.Balancing the classic trade-offs between consistency, performance, and availability: This remains as relevant as ever. In practice, engineers constantly juggle these – and must decide where strong consistency is a must versus where eventual consistency will do.Security and privacy at scale have grown harder: Designing secure systems for millions of users, with evolving privacy regulations and threat landscapes, is an ongoing battle.The rise of AI introduces “new uncertainties”: we’re still learning how to integrate AI agents and AI-driven features safely into large architectures.Chopra offers an example from Netflix: “We once had a live-streaming event where we expected a certain number of users – but ended up with more than three times that number.” The system struggled not because it was fundamentally mis-designed, but due to hidden dependency assumptions. In a microservices world, “you don’t own all the parts—you depend on external systems. And if one of those breaks under load, the whole thing can fall apart,” Chopra warns. A minor supporting service that wasn’t scaled for 3× traffic can become the linchpin that brings down your application. This is why observability is paramount. At Netflix’s scale (hundreds of microservices handling asynchronous calls), tracing a user request through the maze is non-trivial. Teams invest heavily in telemetry to know “which service called what, when, and with what parameters” when things go wrong. Even so, “stitching together a timeline can still be very difficult” in a massive distributed system, especially with asynchronous workflows. Modern observability tools (distributed tracing, centralized logging, etc.) are essential, and even these are evolving with AI assistance to pinpoint issues faster.So how do Big Tech companies approach scalability and robustness by design? One mantra is to design for failure. Assume everything will eventually fail and plan accordingly. “We operate with the mindset that everything will fail,” says Chopra. That philosophy birthed tools like Netflix’s Chaos Monkey, which randomly kills live instances to ensure the overall system can survive outages. If a service or an entire region goes down, your architecture should gracefully degrade or auto-heal without waking up an engineer at 2 AM. Sinha recalls an incident from his days at Yahoo:“I remember someone saying, “This case is so rare, it’s not a big deal,” and the chief architect replied, “One in a million happens every hour here.” That’s what scale does—it invalidates your assumptions.”In high-scale systems, even million-to-one chances occur regularly, so no corner case is truly negligible. In Big Tech, achieving resilience at scale has resulted in three best practices:Fault-tolerant, horizontally scalable architectures: In Netflix and other companies, such architecture ensure that if one node or service dies, the load redistributes and the system heals itself quickly. Teams focus not just on launching features but “landing” them safely – meaning they consider how each new deployment behaves under real-world loads, failure modes, and even disaster scenarios. Automation is key: from continuous deployments to automated rollback and failover scripts. “We also focus on automating everything we can—not just deployments, but also alerts. And those alerts need to be actionable,” Sinha says.Explicit capacity planning and graceful degradation: Engineers define clear limits for how much load a system can handle and build in back-pressure or shedding mechanisms beyond that. Systems often fail when someone makes unrealistic assumptions about unlimited capacity. Caching, rate limiting, and circuit breakers become your safety net. Gradual rollouts further boost robustness. “When we deploy something new, we don’t release it to the entire user base in one go,” Chopra explains. Whether it’s a new recommendation algorithm or a core infrastructure change, Netflix will enable it for a small percentage of users or in one region first, observe the impact, then incrementally expand if all looks good. This staged rollout limits the blast radius of unforeseen issues. Feature flags, canary releases, and region-by-region deployments should be standard operating procedure.Infrastructure as Code (IaC): Modern infrastructure tooling also contributes to resiliency. Many organizations now treat infrastructure as code, defining their deployments and configurations in declarative scripts. As Sinha notes, “we rely heavily on infrastructure as code—using tools like Terraform and Kubernetes—where you define the desired state, and the system self-heals or evolves toward that.” By encoding the target state of the system, companies enable automated recovery; if something drifts or breaks, the platform will attempt to revert to the last good state without manual intervention. This codified approach also makes scaling and replication more predictable, since environments can be spun up from the same templates.These same principles—resilience, clarity, and structured thinking—also underpin how engineers should approach system design interviews.Mastering the System Design InterviewCracking the system design interview is a priority for many mid-level engineers aiming for senior roles, and for good reason. Sinha points out that system design skill isn’t just a hiring gate – it often determines your level/title once you’re in a company. Unlike coding interviews where problems have a neat optimal solution, “system design is messy. You can take it in many directions, and that’s what makes it interesting,” Sinha says. Interviewers want to see how you navigate an open-ended problem, not whether you can memorize a textbook solution. Both Sinha and Chopra emphasize structured thinking and communication. Hiring managers deliberately ask ambiguous or underspecified questions to see if the candidate will impose structure: Do they ask clarifying questions? Do they break the problem into parts (data storage, workload patterns, failure scenarios, etc.)? Do they discuss trade-offs out loud? Sinha and Chopra offer two guidelines:There’s rarely a single “correct” answer: What matters is reasoning and demonstrating that you can make sensible trade-offs under real-world constraints. “It’s easy to choose between good and bad solutions,” Sinha notes, “but senior engineers often have to choose between two good options. I want to hear their reasoning: Why did you choose this approach? What trade-offs did you consider?” A strong candidate will articulate why, say, they picked SQL over NoSQL for a given scenario – and acknowledge the downsides or conditions that might change that decision. In fact, Chopra may often follow up with “What if you had 10× more users? Would your choice change?” to test the adaptability of a candidate’s design. He also likes to probe on topics like consistency models: strong vs eventual consistency and the implications of the CAP theorem. Many engineers “don’t fully grasp how consistency, availability, and partition tolerance interact in real-world systems,” Chopra observes, so he presents scenarios to gauge depth of understanding.Demonstrate a collaborative, inquisitive approach: A system design interview shouldn’t be a monologue; it’s a dialogue. Chopra says, “I try to keep the interview conversational. I want the candidate to challenge some of my assumptions.” For example, a candidate might ask: What are the core requirements? Are we optimizing for latency or throughput? or How many users are we targeting initially? — “that kind of questioning is exactly what happens in real projects,” Chopra explains. It shows the candidate isn’t just regurgitating a pre-learned architecture, but is actively scoping the problem like they would on the job. Strong candidates also prioritize requirements on the fly – distinguishing must-haves (e.g. high availability, security) from nice-to-haves (like an optional feature that can be deferred).Through years of interviews, Sinha and Chopra have noticed three common pitfalls:Jumping into solution-mode too fast: “Candidates don’t spend enough time right-sizing the problem,” says Chopra. “The first 5–10 minutes should be spent asking clarifying questions—what exactly are we designing, what are the constraints, what assumptions can we make?” Diving straight into drawing boxes and lines can lead you down the wrong path. Sinha agrees: “They hear something familiar, get excited, and dive into design mode—often without even confirming what they’re supposed to be designing. In both interviews and real life, that’s dangerous. You could end up solving the wrong problem.”Lack of structure – jumping randomly between components without a clear plan: This scattered approach makes it hard to know if you’ve covered the key areas. Interviewers prefer a candidate who outlines a high-level approach (e.g. client > service > data layer) before zooming in, and who checks back on requirements periodically.Poor time management: It’s common for candidates to get bogged down in details early (like debating the perfect database indexing scheme) and then run out of time to address other important parts of the system. Sinha and Chopra recommend practicing pacing yourself and be willing to defer some details. It’s better to have a complete, if imperfect, design than a perfect cache layer with no time to discuss security or analytics requirements. If an interviewer hints to move on or asks about an area you haven’t covered, take the cue. “Listen to the interviewer’s cues,” Sinha advises. “We want to help you succeed, but if you miss the hints, we can’t evaluate you properly.”Tech interviews in general have gotten more demanding in 2025. The format of system design interviews hasn’t drastically changed, but the bar is higher. Companies are more selective, sometimes even “downleveling” strong candidates if they don’t perfectly meet the senior criteria. Evan King and Stefan Mai, cofounders of interview preparation startup, in an article in The Pragmatic Engineer observe, “performance that would have secured an offer in 2021 might not even clear the screening stage today”. This reflects a market where competition is fierce and expectations for system design prowess are rising. But as Chopra and Sinha illustrate, the goal is not to memorize solutions – it’s to master the art of trade-offs and critical thinking.Beyond Interviews: System Design as a Career CatalystSystem design isn’t just an interview checkbox – it’s a fundamental skill for career growth in engineering. “A lot of people revisit system design only when they're preparing for interviews,” Sinha says. “But having a strong grasp of system design concepts pays off in many areas of your career.” It becomes evident when you’re vying for a promotion, writing an architecture document, or debating a new feature in a design review.Engineers with solid design fundamentals tend to ask the sharp questions that others miss (e.g. What happens if this service goes down? or Can our database handle 10x writes?). They can evaluate new technologies or frameworks in the context of system impact, not just code syntax. Technical leadership roles especially demand this big-picture thinking. In fact, many companies now expect even engineering managers to stay hands-on with architecture – “system design skills are becoming non-negotiable” for leadership.Mastering system design also improves your technical communication. As you grow more senior, your success depends on how well you can simplify complexity for others – whether in documentation or in meetings. “It’s not just about coding—it’s about presenting your ideas clearly and convincingly. That’s a huge part of leadership in engineering,” Sinha notes. Chopra agrees, framing system design knowledge as almost a mindset: “System design is almost a way of life for senior engineers. It’s how you continue to provide value to your team and organization.” He compares it to learning math: you might not explicitly use the quadratic formula daily, but learning it trains your brain in problem-solving.Perhaps the most exciting aspect is that the future is wide open. “Many of the systems we’ll be working on in the next 10–20 years haven’t even been built yet,” Chopra points out. We’re at an inflection point with technologies like AI agents and real-time data streaming pushing boundaries; those with a solid foundation in distributed systems will be the “go-to” people to harness these advances. And as Chopra notes,“seniority isn’t about writing complex code. It’s about simplifying complex systems and communicating them clearly. That’s what separates great engineers from the rest.”System design proficiency is a big part of developing that ability to cut through complexity.Emerging Trends and Next Frontiers in System DesignWhile core principles remain steady, the ecosystem around system design is evolving rapidly. We can identify three significant trends:Integration of AI Agents with Software Systems: As Gavin Bintz writes in Agent One, an emerging trend is the integration of AI agents with everyday software systems. New standards like Anthropic’s Model Context Protocol (MCP), are making it easier for AI models to securely interface with external tools and services. You can think of MCP as a sort of “universal adapter” that lets a large language model safely query your database, call an API like Stripe, or post a message to Slack – all through a standardized interface. This development opens doors to more powerful, context-aware AI assistants, but it also raises architectural challenges. Designing a system that grants an AI agent limited, controlled access to critical services requires careful thought around authorization, sandboxing, and observability (e.g., tracking what the AI is doing). Chopra sees MCP as fertile ground for new system design patterns and best practices in the coming years.Deepening of observability and automation in system management: Imagine systems that not only detect an anomaly but also pinpoint the likely root cause across your microservices and possibly initiate a fix. As Sam Suthar, Founding Director at Middleware, observes, early steps in this direction are already in play – for example, tools that correlate logs, metrics, and traces across a distributed stack and use machine learning to identify the culprit when something goes wrong. The ultimate goal is to dramatically cut Mean Time to Recovery (MTTR) when incidents occur, using AI to assist engineers in troubleshooting. As one case study showed, a company using AI-based observability was able to resolve infrastructure issues 75% faster while cutting monitoring costs by 75%. The complexity of modern cloud environments is pushing us toward this new normal of predictive, adaptive systems.Sustainable software architecture: There is growing dialogue now about designing systems that are not only robust and scalable, but also efficient in their use of energy and resources. The surge in generative AI has shone a spotlight on the massive power consumption of large-scale services. According to Kemene et al., in an article published by the World Economic Forum (WEF), Data centers powering AI workloads can consume as much electricity as a small city; the International Energy Agency projects data center energy use will more than double by 2030, with AI being “the most important driver” of that growth. Green software engineering principles urge us to consider the carbon footprint of our design choices. Sinha suggests this as an area to pay attention to.Despite faster cycles, sharper constraints and more automation system design remains grounded in principles. As Chopra and Sinha make clear, the ability to reason about failure, scale, and trade-offs isn’t just how systems stay up; it’s also how engineers move up in their career.If you found Sinha and Chopra’s perspective on designing for scale and failure compelling, their book System Design Guide for Software Professionals unpacks the core attributes that shape resilient distributed systems. The following excerpt from the book breaks down how consistency, availability, partition tolerance, and other critical properties interact in real-world architectures. You’ll see how design choices around reads, writes, and replication influence system behavior—and why understanding these trade-offs is essential for building scalable, fault-tolerant infrastructure.Expert Insight: Distributed System Attributes by Dhirendra Sinha and Tejas ChopraThe complete “Chapter 2: Distributed System Attributes” from the book System Design Guide for Software Professionals by Dhirendra Sinha and Tejas Chopra (Packt, August 2024)…Before we jump into the different attributes of a distributed system, let’s set some context in terms of how reads and writes happen.Let’s consider an example of a hotel room booking application (Figure 2.1). A high-level design diagram helps us understand how writes and reads happen:Figure 2.1 – Hotel room booking request flowAs shown in Figure 2.1, a user (u1) is booking a room (r1) in a hotel and another user is trying to see the availability of the same room (r1) in that hotel. Let’s say we have three replicas of the reservations database (db1, db2, and db3). There can be two ways the writes get replicated to the other replicas: The app server itself writes to all replicas or the database has replication support and the writes get replicated without explicit writes by the app server.Let’s look at the write and the read flows:Read the Complete ChapterSystem Design Guide for Software Professionals by Dhirendra Sinha and Tejas Chopra (Packt, August 2024) is a comprehensive, interview-ready manual for designing scalable systems in real-world settings. Drawing on their experience at Google, Netflix, and Yahoo, the authors combine foundational theory with production-tested practices—from distributed systems principles to high-stakes system design interviews.For a limited time, get the eBook for $9.99 at packtpub.com — no code required.Get the Book🛠️Tool of the Week⚒️Diagrams 0.24.4 — Architecture Diagrams as Code, for System DesignersDiagrams is an open source Python toolkit that lets developers define cloud architecture diagrams using code. Designed for rapid prototyping and documentation, it supports major cloud providers (AWS, GCP, Azure), Kubernetes, on-prem infrastructure, SaaS services, and common programming frameworks—making it ideal for reasoning about modern system design.The latest release (v0.24.4, March 2025) adds stability improvements and ensures compatibility with recent Python versions. Diagrams has been adopted in production projects like Apache Airflow and Cloudiscovery, where infrastructure visuals need to be accurate, automatable, and version controlled.Highlights:Diagram-as-Code: Define architecture models using simple Python scripts—ideal for automation, reproducibility, and tracking in Git.Broad Provider Support: Over a dozen categories including cloud platforms, databases, messaging systems, DevOps tools, and generic components.Built on Graphviz: Integrates with Graphviz to render high-quality, publishable diagrams.Extensible and Scriptable: Easily integrate with build pipelines or architecture reviews without relying on external design tools.Visit Diagrams' GitHub Repo📰 Tech BriefsAnalyzing Metastable Failures in Distributed Systems: A new HotOS'25 paper builds on prior work to introduce a simulation-based pipeline—spanning Markov models, discrete event simulation, and emulation—to help engineers proactively identify and mitigate metastable failure modes in distributed systems before they escalate.A Senior Engineer's Guide to the System Design Interview: A comprehensive, senior-level guide to system design interviews that demystifies core concepts, breaks down real-world examples, and equips engineers with a flexible, conversational framework for tackling open-ended design problems with confidence.Using Traffic Mirroring to Debug and Test Microservices in Production-Like Environments: Explores how production traffic mirroring—using tools like Istio, AWS VPC Traffic Mirroring, and eBPF—can help engineers safely debug, test, and profile microservices under real-world conditions without impacting users.Designing Instagram: This comprehensive system design breakdown of Instagram outlines the architecture, APIs, storage, and scalability strategies required to support core features like media uploads, feed generation, social interactions, and search—emphasizing reliability, availability, and performance at massive scale.Chiplets and the Future of System Design: A forward-looking piece on how chiplets are reshaping the assumptions behind system architecture—covering yield, performance, reuse, and the growing need for interconnect standards and packaging-aware system design.That’s all for today. Thank you for reading the first issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey we now run monthly—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor in Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0

Divya Anne Selvaraj
12 Jun 2025
21 min read
Save for later

Deep Engineering #4: Alessandro Colla and Alberto Acerbis on Domain-Driven Refactoring at Scale

Divya Anne Selvaraj
12 Jun 2025
21 min read
Why understanding the domain beats applying patterns—and how to refactor without starting over#4Alessandro Colla and Alberto Acerbis on Domain-Driven Refactoring at ScaleWhy understanding the domain beats applying patterns—and how to refactor without starting overWelcome to the fourth issue of Deep Engineering.In enterprise software systems, few challenges loom larger than refactoring legacy systems to meet modern needs. These efforts can feel like open-heart surgery on critical applications that are still running in production. Systems requiring refactoring are often business-critical, poorly modularized, and resistant to change by design.To understand how Domain-Driven Design (DDD) can guide this process, we spoke with Alessandro Colla and Alberto Acerbis—authors of Domain-Driven Refactoring (Packt, 2025) and co-founders of the "DDD Open" and "Polenta and Deploy" communities.Colla brings over three decades of experience in eCommerce systems, C# development, and strategic software design. Acerbis is a Microsoft MVP and backend engineer focused on building maintainable systems that deliver business value. Together, they offer a grounded, pattern-skeptical view of what DDD really looks like in legacy environments—and how teams can use it to make meaningful change without rewriting from scratch.You can watch the full interview and read the full transcript here—or keep reading for our distilled take on the principles, pitfalls, and practical steps that shape successful DDD refactoring.Sign Up |AdvertiseThe conference to learn, apply, and improve your craftdev2next is the premier conference designed for software developers, architects, technology leaders, development managers, and directors. Explore cutting-edge strategies, tools, and essential practices for building powerful applications using the latest trends and good practices.When: September 29 - October 2, 2025Where: Colorado Springs, COBuy Conference and Workshop TicketsPrinciples over Patterns: Applying DDD to Legacy Systems with Alessandro Colla and Alberto AcerbisLegacy systems are rarely anyone’s favorite engineering challenge. Often labeled “big balls of mud,” these aging codebases resist change by design—lacking tests, mixing concerns, and coupling business logic to infrastructure in ways that defy modular thinking. Yet they remain critical. “It’s more common to work on what we call legacy code than to start fresh,” Acerbis notes from experience. Their new book, Domain-Driven Refactoring, was born from repeatedly facing large, aging codebases that needed new features. “The idea behind the book is to bring together, in a sensible and incremental way, how we approach the evolution of complex legacy systems,” explains Colla. Rather than treat DDD as something only for new projects, Colla and Acerbis show how DDD’s concepts can guide the incremental modernization of existing systems.They begin by reinforcing core DDD concepts—what Colla calls their “foundation”—before demonstrating how to apply patterns gradually. This approach acknowledges a hard truth: when a client asks for “a small refactor” of a legacy system, “it’s never small. It always becomes a bigger refactor,” Acerbis says with a laugh. The key is to take baby steps. “Touching a complex system is always difficult, on many levels,” Colla cautions, so the team must break down the work into manageable changes rather than trying an all-at-once overhaul.Modular Monoliths Before MicroservicesOne of the first decisions in a legacy overhaul is whether to break a monolithic application into microservices. But Colla and Acerbis urge caution here—hype should not dictate architecture.“Normally, a customer comes to us asking to transform their legacy application into a microservices system because — you know — ‘my cousin told me microservices solve all the problems,’” Acerbis jokes. The reality is that blindly carving up a legacy system into microservices can introduce as much complexity as it removes. “Once you split your system into microservices, your architecture needs to support that split,” he explains, from infrastructure and deployment to data consistency issues.Instead, the duo advocates an interim step: first evolve the messy monolith into a well-structured modular monolith. “Using DDD terms, you should move your messy monolith into a good modular monolith,” says Acerbis. In a modular monolith, clear boundaries are drawn around business subdomains (often aligning with DDD bounded contexts), but the system still runs as a single deployable unit. This simplification and ordering within the monolith can often deliver the needed agility and clarity. “We love monoliths, OK? But modular ones,” Colla admits. With a modular monolith in place, teams can implement new features more easily and see if further decomposition is truly warranted. Only if needed—due to scale or independent deployment demands—should you “split it into microservices. But that’s a business and technical decision the whole team needs to make together,” Acerbis emphasizes.By following this journey, teams often find full microservices unnecessary. Colla notes that many times they’ve been able to meet all business requirements just by going modular, without ever needing microservices. The lesson: choose the simplest architecture that solves the problem and avoid microservices sprawl unless your system’s scale and complexity absolutely demand it.First Principles: DDD as a Mindset, Not a ChecklistA central theme from Colla and Acerbis is that DDD is fundamentally about understanding the problem domain, not checking off a list of patterns. “Probably the most important principle is that DDD is not just technical — it’s about principles,” says Acerbis. Both engineers stress the importance of exploration and ubiquitous language before diving into code. “Start with the strategic patterns — particularly the ubiquitous language — to understand the business and what you’re dealing with,” Colla advises. In practice, that means spending time with domain experts, clarifying terminology, and mapping out the business processes and subdomains. Only once the team shares a clear mental model of “what actually needs to be built” should they consider tactical design patterns or write any code.Colla candidly shares that he learned this the hard way.“When I started working with DDD, CQRS, and event sourcing, I made the mistake of jumping straight into technical modeling — creating aggregates, entities, value objects — because I’m a developer, and that’s what felt natural. But I skipped the step of understanding why I was building those classes.I ended up with a mess.”Now he advocates for understand the why, then the how. “We spent the first chapters of the book laying out the principles. We wanted readers to understand the why — so that once you get to the code, it comes naturally,” Colla says.This principle-centric mindset guards against a common trap: applying DDD patterns by rote or “cloning” a solution from another project.“I’ve seen situations where someone says, ‘I’ve already solved a similar problem using DDD — I’ll just reuse that design.’ But no, that’s not how it works,” Acerbis warns.Every domain is different, and DDD is “about exploration. Every situation is different.” By treating DDD as a flexible approach to learning and modeling the domain—rather than a strict formula—teams can avoid over-engineering and build models that truly fit their business.From Strategic to Tactical: Applying Patterns IncrementallyOnce the team has a solid grasp of the domain, they can start to apply DDD’s tactical patterns (entities, value objects, aggregates, domain events, etc.) to reshape the code. But which pattern comes first? Colla doesn’t prescribe a one-size-fits-all sequence. “I don’t think there’s a specific pattern to apply before others,” he says. The priority is dictated by the needs of the domain and the pain points in the legacy code. However, the strategic understanding guides the tactical moves: by using the ubiquitous language and bounded contexts identified earlier, the team can decide where an aggregate boundary should be, where to introduce a value object for a concept, and so on.Acerbis emphasizes that their book isn’t a compendium of all DDD patterns—classic texts already cover those. Instead, it shows how to practically apply a selection of patterns in a legacy refactoring context. The aim is to go from “a bad situation — a big ball of mud — to a more structured system,” he says. A big win of this structure is that new features become easier to add “without being afraid of introducing bugs or regressions,” because the code has clear separation of concerns and meaningful abstractions.Exploring the domain comes first. Only then should the team “bring in the tactical patterns when you begin touching the code,” says Colla. In other words, let the problem guide the solution. By iteratively applying patterns in the areas that need them most, the system gradually transforms—all while continuing to run and deliver value. This incremental refactoring is core to their approach; it avoids the risky big-bang rewrite and instead evolves the architecture piece by piece, in sync with growing domain knowledge.Balancing Refactoring with Rapid DeliveryIn theory, it sounds ideal to methodically refactor a system. In reality, business stakeholders are rarely patient—they need new features yesterday. Colla acknowledges this tension:“This is the million-dollar question. As in life, the answer is balance. You can't have everything at once — you need to balance features and refactoring.”The solution is to weave refactoring into feature development, rather than treating it as a separate project that halts new work.“Stakeholders want new features fast because the system has to keep generating value,” Colla notes. Completely pausing feature development for months of cleanup is usually a non-starter (“We’ve had customers say, ‘You need to fix bugs and add new features — with the same time and budget.’”). Instead, Colla’s team refactors in context: “if a new feature touches a certain area of the system, we refactor that area at the same time.” This approach may slightly slow down that feature’s delivery, but it pays off in the long run by preventing the codebase from deteriorating further. Little by little (“always baby steps,” as Colla says), they improve the design while still delivering business value.Acerbis adds that having a solid safety net of tests is what makes this sustainable. Often, clients approach them saying it’s too risky or slow to add features because “the monolith has become a mess.” The first order of business, then, is to shore up test coverage.“We usually start with end-to-end tests to make sure that the system behaves the same way after changes,” he explains.Writing tests for a legacy system can be time-consuming initially, but it instills confidence.“In the beginning, it takes time. You have to build that infrastructure and coverage. But as you move forward, you’ll see the benefits — every time you deploy a new feature, you’ll know it was worth it.”With robust tests in place, the team can refactor aggressively within each iteration, knowing they will catch any unintended side effects before they reach users.Aligning Architecture with OrganizationEven the best technical refactoring will falter if organizational structure is at odds with the design. This is where Conway’s Law comes into play—the notion that software systems end up reflecting the communication structures of the organizations that build them.“When introducing DDD, it’s not just about technical teams. You need involvement from domain experts, developers, stakeholders — everyone,” says Acerbis.In practice, this means that establishing clean bounded contexts in code may eventually require realigning team responsibilities or communication paths in the company.Of course, changing an organization chart is harder than changing code. Colla and Acerbis therefore approach it in phases. “Context mapping is where we usually begin — understanding what each team owns and how they interact,” Colla explains. They first try to fix the code boundaries while not breaking any essential communication between people or teams. For instance, if two modules should only talk via a well-defined interface, they might introduce an anti-corruption layer in code, even if the same two teams still coordinate closely as they always have. Once the code’s boundaries stabilize and prove beneficial, the case can be made to align the teams or management structure accordingly.“The hardest part is convincing the business side that this is the right path,” Acerbis admits. Business stakeholders control budgets and priorities, so without their buy-in, deep refactoring stalls. The key is to demonstrate value early and keep them involved. Ultimately, “it only works if the business side is on board — they’re the ones funding the effort,” he says. Colla concurs: “everyone — developers, architects, business — needs to share the same understanding. Without that alignment, it doesn’t work.” DDD, done right, becomes a cross-discipline effort, bridging tech and business under a common language and vision.Building a Safety Net: Tools and Testing TechniquesGiven the complexity of legacy transformation, what tools or frameworks can help? Colla’s answer may surprise some: there is no magic DDD framework that will do it for you. “There aren’t any true ‘DDD-compliant’ frameworks,” he says. DDD isn’t something you can buy off-the-shelf; it’s an approach you must weave into how you design and code. However, there are useful libraries and techniques to smooth the journey, especially around testing and architecture fitness.“What’s more important to me is testing — especially during refactoring. You need a strong safety net,” Colla emphasizes. His team’s rule of thumb: start by writing end-to-end tests for current behavior. “We always start with end-to-end tests. That way, we make sure the expected behavior stays the same,” Colla shares. These broad tests cover critical user flows so that if a refactoring accidentally changes something it shouldn’t, the team finds out immediately. Next, they add architectural tests (often called fitness functions) to enforce the intended module boundaries. “Sometimes, dependencies break boundaries. Architectural tests help us catch that,” he notes. For instance, a test might ensure that code in module A never calls code in module B directly, enforcing decoupling. And of course, everyday unit tests are essential for the new code being written: “unit tests, unit tests, unit tests,” Colla repeats for emphasis. “They prove your code does what it should.”Acerbis agrees that no all-in-one DDD framework exists (and maybe that’s for the best). “DDD is like a tailor-made suit. Every time, you have to adjust how you apply the patterns depending on the problem,” he says. Instead of relying on a framework to enforce DDD, teams should rely on discipline and tooling – especially the kind of automated tests Colla describes – to keep their refactoring on track. Acerbis also offers a tip on using AI assistance carefully: tools like GitHub Copilot can be helpful for generating code, but “you don’t know how it came up with that solution.” He prefers to have developers write the code with understanding, then use AI to review or suggest improvements. This ensures that the team maintains control over design decisions rather than blindly trusting a tool.Event-Driven Architecture: Avoiding the "Distributed Monolith"DDD often goes hand-in-hand with event-driven architecture for decoupling. Used well, domain events can keep bounded contexts loosely coupled. But Colla and Acerbis caution that it’s easy to misuse events and end up with a distributed mess. Acerbis distinguishes two kinds of events with very different roles: domain events and integration events. “Domain events should stay within a bounded context. Don’t share them across services,” he warns. If you publish your internal domain events for other microservices to consume, you create tight coupling: “when you change the domain event — and you will — you’ll need to notify every team that relies on it. That’s tight coupling, not decoupling.”The safer pattern is to keep domain events private to a service or bounded context, and publish separate integration events for anything that truly needs to be shared externally. That way, each service can evolve its internal model (and its domain event definitions) independently. Colla admits he’s learned this by making the mistakes himself. The temptation is to save effort by reusing an event “because it feels efficient,” but six months later, when one team changes that event’s schema, everything breaks. “We have to resist that instinct and think long-term,” he says. Even if it requires a bit more work upfront to define distinct integration events, it prevents creating what he calls a “distributed monolith that’s impossible to evolve” – a system where services are theoretically separate but so tightly coupled by data contracts that they might as well be a single unit.Another often overlooked aspect of event-driven systems is the user experience in an eventually consistent world. Because events introduce asynchrony, UIs must be designed to handle the delay. Acerbis mentions using task-based UIs, where screens are organized around high-level business tasks rather than low-level CRUD forms, to better set user expectations and capture intent that aligns with back-end processes. The bottom line is that events are powerful, but they come with their own complexities – teams must design and version them thoughtfully, and always keep the end-to-end system behavior in mind.💡What This Means for YouDon’t jump in without understanding the domain: Slow down and truly grasp the domain events and logic before coding them. Focus on principles before patterns. DDD isn’t a bag of technical tricks, but a way to deeply understand the business domain before coding solutions. Align with the business. Technical architecture must reflect the domain and may require organizational buy-in and alignment (think Conway’s Law).Beware the golden hammer: “Use DDD where it makes sense. You don’t need to apply it to your entire system,” Acerbis advises. Focus DDD efforts on the core domain (where the competitive advantage lies), and keep supporting domains simple. Modular monolith first. Instead of rushing into microservices, first untangle your “big ball of mud” into a well-structured modular monolith—often that's enough.No “Franken-events”: If you see an “and” in an event name, that’s a red flag – it likely violates the single responsibility principle for events and will cause trouble when one part of that event changes and the other doesn’t. Refactor in baby steps. Integrate refactoring tasks into regular feature work, supported by a strong safety net of tests, to balance improvement with delivery.Never allow invalid data by design: A subtle but dangerous practice is allowing objects or aggregates in an invalid state (for example, by using flags like isValid). “Your aggregates should always be in a valid state,” Acerbis emphasizes, meaning your constructors or factories should enforce invariants so you don’t have to constantly check validity later.Don’t split the system before it’s ready: Microservices introduce complexity too early. “Once you split your system into microservices, your architecture needs to support that split,” Acerbis warns. Work on converting to a modular monolith first—often that's enough.“Simple” versus “easy” code: “Simple code is not the same as easy code. Simple code takes effort. Easy code is quick, but it’s hard to maintain,” says Acerbis. What feels “easy” in the moment (quick-and-dirty hacks, copy-paste coding, skipping tests) leads to a tangled mess. Writing simple, clear code often requires more thought and discipline—but it pays off with maintainability. Evolve, don’t rewrite. Aim to evolve the system through continuous small changes rather than costly complete rewrites.If you found Colla and Acerbis’ insights useful, their book, Domain-Driven Refactoring offers a deeper, hands-on perspective—showing how to incrementally apply DDD principles in real systems under active development with substantial code examples. Here is an excerpt which covers how to integrate events within a CQRS architecture.Expert Insight: Integrating Events with CQRS by Alessandro Colla and Alberto AcerbisAn Excerpt from “Chapter 7: Integrating Events with CQRS” in the book Domain-Driven Refactoring by Alessandro Colla and Alberto Acerbis (Packt, May 2025)In this chapter, we will explore how to effectively integrate events into your system using the Command Query Responsibility Segregation (CQRS) pattern. As software architectures shift from monolithic designs to more modular, distributed systems, adopting event-driven communication becomes essential. This approach offers scalability, decoupling, and resilience, but also brings complexity and challenges such as eventual consistency, fault tolerance, and infrastructure management.The primary goal of this chapter is to guide you through the implementation of event-driven mechanisms within the context of a CQRS architecture. By the end of this chapter, you will have a clear understanding of how events and commands operate in tandem to manage state changes, communicate between services, and optimize both the reading and writing of data.(In this excerpt) you will learn about the following:The benefits and trade-offs of transitioning from synchronous to asynchronous communicationHow event-driven architectures improve system scalability and decouplingThe difference between commands (which trigger state changes) and events (which signal that something has happened)How to apply proper message-handling patterns for bothThe principles of CQRS and understanding why separating read and write models enhances performance and scalabilityHow to implement the separation of command and query responsibilities with a focus on read and write optimizationHow to introduce a message broker for handling asynchronous communicationHow to capture and replay the history of state changes with event sourcingRead the Complete ExcerptDomain-Driven Refactoring by Alessandro Colla and Alberto Acerbis is a practical guide to modernizing legacy systems using DDD. Through real-world C# examples, the authors show how to break down monoliths into modular architectures—whether evolving toward microservices or improving maintainability within a single deployable unit. The book covers both strategic and tactical patterns, including bounded contexts, aggregates, and event-driven integration.Use code DOMAIN20 for 20% off at packtpub.com — valid through June 16, 2025.Get the Book🛠️Tool of the Week⚒️Context Mapper 6.12.0 — Strategic DDD Refactoring, VisualizedContext Mapper is an open source modeling toolkit for strategic DDD, purpose-built to define and evolve bounded contexts, map interrelationships, and drive architectural refactorings. It offers a concise DSL for creating context maps and includes built-in transformations for modularizing monoliths, extracting services, and analyzing cohesion/coupling trade-offs.The latest version continues its focus on reverse-engineering context maps from Spring Boot and Docker Compose projects, along with support for automated architectural refactorings—making it ideal for teams modernizing legacy systems or planning microservice transitions.Highlights:Iterative Refactoring: Apply “Architectural Refactorings” to improve modularity without rewriting everything.Reverse Engineering: Extract bounded context candidates from existing codebases using the Context Map Discovery library.Multi-Format Output: Export maps to Graphviz, PlantUML, MDSL, or Freemarker-based text formats.IDE Integrations: Available as plugins for Eclipse and VS Code, or use it directly in Gitpod without local setup.Visit the Project Website📰 Tech BriefsArchitecture Refactoring Towards Service Reusability in the Context of Microservices by Daniel et al.: This paper proposes a catalog of architectural refactorings—Join API Operations with Heterogeneous Data, Introduce Metadata, and Extract Pluggable Processors—to improve service reusability in microservice architectures by reducing code duplication, decoupling data from processing logic, and supporting heterogeneous inputs, and validates these patterns through impact analysis on three real-world case studies.DDD & LLMs - Eric Evans - DDD Europe 2024: In this keynote, Evans reflects on the transformative potential of large language models in software development, urging the community to embrace experimentation, learn through hands-on projects, and explore how DDD might evolve—or be challenged—in an era increasingly shaped by AI-assisted systems.Domain Re-discovery Patterns for Legacy Code - Richard Groß - DDD Europe 2024: In this talk, Groß introduces domain rediscovery patterns for legacy systems—ranging from passive analysis techniques like mining repositories and activity logging to active refactoring patterns and visualization tools—all aimed at incrementally surfacing domain intent, guiding safe modernization without full rewrites, and avoiding hidden technical and organizational costs of starting from scratch.Legacy Modernization meets GenAI by Ferri et al., Thoughtworks: This article discusses how GenAI can address core challenges in legacy system modernization—such as reverse engineering, capability mapping, and high-level system comprehension—arguing for a human-guided, evolutionary approach while showcasing Thoughtworks’ internal accelerator, CodeConcise, as one practical application of these ideas.Refactor a monolith into microservices by the Google Cloud Architecture Center: This guide outlines how to incrementally refactor a monolithic application into microservices using DDD, bounded contexts, and asynchronous communication—emphasizing the Strangler Fig pattern, data and service decoupling strategies, and operational considerations like distributed transactions, service boundaries, and database splitting.That’s all for today. Thank you for reading the first issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor in Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}.reverse{display:table;width: 100%;
Read more
  • 0
  • 0

Divya Anne Selvaraj
05 Jun 2025
16 min read
Save for later

Deep Engineering #3: Designing for AI and Humans with MoonBit Core Contributor Zihang YE

Divya Anne Selvaraj
05 Jun 2025
16 min read
From CLI design to AI ergonomics—MoonBit offers patterns worth borrowing#3Designing for AI and Humans with MoonBit Core Contributor Zihang YEFrom CLI design to AI ergonomics—MoonBit offers patterns worth borrowingHi ,Welcome to the third issue of Deep Engineering.AI agents are no longer just code generators, they’re becoming active users of codebases, APIs, and developer tools. From semantic documentation protocols to agent-readable APIs, the systems we design must increasingly expose structure, context, and intent. Software now needs to serve two audiences—humans and machines.This issue explores what that means in practice, through the lens of MoonBit—a new language built from the ground up for WebAssembly (Wasm)-native performance and AI-first tooling.Our feature article examines how MoonBit responds to this dual-audience challenge: not with flashy syntax, but with a tightly integrated toolchain and a runtime model designed to be both fast and machine-consumable. And in a companion tutorial, MoonBit core contributor Zihang YE walks us through building a diff algorithm as a Wasm-ready CLI—an instructive example of the language’s design philosophy in action.Sign Up |AdvertiseSponsored:Web Devs: Turn Your Knowledge Into IncomeBuild the knowledge base that will enable you to collaborate with AI for years to come💰 Competitive Pay Structure⏰ Ultimate Flexibility🚀 Technical Requirements (No AI Experience Needed)Weekly payouts + remote work: The developer opportunity you've been waiting for!The flexible tech side hustle paying up to $50/hourApply NowBeyond Syntax: MoonBit and the Future of Language, Tooling, and AI WorkflowsThe mainstream dominance of Python, JavaScript, and Rust might suggest the age of new programming languages is over. A new breed of languages including MoonBit prove otherwise—not by reinventing syntax, but by responding to two tectonic shifts in software development: AI-assisted workflows, and the rise of Wasm-native deployment in cloud and edge environments.In edge computing and micro-runtime environments, developers need tools that start instantly, consume minimal memory, and run predictably across platforms. MoonBit’s design responds directly to this: it produces compact Wasm binaries optimized for streaming data, making it suitable for CLI tools, embedded components, and other low-overhead tasks.At the same time, AI workloads are exposing the limitations of dynamic languages like Python in large-scale systems. MoonBit’s founders note that Python’s “easy to learn” nature can become a double-edged sword for complex tasks. Even with optional annotations, its dynamic type system can hinder static analysis, complicating maintainability and scalability as codebases grow. In response, MoonBit introduces a statically typed, AI-aware language model with built-in tooling—formatter, package manager, VSCode integration—designed to support both human and machine agents.Rather than replacing Python, MoonBit takes a pragmatic approach. It explicitly embraces an “ecosystem reuse” model: it uses AI-powered encapsulation to lower the barrier for cross-language calls, avoiding reinvention of existing Python tools, and it aims to “democratize” static typing by coupling a strict type system with AI code generation.A Language is Not EnoughMoonBit is a toolchain-native languages, designed from the start to work smoothly with modern build, editing, and AI workflows. Unlike older languages that were retrofitted with new tools, MoonBit bundles its compiler, package manager, IDE, language server, and even an AI assistant as a cohesive whole. As the MoonBit team puts it, they “integrate a comprehensive toolchain from the start” to provide a streamlined coding experience.This stands in contrast to older systems languages like C/C++ and even to modern ones like Rust, which, despite its safety guarantees, still requires extra configuration to target Wasm. MoonBit by design treats Wasm as its primary compilation target – it is “Wasm-first”, built “as easy as Golang” but generating very compact Wasm output.Similarly, MoonBit was conceived to work hand-in-hand with AI tools. It offers built-in hooks for AI code assistance (more on this below) and even considers AI protocols like Anthropic’s Model Context Protocol (MCP) as first-class integration points. In MoonBit, the language + toolchain combo is now a single product, not an afterthought.MoonBit is not alone. Other new languages like Grain, Roc, and Hylo (formerly Val) each explore different priorities—from functional programming for the web to safe systems-level design and simplified developer experience.Grain prioritizes JS interop and functional ergonomics; Roc favors simplicity and speed, though it’s still pre-release; and Hylo experiments with value semantics and low-level control. MoonBit and these other languages make it clear that language design is soon going to become inseparable from its runtime, developer experience, and AI integration.Architecture and Developer ExperienceMoonBit’s architecture reflects a deliberate focus on toolchain integration and cross-platform performance. It is a statically typed, multi-paradigm language influenced by Go and Rust, supporting generics, structural interfaces, and static memory management. The compiler is designed for whole-program optimization, producing Wasm or native binaries with minimal overhead. According to benchmarks cited by the team, MoonBit compiled 626 packages in 1.06 seconds—approximately 9x faster than Rust in the same test set. Its default Wasm output is compact: a basic HTTP service compiles to ~27 KB, which compares favorably to similar Rust (~100 KB) and JavaScript (~8.7 MB) implementations. This is partly due to MoonBit’s support for Wasm GC, allowing it to omit runtime components that Rust must include.The syntax and structure are also optimized for machine parsing. All top-level definitions require explicit types, and interface methods are defined at the top level rather than nested. This flatter structure reportedly improves LLM performance by reducing key–value cache misses during code generation. The language includes built-in support for JSON, streaming data processing via iterators, and compile-time error tracking through control-flow analysis.Tooling is tightly coupled with the language. The moon CLI handles compilation, formatting, testing, and dependency management via the Mooncakes registry. The build system, written in Rust, supports parallel, incremental builds. A dedicated LSP server (distributed via npm) integrates MoonBit with IDEs, enabling features like real-time code analysis and completions. Debugging is supported via the CLI with commands like moon run --target js --debug, which link into source-level tools.A browser-based IDE preview is also available. It avoids containers in favor of a parallelized backend and includes an embedded AI assistant capable of generating documentation, suggesting tests, and offering inline explanations. According to the team, this setup is designed to support both developer productivity and AI agent interaction.MoonBit’s performance profile extends beyond Wasm. A recent release introduced an LLVM backend for native compilation. In one example published by the team, MoonBit outperformed Java by up to 15x in a numeric loop benchmark. The language also supports JavaScript as a compilation target, expanding deployment options across web and server contexts.AI Systems as Language ConsumersLLMs are no longer just helping developers write code—they’re starting to read, run, and interact with it. This shift requires rethinking what it means for a language to be “usable.”MoonBit anticipates this by treating AI systems as first-class consumers of code and tooling. Its team has adopted the MCP, an emerging open standard developed by Anthropic to enable LLMs to interface with external tools and data sources. MCP defines a JSON-RPC server architecture, allowing programs to expose structured endpoints that LLMs can query or invoke. MoonBit’s ecosystem includes a work-in-progress MCP server SDK written in MoonBit and compiled to Wasm, enabling MoonBit components to act as MCP-capable endpoints callable by models such as Claude.This integration reflects a broader shift in tooling. Modern documentation tools like Mintlify now expose semantically indexed content explicitly for AI retrieval. UIs and APIs are being annotated with machine-readable metadata. Even version control is evolving: newer workflows track units of change like (prompt + schema + tests), not just line diffs, enabling intent-aware versioning usable by humans and machines alike.MoonBit’s example agent on GitHub demonstrates this in practice, combining Wasm components (e.g. via Fermyon Spin), LLMs (such as DeepSeek), and MoonBit logic to automate development tasks. Under this model, protocols like MCP enable developers to publish AI-accessible functions directly from their codebases. MoonBit’s support for this workflow—via Wasm and first-party libraries—illustrates a growing view in language design: that AI systems are not just tools for writing code, but active consumers of it.Wasm’s Impact on Performance and PortabilityThree years ago, William Overton, a Senior Serverless Solutions Architect, said, Wasm "starts incredibly quickly and is incredibly light to run," making it well-suited to execute code across CDNs, edge nodes, and lightweight VMs with low startup latency and near-native speed. Today, the growing adoption of Wasm is reshaping expectations for both performance and cross-platform deployment.For MoonBit, Wasm is the default compilation target—not an optional backend. Its tooling is built around producing compact, portable Wasm modules. A simple web server in MoonBit compiles to a 27 KB Wasm binary—significantly smaller than equivalent builds in Rust or JavaScript. This reduction in size translates directly to faster load times and reduced memory usage, making MoonBit viable for constrained environments like embedded systems, CLI tools, and edge deployments.Standardized but still-emerging features like Wasm GC—and experimental ones like the Component Model—further reinforce this model. MoonBit has adopted both: its use of interface types and Wasm GC helps minimize runtime footprint. In a published comparison, MoonBit’s Wasm output was roughly an order of magnitude smaller than that of Rust, largely due to differences in memory management.Taken together, these developments suggest that Wasm is becoming a practical universal format for lightweight applications. For teams building portable utilities or latency-sensitive services, languages with Wasm-native support—such as MoonBit—offer tangible advantages over traditional container- or VM-based approaches.💡What This Means for YouMoonBit offers concrete lessons even if you never write MoonBit code. Key takeaways include:Ecosystem Continuity: Instead of building isolated ecosystems, consider bridging existing ones. MoonBit demonstrates that Python libraries can be reused as external modules—wrapped, if needed, by AI-generated shims. This reduces rewrites and enables gradual migration to safer or more performant languages.Integrated Tooling: Treat your language platform as a cohesive whole. MoonBit’s CLI (moon) unifies compilation, testing, debugging, and package management, minimizing context switches. Its build system exposes project metadata to IDEs via LSP integration. In your own tooling, aim for end-to-end flows powered by a single interface that integrates with the editor.Wasm and Runtime Strategy: For cross-platform deployment, prioritize Wasm as a primary target. MoonBit emits Wasm, JavaScript, or native binaries from a single compiler, and leverages Wasm GC for smaller outputs. Adopt language/toolchain combinations that support compact binaries and multiple backends without sacrificing performance.Data-Oriented Design: MoonBit’s JSON type, Iter abstraction, and pattern matching illustrate a clean model for streaming data. Architect utilities and pipelines to minimize allocations and intermediate state—use iterators, stream transforms, and statically analyzable data access patterns where possible.AI-Friendliness: MoonBit enforces top-level type annotations and flattens scope structures to support linear token generation. If you expect AI tooling to generate, refactor, or analyze your code, avoid deep nesting and implicit state—prefer clarity and structure that LLMs can parse efficiently.Static Checking + AI: MoonBit combines a strict type and error system with AI assistance to ease onboarding and boilerplate generation. This model lets developers write in a safe language without sacrificing velocity. For your own teams, consider pairing statically typed languages (or gradually typed ones like Python with type hints) with copilots that bridge ergonomics and enforcement.CLI Extensibility: The moon CLI supports modular growth—commands like moon new, moon run, and moon add are extensible by design. It can even serve as an LSP or MCP server. Treat your own CLIs as platform interfaces: design for plugin support, programmatic inspection, and long-term integration with AI and editor tooling.To see these ideas in practice—especially MoonBit’s type system, performance model, and Wasm-native tooling—Zihang YE, one of MoonBit’s core contributors, offers a hands-on walkthrough. His article walks us through the implementation of a diff algorithm using MoonBit, building a CLI tool that’s usable both by developers and AI systems via the MCP.Expert Insight: Implementing a Diff Algorithm in MoonBit by Zihang YEA hands-on introduction to MoonBit through the implementation of a version-control-grade diff tool.MoonBit is an emerging programming language that has a robust toolchain and relatively low learning curve. As a modern language, MoonBit includes a formatter, a plugin supporting VSCode, an LSP server, a central package registry, and more. It offers the friendly features of functional programming languages with manageable complexity.To demonstrate MoonBit’s capabilities, we’ll implement a core software development tool—a diff algorithm. Diff algorithms are essential in software development, helping identify changes between different versions of text or code. They power critical tools in version control systems, collaborative editing platforms, and code review workflows, allowing developers to track modifications efficiently. If you have ever used git diff then you are already familiar with such algorithms.The most widely used approach is Eugene W. Myers Diff algorithm, proposed in the paper “An O(ND) Difference Algorithm and Its Variations”. This algorithm is widely used for its optimal time complexity. Its space-efficient implementation and ability to find the shortest edit script make it superior to alternatives like patience diff or histogram diff and make it the standard in version control systems like Git and many text comparison tools such as Meld.In this tutorial, we’ll implement a version of the Myers Diff algorithm in MoonBit. This hands-on project is ideal for beginners exploring MoonBit, offering insight into version control fundamentals while building a tool usable by both humans and AI through a standard API.We will start by developing the algorithm itself, then build a command line application that integrates the Component Model and the MCP, leveraging MoonBit’s WebAssembly (Wasm) backend. Wasm is a blooming technology that provides privacy, portability, and near-native performance by running assembly-like code in virtual machines across platforms —qualities that MoonBit supports natively, making the language well-suited for building efficient cross-platform tools.By the end of this tutorial, you’ll have a functional diff tool that demonstrates these capabilities in action.Project SetupLet’s first create a new moonbit project by running:moon new --lib diffThe following will be the project structure of the code. The moon.mod.json contains the configuration for the project, while the moon.pkg.json contains the configuration for each package. top.mbt is the file we'll be editing throughout this post.├── LICENSE├── moon.mod.json├── README.md└── src ├── lib │ ├── hello.mbt │ ├── hello_test.mbt │ └── moon.pkg.json ├── moon.pkg.json └── top.mbtWe will be comparing two pieces of text, divided each into lines. Each line will include its content and a line number. The line number helps track the exact position of changes, providing important context about the location of changes when displaying the differences between the original and modified files.Read the Complete Tutorial🛠️Tool of the Week⚒️MCP Python SDK 1.9.2 — Structured Interfaces for AI-Native ApplicationsThe MCP is a standard for exposing structured data, tools, and prompts to language models. The MCP Python SDK brings this to production-ready Python environments, with a lightweight, FastAPI-compatible server model and first-class support for LLM interaction patterns. The latest release, v1.9.2 (May 2025), introduces:Streamable HTTP Support: Improved transport layer for scalable, resumable agent communication.Lifespan Contexts: Type-safe initialization for managing resources like databases or auth providers.Authentication: Built-in OAuth2 flows for securing agent-accessible endpoints.Claude Desktop Integration: Direct install into Anthropic’s desktop agent environment via mcp install.Async Tooling: Tools, resources, and prompts can now be async functions with full lifecycle hooks.Ideal for teams designing LLM-facing APIs, building AI-autonomous agents, or integrating prompt-based tools directly into Python services. It’s the protocol MoonBit already supports—and the interface LLMs increasingly expect.Read the Project Description📰 Tech BriefsArchitectural Patterns for AI Software Engineering Agents by Nati Shalom, Fellow at Dell NativeEdge: Examines how modern coding agents are being structured like real-world dev teams—using patterns such as code search, AST analysis, and version-controlled prompt templates to enable disciplined, multi-agent collaboration.A survey of agent interoperability protocols: Model Context Protocol (MCP), Agent Communication Protocol (ACP), Agent-to-Agent Protocol (A2A), and Agent Network Protocol (ANP) by Ehtesham et al.: Offers an in-depth analysis of four emerging protocols designed to enhance interoperability among AI agents, examining their architectures, communication patterns, and security models.When the Agents Go Marching In: Five Design Paradigms Reshaping Our Digital Future by Adrian Levy, Senior UX Expert at CyberArk: Discusses how agentic UX is reshaping everything from collaboration to trust. If MoonBit is what languages might look like in this new world, Levy’s article shows how interfaces and systems are evolving to meet the same challenge, articulating the Agent Experience (AX) paradigm.Beyond augmentation: Agentic AI for software development by the Khare et al., Infosys Knowledge Institute: A practice-oriented report on how autonomous agents are moving from coding assistants to pipeline-integrated actors—handling complex dev tasks end-to-end and delivering measurable productivity gains in database and API generation.Emerging Developer Patterns for the AI Era by Yoko Li, Engineer, a16z: Explores how core concepts like version control, documentation, dashboards, and scaffolding are being reimagined to support AI agents as first-class participants in the software loop—not just code generators, but consumers, collaborators, and operators.That’s all for today. Thank you for reading this issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor-in-Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0

Divya Anne Selvaraj
29 May 2025
18 min read
Save for later

Deep Engineering #2: Dave Westerveld on Scalable API Testing and Orchestration

Divya Anne Selvaraj
29 May 2025
18 min read
Shift-left strategies, parallel test design, and the realities of testing AI-driven APIs at scale#2Dave Westerveld on Scalable API Testing and OrchestrationShift-left strategies, parallel test design, and the realities of testing GraphQL, gRPC, and AI-driven APIs at scaleHi ,Welcome to the second issue of Deep Engineering.Postman’s 2024 State of the API report reveals that 74% of teams now follow an API-first approach, signaling a major shift in software development from the code-first approach. As APIs grow more complex—and as AI agents, gRPC, and GraphQL reshape how services communicate—the question is no longer whether to test early, but how to test well at scale.In this issue, we speak with Dave Westerveld—developer, author of API Testing and Development with Postman, and testing specialist with years of experience across both mature systems and early-stage teams. Drawing from his work on automation strategy, API integration, and scaling quality practices, Dave offers a grounded take on CI pipelines, parallel execution, and the tradeoffs of modern API protocols.You can watch the full interview and read the full transcript here— or keep reading for our distilled take on what makes modern test design both reliable and fastSign Up |AdvertiseSponsored:Webinar: Make Your App a Moving Targetand Leave Attackers GuessingLearn how your app could evolve automatically, leaving reverse engineers behind with every release.Hosted by Guardsquare featuring:Anton Baranenko-Product ManagerDate/time: Tuesday, June 10th at 4 PM CET (10 AM EDT)Register NowFrom REST to Agents: Why Systems Thinking Still Anchors Good API Testing with Dave WesterveldSome testing principles are foundational enough to survive revolutions in tooling. That’s the starting point for Dave Westerveld’s approach to API testing in the post-AI tech landscape.“There are testing principles that were valid in the '80s, before the consumer internet was even a thing. They were valid in the world of desktop and internet computing, and they’re still valid today in the world of AI and APIs.”And while the landscape has shifted dramatically in the last two years—Postman now ships an AI assistant, supports gRPC and GraphQL, and offers orchestration features for agentic architectures—Westerveld believes the best way to scale quality is to combine these new capabilities with timeless habits of mind: systems thinking, structured test design, and a bias for clarity over cleverness.Systems Thinking as the FoundationWesterveld argues that API testers need to operate with a systems-level understanding of the software they’re validating. He calls this:“(The) ability to zoom out and see the entire forest first, and then come back in and see the tree, and realize how it fits into the larger picture and how to approach thinking about and testing it.”In practice, that means asking not just whether an endpoint returns the expected result, but how it fits into the larger architecture and user experience. It means understanding when to run exploratory tests, when to assert workflows, and when to defer to contract validation.These instincts, he says, haven’t changed even as APIs have diversified:“Things like how to approach and structure your testing are … timeless when it comes to REST APIs. They haven’t fundamentally changed in the last 20 years—neither should the way you think about testing them.”What matters more than syntax is structure—how testers reason about coverage, maintainability, and feedback cycles.AI as Accelerant, Not OraclePostman’s Postbot is the most visible new capability in the platform’s AI strategy. Built atop LLM infrastructure, it can suggest test cases, generate assertions, and translate prompts into working scripts. Internally, it draws on your Postman data—collections, environments, history—to provide context-aware assistance.Westerveld sees the benefit, but draws a hard line between skilled and unskilled use:“For a skilled tester, someone with a lot of experience, these AI tools can help you move more quickly through tasks you already know how to do. Often, when you reach that level, you’ve done a lot of testing—you can look at something and say, ‘OK, this is what I need to do here.’ But it can get repetitive to implement some scripts or write things out again and again.”He frames AI as an accelerant: helpful when you understand the underlying logic, risky when you don’t.“For more junior people, there’s a temptation to use AI to auto-generate scripts without fully understanding what those scripts are doing. I think that’s the wrong approach early in your career, because once the AI gets stuck, you won’t know how to move forward.”This caution aligns with Postman’s architectural choices. Postbot uses a deterministic intent classifier to map prompts to supported capabilities, orchestrates tool usage through a controlled execution layer, and codifies outputs as structured in-app actions—such as generating test scripts, visualizing responses, or updating request metadata. Its latest iteration adds a memory-aware agent model that supports multi-turn conversations and multi-action workflows, but with strict boundaries around tool access and state transitions.In this, Westerveld agrees: AI-generated tests are often brittle and opaque. Use them, he advises,“more as a learning tool than an autocomplete tool.”Scaling Through Independence and RestraintOne of Westerveld’s strongest positions concerns test design: automated tests should be independent of each other. This is both a correctness and scalability concern. When teams overuse shared setup code or rely on common state, it breaks test parallelism and increases the chance of cascading failures.In Postman, reusable scripts are managed via the Package Library, which allows teams to store JavaScript test logic in named packages and import them into requests, collections, monitors, and Flows. While this enables consistency and reuse, Westerveld notes that it also introduces new failure points if not applied judiciously.“If something in the shared code breaks—or if a dependency the shared code relies on fails—you can end up with all your tests failing. …So, you have to be careful that a single point of failure doesn’t take everything down.”His solution: only abstract what truly reduces duplication, and mock where necessary.“In cases like that, it’s worth asking: ‘Do we really need this to be a shared script, or can we mock this instead?’ For example, if you're repeatedly calling an authentication endpoint that you're not explicitly testing, maybe you could insert credentials directly instead. That might be a cleaner and faster solution.”He also advocates for test readability. Tests, he says, should act as documentation. Pulling too much logic into shared libraries makes them harder to understand.“A well-written test tells you what the system is supposed to do. It shows real examples of expected behavior, even if it's not a production scenario. You can read it and understand the intent.But when you extract too much into shared libraries, that clarity goes away. Now, instead of reading one script, you’re bouncing between multiple files trying to figure out how things work. That hurts readability and reduces the test's value as living documentation.”Contracts, Specs, and CI IntegrationWith Postman’s new Spec Hub, teams can now author, govern, and publish API specifications across supported formats, helping standardize collaboration around internal and external APIs. As Westerveld puts it:“The whole point of having a specification is that it defines the contract we’re all agreeing to—whether that’s between frontend and backend teams, or with external consumers.”He recommends integrating schema checks as early as possible:“If you're violating that contract, the right response is to stop. … So yes, in that sense, we want development to ‘slow down’ when there’s a spec violation. But in the long run, this actually speeds things up by improving quality. You’re building on a solid foundation.”He advocates running validation as part of the developer CI pipeline—using lightweight checks at merge gates or as part of pull requests.This pattern aligns with what Postman now enables. Spec Hub introduces governance features such as built-in linting to enforce organizational standards by default. For CI integration, Postman’s contract validation tooling can be executed using the Postman CLI or Newman, both of which support running test collections—including those that validate OpenAPI contracts—within continuous integration pipelines. Together, these tools allow teams to maintain a single, trusted specification that anchors both collaboration and automated enforcement across environments.From REST to gRPC and GraphQLProtocol diversity is a reality for modern testers. Westerveld emphasizes that while core principles carry over across styles, testing strategies must adapt to the nuances of each protocol.gRPC, for example, provides low-level access through strongly typed RPC calls defined in .proto files. This increases both the power and the surface area of test logic.“One area where you really see a difference with modern APIs is in how you think about test coverage. The way you structure and approach that will be different from how you’d handle a REST API.That said, there are still similar challenges. For instance, if you’re using gRPC and you’ve got a protobuf or some kind of contract, it’s easier to test—just like with REST, if you have an OpenAPI specification.So, advocating for contracts stays the same regardless of API type. But with GraphQL or gRPC, you need more understanding of the underlying code to test them adequately. With REST, you can usually just look at what the API provides and get a good sense of how to test it.”GraphQL, he notes, introduces different complexities. Because it’s introspective and highly composable:“With GraphQL, there are a lot of possible query combinations… A REST API usually has simple, straightforward docs—‘here are the endpoints, here’s what they do’—maybe a page or two.With GraphQL, the documentation is often dynamically generated and feels more like autocomplete. You almost have to explore the graph to understand what’s available. It’s harder to get comprehensive documentation.”Postman supports both gRPC and GraphQL natively, enabling users to inspect schemas, craft requests, and run tests—all without writing code. But effective testing still depends on schema discipline and clarity. Westerveld points out that with GraphQL, where documentation can feel implicit or opaque, mock servers and contract-first workflows are critical. Postman helps here too, offering design features that can generate mocks and example responses directly from imported specs.Orchestration and Shift-Left StrategiesPostman’s recent support for the Model Context Protocol (MCP) and the launch of its AI Tool Builder mark a shift toward integrating agent workflows into the API lifecycle. Developers can now build and test MCP-compliant servers and requests using Postman’s familiar interface—lowering the barrier to designing autonomous agent interactions atop public or internal APIs.But as Westerveld points out, these advances don’t replace fundamentals. His focus remains on feedback speed, execution reliability, and test independence.“Shift-left and orchestration have been trending for quite a while. As an industry, we’ve been investing in these ideas for years—and we’re still seeing those trends grow. We’re pushing testing closer to where the code is written, which is great. At the same time, we’re seeing more thorough and complete API testing, which is another great development.”He notes a natural tension between shift-left principles and orchestration complexity:“Shift-left means running tests as early as possible, close to the code. The goal is quick feedback. But orchestration often involves more complexity—more setup, broader coverage—and that takes longer to run.So those two trends can pull in different directions: speed versus depth.”The path forward, he argues, lies in test design and execution architecture:“We’re pushing testing left and improving the speed of execution. That’s happening through more efficient test design, better hardware, and—importantly—parallelization.Parallelization is key. If we want fast feedback loops and shift-left execution, we need to run tests in parallel. For that to work, tests must be independent. That ties back to an earlier point I made—test independence isn’t just a nice-to-have. It’s essential for scalable orchestration.”“So I think test orchestration is evolving in a healthy direction. We’re getting both faster and broader at the same time. And that’s making CI/CD pipelines more scalable and effective overall.”💡What This Means for YouPrioritize test independence for parallelization: To scale reliably in CI/CD, design tests that don’t share state. This is a prerequisite for fast, parallel execution and essential for shift-left strategies to succeed at scale.Use AI tools to accelerate, not replace, expertise: Tools like Postbot can speed up repetitive tasks, but they’re most effective in the hands of experienced testers. Treat AI as a companion to structured thinking—not a shortcut for understanding.Be cautious with reusable scripts: Shared logic can improve maintainability, but overuse increases fragility. Mock where appropriate, and abstract only what truly reduces duplication without harming readability.Enforce contracts early through CI: Combine schema-first design with early validation in pull requests. Postman’s Spec Hub and CLI support this model, helping teams catch errors before they spread downstream.Adapt your strategy to protocol complexity: REST, gRPC, and GraphQL each demand different approaches to coverage and validation. Understand the shape of your APIs—and tailor your tooling, mocks, and tests accordingly.If you are looking to implement the principles discussed in our editorial—from contract-first design to CI integration, Westerveld’s book, API Testing and Development with Postman, offers a clear, hands-on walkthrough. Here is an excerpt from the book which explains how contract testing verifies that APIs meet agreed expectations and walks you through setting up and validating these tests in Postman using OpenAPI specs, mock servers, and automated tooling.Expert Insight: Using Contract Testing to Verify an APIAn Excerpt from "Chapter 13: Using Contract Testing to Verify an API" in the book API Testing and Development with Postman, Second Edition by Dave Westerveld (Packt, June 2024)In this chapter, we will learn how to set up and use contract tests in Postman, but before we do that, it’s important to make sure that you understand what they are and why you would use them. So, in this section, we will learn what contract testing is. We will also learn how to use contract testing and then discuss approaches to contract testing – that is, both consumer-driven and provider-driven contracts. To kick all this off, we are going to need to know what contract testing is. So, let’s dive into that.What is contract testing?…Contract testing is a way to make sure that two different software services can communicate with each other. Often, contracts are made between a client and a server. This is the typical place where an API sits, and in many ways, an API is a contract. It specifies the rules that the client must follow in order to use the underlying service. As I’ve mentioned already, contracts help make things run more smoothly. It’s one of the reasons we use APIs. We can expose data in a consistent way that we have contractually bound ourselves to. By doing this, we don’t need to deal with each user of our API on an individual basis and everyone gets a consistent experience.However, one of the issues with an API being a contract is that we must change things. APIs will usually change and evolve over time, but if the API is the contract, you need to make sure that you are holding up your end of the contract. Users of your API will come to rely on it working in the way that you say it will, so you need to check that it continues to do so.When I bought my home, I took the contract to a lawyer to have them check it over and make sure that everything was OK and that there would be no surprises. In a somewhat similar way, an API should have some checks to ensure that there are no surprises. We call these kinds of checks contract testing. An API is a contract, and contract testing is how we ensure that the contract is valid, but how exactly do you do that?Read the Complete ExcerptAPI Testing and Development with Postman, Second Edition by Dave Westerveld (Packt, June 2024) covers everything from workflow and contract testing to security and performance validation, the book combines foundational theory with real-world projects to help developers and testers automate and improve their API workflows.Use code POSTMAN20 for 20% off at packtpub.com.Get the Book🛠️Tool of the Week⚒️Bruno 2.3.0 — A Git-Native API Client for Lightweight, Auditable WorkflowsBruno is an open source, offline-first API client built for developers who want fast, version-controlled request management. The latest release, version 2.3.0 (May 2025), adds capabilities that push it further into production-ready territory:OAuth2 CLI Flows: Streamlined authentication for secure endpoints.Secrets Integration: Native support for AWS Secrets Manager and Azure Key Vault.OpenAPI Sync: Improved support for importing and validating OpenAPI specs.Dev-Centric Design: Files are stored in plain text, organized by folder, and easy to diff in Git.It’s a strong fit for small teams, CI/CD testing, or cases where you want to keep everything under version control—without a heavyweight UI.Westerveld on Bruno“I recently tried Bruno. I liked it—I thought their approach to change management was really well designed. But it didn’t support some of the features I rely on. I experimented with it on a small project, but in the end, I decided I still needed Postman for my main workflows.”“That said, I still open Bruno now and then. It’s useful, simple, and interesting—but we’re not ready to adopt it team-wide.”Westerveld's advice: evaluate new tools with clear use cases in mind. Bruno may not replace your primary API platform overnight, but it’s a valuable addition to your workflow toolkit—especially for Git-native or OpenAPI-first teams.Read more about Bruno📰 Tech Briefs2024 State of the API Report: Postman’s 2024 State of the API report reveals that 74% of teams now follow an API-first approach, linking it to faster API delivery, improved failure recovery, rising monetization, and growing reliance on tools like Postman Workspaces, Spec Hub, and Postbot to navigate collaboration, governance, and security challenges.The MCP Catalog: Postman’s MCP Catalog offers a live, collaborative workspace to discover and test Model Context Protocol (MCP) servers from verified publishers like Stripe, Notion, and Perplexity—enabling developers to prototype LLM-integrated tools quickly using ready-to-run Postman Collections and JSON-RPC 2.0 examples.If an AI agent can’t figure out how your API works, neither can your users: This article argues that improving developer experience (DX) for LLM-powered agents (AX) is now table stakes, advocating for consistent design, clear docs, actionable errors, and golden-path smoke tests as shared foundations for both human and machine usability.15 Best API Testing Tools in 2025: Free and Open-source: Reviews 15 tools covering both established options like Postman, SoapUI, and JMeter, as well as emerging platforms such as Apidog, which offers an all-in-one solution for API design, testing, and mocking—positioning itself as a powerful alternative to fragmented toolchains.The new frontier of API governance: Ensuring alignment, security, and efficiency through decentralization: Decentralized API governance replaces rigid control with shared responsibility, combining design-time standards and runtime enforcement—augmented by AI—to enable secure, scalable, and autonomous API development across distributed teams.That’s all for today. Thank you for reading this issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor in Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}.reverse{display:table;width: 100%;
Read more
  • 0
  • 0

Divya Anne Selvaraj
22 May 2025
15 min read
Save for later

Deep Engineering #1: Patrice Roy on Modern Memory Management in C++

Divya Anne Selvaraj
22 May 2025
15 min read
What RAII, lifetime profiles, and memory-safe languages mean for your codebase#1Patrice Roy on Modern Memory Management in C++What RAII, lifetime profiles, and memory-safe languages mean for your codebaseHi ,Welcome to the very first issue of Deep Engineering.With memory safety behind more than 70% of all known security vulnerabilities (CVEs), the push toward safer programming has become a matter of urgency. Should we rewrite in Rust and Go, or modernize how we write C++?To answer this question, we turned to Patrice Roy—author of C++ Memory Management, long-time member of the ISO C++ Standards Committee, and veteran educator with nearly three decades of experience training systems programmers.You can watch the full interview and read the full transcript here—or keep reading for our distilled take on what modern memory management should look like in practice.Sign Up |AdvertiseRAII and Ownership: Type-Driven Memory Management in Modern C++ with Patrice RoyOne of the most important lessons in modern C++ is clear: "avoid manual memory handling if you can." As Patrice Roy explains, C++’s automatic storage and Resource Acquisition Is Initialization (RAII) mechanisms “work really well” and should be the first tools developers reach for.Modern C++ favors type-driven ownership over raw pointers and new/delete. Smart pointers and standard containers make ownership explicit and self-documenting. For example, std::unique_ptr signals sole ownership in the code itself—eliminating ambiguity about responsibility. As Roy puts it:“You don’t have to ask who will free the memory—it’s that guy. He’s responsible. It’s his job.”Shared ownership is handled by std::shared_ptr, with reference-counted lifetime management. The key idea, Roy stresses, is visibility: ownership should be encoded in the code, not left to comments or convention. This design clarity eliminates entire classes of memory bugs.The same principle applies to Standard Library containers. Types like std::vector manage memory internally—allocation, deallocation, resizing—so developers can focus on program logic, not logistics. RAII and the type system eliminate leaks, double frees, and dangling pointers, and improve exception safety by guaranteeing cleanup during stack unwinding.As C++ veteran Roger Orr quipped:“The most beautiful line of C++ code is the closing brace,”because it signals the automatic cleanup of all resources in scope.The takeaway is simple: default to smart pointers and containers. Use raw memory only when absolutely necessary—and almost never in high-level code.Knowing When to Go Manual (and How to Do It Safely)Manual memory management still has its place in C++, especially in domains where performance, latency, or control over allocation patterns is critical. But as Roy emphasizes, developers should measure before reaching for low-level strategies:“The first thing you should do is measure. Make sure the allocator or memory pool you already have doesn’t already do the job. If you're spending time on something, it has to pay off.”He cites high-frequency trading as an example where even small delays can be unacceptable:“Say you’re working in the finance domain, and you have nanosecond-level constraints because you need to buy and sell very fast—then yes, sometimes you’ll want more control over what’s going on.”In such cases, allocation must be avoided during critical execution windows. One option is to pre-allocate memory buffers on the stack.Modern C++ offers fine-grained control through allocator models. Roy contrasts the traditional type-based model with the polymorphic memory resources (PMR) model introduced in C++17:“Since C++17, we’ve had the PMR (Polymorphic Memory Resource) model... a PMR vector has a member—a pointer to its allocator—instead of having it baked into the type.”While PMR introduces a layer of indirection via virtual function calls, Roy notes that the overhead is usually negligible:“Allocation is a costly operation anyway. So the indirection of a virtual function call isn’t much of a cost—it’s already there in the background.”But when even that cost is too high, the traditional model may be more appropriate:“If you're in a domain where nanoseconds matter, even that indirection might be too much. In that case, the traditional model... may be a better choice, even if you have to write more code.”Roy’s guidance is clear: measure first, optimize only when necessary, and understand the trade-offs each model presents.Trends and Tools for Memory Safety in C++Despite decades of hard-won expertise, C++ developers still face memory safety risks—from dangling references and buffer overruns to subtle use-after-free bugs. The good news: the C++ ecosystem is evolving to tackle these risks more directly, through improved diagnostics, optional safety models, and support from both compilers and hardware.Lifetime Safety, Profiles, and ContractsRoy identifies dangling references as one of the most persistent and subtle sources of undefined behavior in C++:“The main problem we still have is probably what we call dangling references... Lifetime is at the core of object and resource management in C++.”Even modern constructs like string_view can trigger lifetime errors, particularly when developers return references to local variables or temporaries. To address this, the ISO C++ committee has launched several initiatives focused on improving lifetime safety.Roy highlights ongoing work by Herb Sutter and Gašper Ažman (P3656 R1) to introduce lifetime annotations and static analysis to make these bugs less likely:“They’re trying to reduce undefined behavior and make lifetime bugs less likely.”C++23 introduced an optional Lifetime Safety Profile, based on the C++ Core Guidelines, which flags unsafe lifetime usage patterns. This fits into a broader trend toward compiler-enforced profiles—opt-in language subsets proposed by Bjarne Stroustrup that would strengthen guarantees around type safety, bounds checking, and lifetimes.Roy also mentions a proposal of his for C++29, allowing developers to mark ownership transfer explicitly in function signatures—reinforcing ownership visibility and lifetime clarity.Alongside profiles, contracts are expected in C++26. These language features will allow developers to specify preconditions and postconditions directly in code:“Let you mark preconditions and postconditions in your functions... written into the code—not just as prose.”While not limited to memory management, contracts contribute to overall safety by formalizing intent and reducing the likelihood of incorrect usage.Tools for Safer C++Alongside language improvements, developers today have access to a mature suite of static and runtime tools for detecting memory errors.Sanitizers: First-Line DefensesSanitizers have become essential for modern C++ development. Tools like AddressSanitizer (ASan), MemorySanitizer (MSan), and ThreadSanitizer (TSan) instrument the compiled code to detect memory bugs during testing. Roy endorses their use—even if he doesn’t run them constantly:“They’re awesome…I don’t use them much... I think everyone should use them once in a while... They should be part of everyone’s test process.”He encourages developers to experiment and weigh the costs.Compiler Warnings and Static AnalysisRoy also recommends increasing compiler warning levels to catch memory misuse early:“If you're using Visual Studio, try /W4... Maybe not /Wall with GCC, because it's too noisy, or with Clang—but raise the warning levels a bit.”Static analysis tools like the Clang Static Analyzer and Coverity inspect code paths without execution and flag issues such as memory leaks, double frees, and buffer overruns.Hardware Support: MTE and BeyondOn the hardware front, ARM’s Memory Tagging Extension (MTE) offers runtime memory validation through tagged pointers. Available on ARMv9 (e.g. recent Android devices), MTE can catch use-after-free and buffer overflow bugs with minimal runtime impact.Where MTE isn't available, lightweight runtime tools help fill the gap. Google’s GWP-ASan offers probabilistic detection of heap corruption in production, while Facebook’s CheckPointer (in Folly) builds bounds-checking into smart pointer types.Memory-Safe Languages: The New ParadigmNo discussion of memory management today is complete without addressing the elephant in the room: memory-safe languages. Two prominent examples are Rust and Go, which take almost opposite approaches to solve the same problem. “The genius of Go is that it has a garbage collector. The genius of Rust is that it doesn’t need one,” as John Arundel of Bitfield consulting cleverly puts it.Rust: Memory Safety by DesignRust is designed from the ground up to eliminate classes of memory errors common in languages like C and C++. However, Rust’s safety comes with a learning curve, especially for developers accustomed to manually managing lifetimes. Despite this, according to JetBrains' 2025 Developer Ecosystem Survey, Rust has seen significant growth, with over 2.2 million developers using it in the past year and 709,000 considering it their primary language. While Rust's syntax can be initially challenging, many developers find that its multi-paradigm nature and strong safety guarantees make it a robust choice for complex systems development.Researchers have also proposed refinement layers atop C2Rust that automatically reduce the use of unsafe code and improve idiomatic style. One such technique, described in a 2022 IEEE paper, uses TXL-based program transformation rules to refactor translated Rust code—achieving significantly higher safe-code ratios than raw C2Rust output.As one developer quoted by JetBrains put it, Rust is no longer just a safer C++; it's “a general-purpose programming language” powering everything from WebAssembly to command-line tools and backend APIs. And for those coming from legacy C or C++ environments, Rust doesn't demand a full rewrite—interoperability, through FFI and modular integration, allows new Rust code to safely coexist with existing infrastructure.Go: Simplicity Through Runtime SafetyGo adopts a runtime approach to memory safety, deliberately removing the need for developers to manage memory manually. The Go team’s recent cryptography audit—conducted by Trail of Bits and covering core packages like crypto/ecdh, crypto/ecdsa, and crypto/ed25519—underscored this design strength. The auditors found no exploitable memory safety issues in the default packages. Only one low-severity issue was found in the legacy Go+BoringCrypto integration, which required manual memory management via cgo and has since been deprecated. As the Go authors noted, “we naturally rely on the Go language properties to avoid memory management issues.”By sidestepping manual allocation and pointer arithmetic, Go reduces the attack surface for critical bugs like buffer overflows and dangling pointers. While garbage collection does introduce latency trade-offs that make Go less suitable for hard real-time systems, its safety-by-default model and well-tested cryptographic APIs make it ideal for server-side development, cloud infrastructure, and security-sensitive applications where predictable correctness matters more than raw latency.Go’s simplicity also extends to API design. The audit emphasized the team’s emphasis on clarity, safety, and minimalism: prioritizing security over performance, avoiding complex assembly where possible, and keeping code highly readable to support effective review and auditing.The Status of C and C++The rise of memory-safe languages like Rust and Go has put C and C++ under scrutiny—especially in safety-critical domains. The U.S. White House Office of the National Cyber Director now recommends using memory-safe languages for new projects, citing their ability to prevent classes of vulnerabilities inherent in manual memory management.But, replacing C and C++ wholesale is rarely feasible. Most real-world systems will continue to mix languages, gradually modernizing existing C++ code with safer idioms and tooling.Modern C++ is adapting. While the language remains low-level, initiatives like the Core Guidelines, contracts, and lifetime safety proposals are making it easier to write safer code.💡What This Means for YouDefault to RAII and Smart Pointers in C++: Use unique_ptr, shared_ptr, and standard containers to make ownership explicit. Avoid raw new/delete unless absolutely necessary—and never in high-level code.Measure Before You Optimize: Before adopting custom allocators or manual strategies, profile your code. Built-in allocators and containers are often sufficient and safer.Use the Right Allocator Model for the Job: Favor PMR for flexibility. Use the traditional model only if profiling shows the indirection cost matters.Start with Safety-First Defaults: Structure your C++ projects around safe idioms. Apply Core Guidelines, and integrate sanitizers into your CI pipeline to catch memory errors early.Raise Compiler Warnings: Turn on high warning levels (/W4 for MSVC, -Wall -Wextra for Clang/GCC) and treat warnings as errors to surface issues before they reach production.Experiment with Safety Profiles and Contracts: Stay ahead by adopting upcoming C++ features like lifetime annotations and design-by-contract support (C++26 and beyond).Don’t Rely on Comments—Express Ownership in Code: As Roy stresses, ownership must be visible in the code itself. Let types, not prose, determine who frees memory.If you found the insights in our editorial useful, Roy’s book, C++ Memory Management (Packt, March 2025), offers a much deeper exploration, including tips on avoiding common pitfalls and embracing C++17/20/23 features for better memory handling. Here is an excerpt from the book which explains arena-based memory management in C++, using a custom allocator for a game scenario to demonstrate how preallocating and sequentially allocating memory can reduce fragmentation and improve performance.Expert Insight: Arena-based memory managementAn Excerpt from "Chapter 10: Arena-Based Memory Management and Other Optimizations" in the book C++ Memory Management by Patrice Roy (Packt, March 2025)The idea behind arena-based memory management is to allocate a chunk of memory at a known moment in the program and manage it as a “small, personalized heap” based on a strategy that benefits from knowledge of the situation or of the problem domain.There are many variants on this general theme, including the following:In a game, allocate and manage the memory by scene or by level, deallocating it as a single chunk at the end of said scene or level. This can help reduce memory fragmentation in the program.When the conditions in which allocations and deallocations are known to follow a given pattern or have bounded memory requirements, specialize allocation functions to benefit from this information.Express a form of ownership for a group of similar objects in such as way as to destroy them all at a later point in the program instead of doing so one object at a time.The best way to explain how arena-based allocation works is probably to write an example program that uses it and shows both what it does and what benefits this provides. We will write code in such a way as to use the same test code with either the standard library-provided allocation functions or our own specialized implementation, depending on the presence of a macro, and, of course, we will measure the allocation and deallocation code to see whether there is a benefit to our efforts.Read the Complete ExcerptIn this hands-on guide to mastering memory in modern C++, Roy covers techniques to write leaner and safer C++ code, from smart pointers and standard containers to custom allocators and debugging tools. He also dives into examples across real-time systems, games, and more, illustrating how to balance performance with safety.Use code MEMORY20 for 20% off at packtpub.comGet the Book🛠️Tool of the Week⚒️Valgrind 3.25.0 — Classic Memory Debugging, Now with Broader Platform SupportValgrind has long been a staple for memory debugging in C and C++ applications. The latest release, version 3.25.0, brings significant enhancements:Expanded Platform Support: Now includes RISCV64 Linux, ARM/Android, and preliminary support for macOS 10.13.Performance Improvements: Introduces GDB “x” packet support for faster memory reads and zstd-compressed debug sections.Enhanced Tooling: Continues to offer tools like Memcheck for detecting memory leaks and invalid accesses, and Massif for heap profiling.Read the Valgrind User Manual📰 Tech Briefs2025 EuroLLVM - Recipe for Eliminating Entire Classes of Memory Safety Vulnerabilities in C and C++: Apple is addressing memory safety in C-based languages by combining compiler-enforced programming models, developer annotations, and runtime checks to eliminate entire classes of vulnerabilities without requiring a full rewrite in memory-safe languages.Secure by Design Alert: Eliminating Buffer Overflow Vulnerabilities: CISA and the FBI issued a Secure by Design alert urging software manufacturers to eliminate buffer overflow vulnerabilities—designating them as "unforgivable" defects—and recommending memory-safe languages, runtime checks, and secure development practices to prevent exploitation and reduce systemic memory safety risks.Rustls Server-Side Performance: Rustls 0.23.17, an open source TLS library written in Rust that provides a memory-safe alternative to C-based libraries like OpenSSL, has now improved server-side TLS performance by scaling efficiently across cores, reducing handshake latency, and minimizing contention in ticket resumption.Tagged Pointers for Memory Safety: Explains how to implement memory-safe tagged pointers in C++—using runtime-generated tags to detect use-after-free errors—with minimal performance overhead and compatibility with standard allocators.Taking a Look at Database Disk, Memory, and Concurrency Management: Offers a comprehensive, hands-on walkthrough of how modern databases manage disk I/O, memory, transactions, and concurrency—covering buffer pools, write-ahead logging, and locking mechanisms—through a simplified database implementation in Go.That’s all for today. Thank you for reading the first issue of Deep Engineering. We’re just getting started, and your feedback will help shape what comes next.Take a moment to fill out this short survey—as a thank-you, we’ll add one Packt credit to your account, redeemable for any book of your choice.We’ll be back next week with more expert-led content.Stay awesome,Divya Anne SelvarajEditor in Chief, Deep EngineeringTake the Survey, Get a Packt Credit!If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 65
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €14.99/month. Cancel anytime
Divya Anne Selvaraj
15 May 2025
14 min read
Save for later

ProgrammingPro #101: Python Tops Tiobe, AI Code Reviews in VS Code, C# 14 Extensions, and Grafana’s AI Upgrade

Divya Anne Selvaraj
15 May 2025
14 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#101:Python Tops Tiobe, AI Code Reviews in VS Code, C# 14 Extensions, and Grafana’s AI UpgradeLive Webinar | Scale AppSec with Security Champions – May 15Security Champions programs are a proven way to scale AppSec across dev teams. Join Snyk’s live webinar on May 15 @ 11AM ET to learn how to:✓ Define the role of security champions✓ Design a scalable, tailored program✓ Recognize, reward, and grow your champions🎓 BONUS: Earn CPE credits for attending!Save your spot now!Hi ,This is the last issue of ProgrammingPro as you know it.Starting next week, we’re relaunching under a new name: Deep Engineering. Why the change? Because the newsletter has evolved. Our audience—and our focus—now centres on developers and architects tackling complex challenges, designing better systems, and thinking beyond syntax.You’ll still hear from the same team. But the format will sharpen, the insights will go deeper, and the editorial focus will shift from general programming updates to thoughtful analysis, architecture, and advanced engineering practice.Thank you for being part of the journey so far—and see you next week in Deep Engineering.In today’sExpert Insight, we bring you Part 2 of our interview withFabrizio Romano, author of Learn Python Programming, Fourth Edition, where he shares what it takes to lead modern development teams—from fostering psychological safety and developer autonomy to navigating AI-assisted coding and tool debates with clarity and empathy.News Highlights: Python tops the May 2025 Tiobe Index, its highest since Java in 2001; CodeRabbit brings AI code reviews to VS Code and other IDEs; Grafana 12 adds observability-as-code and AI features; C# 14 enables extension members without altering original types.My top 5 picks from today’s learning resources:How to use template strings in Python 3.14🧵Interview: Bjarne Stroustrup on 21stcentury C++, AI risks, and why the language is hard to replace🧠Lock-Free Rust: How to Build a Rollercoaster While It’s on Fire🎢How We Built RisingWave on S3: A Deep Dive into S3-as-primary-storage Architecture🌊Democratizing AI: The Psyche Network Architecture🛰️But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefReplace Secrets with Scalable, Zero-Trust Access for AI Agents and Apps📢 Ditch secrets for good—Aembit’s new Identity Federation Hub replaces static credentials with short-lived, scoped tokens for NHIs across all clouds, no code needed.🔍 See how Snowflake uses Aembit to secure non-human access → Read the blogLearn more and explore the platform →Sign Up |Advertise🗞️News and Analysis🔎Python popularity climbs to highest ever – Tiobe: Python reached an all-time high in the May 2025 Tiobe Index with a 25.35% share, the highest rating since Java in 2001, and now leads C++ by over 15 percentage points.CodeRabbit brings AI-powered code review into Visual Studio Code: CodeRabbit now integrates its AI-powered code review tool into Visual Studio Code, Cursor, and Windsurf, enabling contextual, real-time reviews directly in the IDE.Grafana 12 is now available with new observability as code features, Dynamic Dashboards, and more: New AI features in Grafana Assistant enable natural-language interactions, while Beyla is being donated to OpenTelemetry as an eBPF-based instrumentation tool.C# 14 introduces extension members: The feature allows you to add static and instance methods or properties to existing types using a new optional syntax, without modifying the original code..NET 10 Preview 4 enhances Zip processing, JIT compilation, Blazor WebAssembly:The version also brings performance gains to F#, Android, and WPF development.Scala stabilizes named tuples: Scala 3.7.0 stabilizes named tuples for more readable multi-value returns, fixes Android lambda type issues by boxing return types, and adds support for dependent fields in case classes.LaunchDarkly adds new features to help developers release faster while mitigating risk: Features include dynamic rollout controls, AI governance, real-time experimentation with Multi-Armed Bandits, and team-level analytics.🎓Tutorials and Learning Resources💡Python🎓How to use template strings in Python 3.14: Explains how Python 3.14’s new template strings (t-strings) work, how they differ from f-strings, and how to use them for advanced string processing tasks like custom formatting and HTML sanitization.For more Python resources go to PythonProC# and .NET🎓C# 14 – Exploring extension members: explains C# 14’s new feature, detailing how developers can use the extension block to define grouped extension methods and properties—both instance and static—for existing types.🎓A sub-millisecond GC for .NET?!: Introduces Satori, an experimental garbage collector for .NET that delivers dramatic improvements in pause times—up to 100x faster at the 99th percentile—and reduces heap size.💼How Workleap uses .NET Aspire to transform local development: Explains how Workleap built Leap, a powerful CLI tool based on .NET Aspire, to automate and standardize local development across teams using microservices.C++ and C💡Interview: Bjarne Stroustrup on 21stcentury C++, AI risks, and why the language is hard to replace: Discusses best practices like RAII and concepts, warns against raw pointers and casts, and critiques AI-generated code.🎓Rust Devs Think We’re Hopeless; Let’s Prove Them Wrong (with C++ Memory Leaks)!: Uses humour and hands-on C++ code examples to show how to detect memory leaks without external tools.🎓Let’s write a Real-Time Operating System(RTOS) (Part4: Concurrency and interrupt management): Explains how to manage concurrency and interrupts in an RTOS using atomic operations and critical sections.Java🗞️JDK 25: The new features in Java 25: The impending LTS release introduced nine major features, including finalized scoped values, an updated vector API, and a new key derivation function API.🎓How to Supercharge Your Java Project with Rust — A Practical Guide to JNI Integration with a Complete Example: Explains how to integrate Rust with Java using JNI, covering packaging native libraries in a JAR, unifying logs, and more.JavaScript and TypeScript💡JavaScript's New Superpower: Explicit Resource Management: Introduces JavaScript's new proposal, adding using and await using declarations, Symbol.dispose/Symbol.asyncDispose, DisposableStack/AsyncDisposableStack, and SuppressedError to support safe, deterministic cleanup of resources.🎓Cursor Rules for TypeScript Engineers: Shares a curated set of Cursor rules tailored for TypeScript engineers, covering strict type safety, ESLint enforcement, Zod-based runtime validation, and Bun-first tooling preferences.Go🎓Build your own ResponseWriter: safer HTTP in Go: Demonstrates how to wrap Go’s http.ResponseWriter to enforce safer HTTP handler behavior—like requiring explicit status codes and blocking writes after errors.🎓Using type assertions in Go with concrete types: Explains how to safely call the String() method on a concrete type in Go (like [16]byte) by type asserting through interface{} rather than directly asserting on the concrete type.Rust💡Flattening Rust's Learning Curve: Outlines practical strategies, mindset shifts, and coding habits to help programmers—especially those from other language backgrounds—overcome common pitfalls and learn Rust more effectively.🎓Lock-Free Rust: How to Build a Rollercoaster While It’s on Fire: How to implement a lock-free, fixed-size array in Rust using atomics and a freelist, exploring advanced memory ordering semantics and concurrency safety.Swift💡What's new in Swift 6.2?: Provides an overview of enhancements in language capabilities, performance optimizations, and tooling updates.🎓Universal Links implementation on iOS: Explains how to configure, implement, and test Universal Links on iOS using Xcode and tools like RocketSim.PHP🗞️FrankenPHP Is Now Officially Supported by The PHP Foundation: The high-performance PHP server built with Go and Caddy, is now officially backed by the PHP Foundation to support ongoing development and ecosystem modernization.🎓Stop using preg_* on HTML and start using \Dom\HTMLDocument instead: Explains how PHP 8.4’s new \Dom\HTMLDocument HTML5 parser offers a safer, more robust alternative to preg_* functions for handling HTML.SQL💡A Visual Explanation of SQL Joins: Compares various joins—inner, left outer, full outer, anti-joins, and cross joins—highlighting how each operation behaves when combining two tables by a shared column.Ruby🗞️ZJIT has been merged into Ruby: Unlike YJIT, ZJIT uses a high-level SSA-based IR, compiles entire methods at once, and employs a modular optimiser.🎓Coding agent in 94 lines of Ruby: Walks you through building a functional coding agent using RubyLLM, showing how simple tool integrations—like file reading, editing, and shell execution—enable LLM-powered automation.🌟Advanced Concepts🚀How We Built RisingWave on S3: A Deep Dive into S3-as-primary-storage Architecture: Explains how RisingWave was engineered to use Amazon S3 as its only storage layer—handling internal state, views, and logs.Democratizing AI: The Psyche Network Architecture: Presents Psyche, a decentralized AI training architecture that enables LLM development across globally distributed, underutilized hardware using the Solana blockchain and DisTrO optimization.From Code to Charisma: Emotional Mastery for Tech Leaders: Explores how tech leaders can develop influence by mastering emotional regulation, recognising brain states (rational, emotional, survival), and fostering trust and psychological safety.Designing an architecture using dark matter and dark energy: Uses “dark matter” and “dark energy” as metaphors to explain how to balance cohesion and decoupling when designing monolithic or microservice architectures.🧠Expert Insight: Leading with Empathy 📚Part 2 of our interview with Fabrizio Romano, author of Learn Python Programming, Fourth EditionIn Part 1, Fabrizio Romano shared his journey with Python, talking about the language’s strengths, its limitations, and how it continues to evolve across tools, ecosystems, and developer mindsets. In this second part of our interview, we turn to his experiences as a software development leader—from his transition into management to his team culture, decision-making, and coaching philosophy.Development Manager at Sohonet and long-time Python programmer, Fabrizio brings more than two decades of experience to software engineering leadership. While many know him as the author of Learn Python Programming, Fabrizio's approach to management is rooted in empathy, communication, and personal growth.Q: What led to your transition into a leadership role?Fabrizio: I had been working as a developer for a long time, and after a point, writing code didn’t give me the same satisfaction it once did. I found myself more drawn to helping people grow. Even before I formally became a development manager, I was leading teams and mentoring developers.The experience that really shaped me happened years ago when I was teaching mathematics. A young student struggled with adding fractions. Everyone had given up, assuming she just couldn’t get it. But when I explained it using apples and bananas, she finally understood. That experience taught me that people learn differently, and you have to find the right explanation for each person. I try to lead with that same mindset today.Q: What are the biggest non-technical challenges you’ve encountered in software teams?Fabrizio: The real challenges in software development aren’t technical. At Sohonet, we work on cutting-edge tech for the media industry, and yes, some parts are complex. But most of the work—APIs, platforms, saving data—is not the issue. It’s the people side: miscommunication, mismatched expectations, and lack of shared process.If 11 people on a team all have different understandings of how our process works, then we waste time. I might move a task in a certain way that interrupts someone else’s workflow. These things accumulate. So I work hard to make sure everyone shares the same mental model of how we operate.Q: You've said you prefer values over rigid processes. What does that look like in practice?Fabrizio: I’ve seen teams run with strict rules, lots of constraints, and it can work for some. But not mine. I set up a process that’s flexible and based on values—things like being open, respectful, committed, courageous. When you're unsure what to do, you can use those values like a litmus test.This is similar to how spiritual disciplines work. In Reiki, for example, there are five principles—don’t get angry, don’t worry, be grateful, work hard, be kind. If you ask yourself, “Will this action make me more angry or more grateful?”, it helps guide behaviour. In teams, the same logic applies: let values shape your actions instead of just checking boxes.Q: How do you help your team handle stress and emotional setbacks?Fabrizio: Stress is universal. Everyone’s always trying to deliver faster, and that pressure builds up. One of my jobs is to pay close attention—to what people say, how they act on Slack, their body language in meetings. If I notice something’s off, I check in.I’ve taught half my team meditation techniques and worked with many of them one-on-one. When people are upset or angry, they activate the sympathetic nervous system—the fight-or-flight response. That leads to tunnel vision, shallow breathing, and poor decision-making.Some think that accepting a frustrating situation means passivity. But acceptance isn’t surrender. It’s choosing to remain calm and then respond intelligently. A relaxed mind is a creative mind.Q: How do you see AI tools like GitHub Copilot affecting developer workflows?Fabrizio: They're very helpful. I got everyone on my team Copilot licenses. It’s especially good for repetitive tasks—like hardcoding test cases or writing boilerplate.But I always tell my team: don’t let it replace your thinking. Part of our job is smashing our heads against tough problems. That’s how you develop creativity, problem-solving, and memory. Copilot can assist, but you need to stay sharp. Use it, learn from it—but don’t let it think for you.Q: What’s your view on tooling and tech stacks? Are you opinionated about what teams should use?Fabrizio: No, and I think strong opinions can be dangerous. If you only know one tool, every problem starts to look like a nail. That’s not effective.I want my team to find the best idea, not my idea. We debate things—FastAPI, Django, Flask—and decide what’s right for the context. The diversity of viewpoints leads to better solutions. A developer should choose tools based on what the problem needs, not what they’re comfortable with.Q: What advice would you give to developers considering a leadership path?Fabrizio: Don’t do it just because it’s the next step. Leadership isn’t about being a senior developer—it’s about people. And people aren’t machines. If you’re not passionate about helping others grow, you’ll struggle.You can train as a mentor or coach, but you need that core desire to help. I always say, “People don’t leave companies—they leave managers.” So if you’re thinking of moving into leadership, ask yourself: do I want to support others first, before anything else?To hear the full conversation—including Fabrizio Romano’s reflections on Python’s evolution, its strengths and trade-offs, as well as his insights on leadership, mentorship, team dynamics, and the role of AI in modern development—you can watch the complete video interview here.For a deeper dive, check out Learn Python Programming, Fourth Edition, co-authored by Fabrizio, which offers practical guidance on writing clean, maintainable Python code while building real-world applications. The book mirrors the learner-focused approach Fabrizio champions in this interview—encouraging curiosity, self-sufficiency, and deeper understanding over rote memorisation.Get the eBook for $35.99$31.98Get the Paperback for $39.99🛠️Useful Tools⚒️clickhouse-etl: An open-source ETL tool for real-time streaming from Kafka to ClickHouse, offering deduplication, temporal joins, and a web UI for managing pipelines.quickjs: A pure Go JavaScript engine supporting ECMAScript 2023 features like modules, async generators, and BigInt for embedding JS in Go apps.Cogent Core: An open-source Go framework for building cross-platform 2D and 3D applications that run on desktop, mobile, and web using a single codebase.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 47

Divya Anne Selvaraj
08 May 2025
15 min read
Save for later

ProgrammingPro #100: C# 12 Architecture Insights, Python 3.14 Upgrades, Rust Trait Debugger, and Uber on Ray

Divya Anne Selvaraj
08 May 2025
15 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#100:C# 12 Architecture Insights, Python 3.14 Upgrades, Rust Trait Debugger, and Uber on RayLive Webinar | Scale AppSec with Security Champions – May 15Security Champions programs are a proven way to scale AppSec across dev teams. Join Snyk’s live webinar on May 15 @ 11AM ET✓ Defining the role of security champions✓ Designing a scalable, tailored program✓ Recognizing, rewarding & growing your champions🎓 BONUS: Earn CPE credits for attending!Save your spot now!Hi ,Welcome to a brand new issue of ProgrammingPro.In today’sExpert Insight, we bring you Part 2 of our interview with Francesco AbbruzzeseandGabriel Baptista, authors ofSoftware Architecture with C# 12 and .NET 8, Fourth Edition, where they discuss how software architects can design resilient, adaptable, and secure systems in a cloud-native, data-driven world—while staying aligned with evolving business needs.News Highlights: JetBrains open-sources Mellum, a lightweight LLM for code completion; Amazon Q Developer adds agentic coding to VS Code with real-time collaboration; Python 3.14.0b1 debuts with deferred annotations and template strings; Deno 2.3 brings native compile improvements and local NPM support.My top 5 picks from today’s learning resources:The best new features and fixes in Python 3.14🧪An Interactive Debugger for Rust Trait Errors🕵️‍♂️How to gracefully migrate your JavaScript programs to TypeScript🔁Domain-Driven RAG: Building Accurate Enterprise Knowledge Systems Through Distributed Ownership🧠Uber’s Journey to Ray on Kubernetes🚖But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSign Up |Advertise🗞️News and Analysis🔎Python 3.14.0b1: The first beta of the upcoming 3.14 release, introduces deferred annotation evaluation (PEP 649), template strings (PEP 750), Zstandard compression support (PEP 784), and other major improvements.JetBrains open sources its code completion LLM, Mellum: Mellum is on Hugging Face and is positioned as a lightweight, task-specific “focal model” optimized for code completion across multiple languages.Amazon Q Developer gets new agentic coding experience in Visual Studio Code: Amazon Q Developer now enables real-time, interactive collaboration for tasks like writing code, generating documentation, testing, and reviewing changes.Deno 2.3 adds compile improvements, support for local NPM packages: The version enhances deno compile with support for native libraries and Node plug-ins, speeds up dependency installs, and upgrades to TypeScript 5.8 and V8 13.5.JDK 25: The new features in Java 25: The LTS release due in September, introduces a fifth preview of structured concurrency, finalized flexible constructor bodies, module import declarations, compact source files, stable values, and more.Node.js 24 drops MSVC support: The version has dropped support for Microsoft’s MSVC compiler in favor of ClangCL on Windows, updated the V8 engine to 13.6 with new JavaScript features, and improved async context handling.🎓Tutorials and Learning Resources💡Python🗞️🎥ty: Astral's New Type Checker (Formerly Red-Knot) - Talk Python to Me Ep. 506: Developed as a complement to Astral’s popular tools Ruff and UV, ty aims to offer faster, scalable, and more beginner-friendly type checking. It focuses on performance, better editor integration, and smoother adoption in large codebases. TY will be released as a standalone tool, not a drop-in replacement for MyPy or Pyright.🎓Kate and Python language server: Explains how to configure the python-lsp-server in the Kate editor to work smoothly with Python virtual environments by using a custom bash script (pylsp_in_env) and enabling the ruff plugin for linting.🎓"AI Coffee" Grand Opening This Monday • A Story About Parameters and Arguments in Python Functions: Uses a coffee shop analogy to explain Python function parameters, covering positional and keyword arguments, *args and **kwargs , default values, and more.💡The best new features and fixes in Python 3.14: Walks through each new feature and its developer impact, especially for improving debugging, code clarity, performance, and extensibility.C# and .NET🎓How to use the IServiceProvider interface in ASP.NET Core: Explains how to use the interface to dynamically resolve dependencies at runtime, create scopes for background tasks, and enhance application modularity and more.💡Best Practices for Managing Shared Libraries in .NET Applications at Scale: Covers Central Package Management, Git submodules, and umbrella packages, discussing their trade-offs.💡Why we built our startup in C#: Discusses why Tracebit chose C# to build its B2B SaaS security product, highlighting the language's productivity, modern cross-platform ecosystem, strong tooling, and rich libraries as key advantages.C++ and C💡Hazard Pointers in C++26: Introduces hazard pointers in C++26 as a safe memory reclamation mechanism that enables garbage collection, prevents the ABA problem, and improves concurrency correctness and performance.🎓Using C++ type aliasing to avoid the One Definition Rule (ODR) problem with conditional compilation, part 1: Explains how to use type aliasing with templates and conditional compilation to enable different builds.📄Large Language Models for C Test Case Generation: A Comparative Analysis: Evaluates how LLMs can automate C unit test generation by comparing different models using Pass@1 and Line Coverage metrics.Java💡Fixrleak: Fixing Java Resource Leaks with GenAI: Introduces a tool that automates detection and repair of resource leaks in Java by combining AST analysis and generative AI to produce safe, idiomatic fixes.🗞️🎥Java for AI: Talks about how Java is evolving to support AI/ML workloads through key features like the Foreign Function & Memory API (FFM), Vector API, value classes from Project Valhalla, and code reflection from Project Babylon.JavaScript and TypeScript🎓How to gracefully migrate your JavaScript programs to TypeScript: Explains how to incrementally migrate JavaScript codebases to TypeScript by setting up the TypeScript compiler, using type annotations, and more.💡8 ways to do more with modern JavaScript: Outlines ways to level up in modern JavaScript, covering best practices like using const and let , functional operators, async/await, modern syntax, closures, and graceful error handling.Go🗞️☠️Linux wiper malware hidden in malicious Go modules on GitHub: A destructive supply-chain attack targeted Linux servers via malicious Go modules on GitHub by delivering a disk-wiping payload disguised as developer tools.🎓Graceful Shutdown in Go: Practical Patterns: Covers handling termination signals, timeout management, stopping new requests, completing in-flight requests, and releasing resources safely.Rust💡Understanding Memory Management, Part 5: Fighting with Rust: Explores the challenges of adapting to Rust's strict memory safety model, emphasizing how its ownership and borrowing rules lead to more robust code.🗞️An Interactive Debugger for Rust Trait Errors: Introduces Argus, an interactive GUI-based debugger for Rust trait errors that helps developers explore the compiler’s trait inference tree and understand complex type errors.Swift🎓Testing push notifications on the iOS simulator: Explains how to test push notifications on the iOS Simulator using Xcode tools, JSON or APNS payloads, and third-party tools like RocketSim.🎓SwiftUI View Model Ownership: Explores how to correctly instantiate and manage SwiftUI view model ownership using @State , highlighting common pitfalls with initializers and value updates.PHP🎓PHP Hypertext Processor: Introduces PHP as a server-side scripting language for generating dynamic web content, explaining its origins, core syntax, and evolution to help beginners build interactive websites.SQL💡Which LLM writes the best analytical SQL?: Evaluates the SQL-writing capabilities of 19 LLMs and one human by having them generate SQL queries for 50 analytical questions on a 200-million-row GitHub dataset.Ruby💼Part 1: How We Fell Out of Love with Next.js and Back in Love with Ruby on Rails & Inertia.js: Covers how Hardcover transitioned to Ruby on Rails with Inertia.js to address performance issues, reduce hosting costs, and simplify development.🌟Advanced Concepts🚀Legacy Modernization: Architecting Real-Time Systems around a Mainframe: Describes how National Grid incrementally modernized a legacy mainframe-based system by using Change Data Capture, Domain-Driven Design, Event-Driven Architecture, and Team Topologies.Domain-Driven RAG: Building Accurate Enterprise Knowledge Systems Through Distributed Ownership: Outlines how a banking tech company used DDD to build modular, expert-owned RAG systems that deliver accurate, contextual responses.Uber’s Journey to Ray on Kubernetes: Explains how Uber transitioned its machine learning workloads to Ray on Kubernetes to improve scalability, automate resource management, and optimize hardware utilization.CriticalArchitecture/Software Theory: Explores how postmodern architectural criticism can inspire a more self-aware and reflective approach to software development.🧠Expert Insight: Designing for Change and Scale in Modern Architecture📚Part 2 of our interview with Francesco Abbruzzese and Gabriel Baptista, authors of Software Architecture with C# 12 and .NET 8, Fourth EditionIn Part 1, Francesco Abbruzzese and Gabriel Baptista discussed the evolving role of software architects in the age of AI. In this second excerpt from our conversation, we shift focus to the architectural decisions shaping today’s enterprise applications—from cloud-native resilience to security by design, edge computing, and long-term maintainability.Q: Cloud-native computing is reshaping enterprise systems. What architectural practices should teams adopt to ensure resilience and adaptability?Gabriel:In the near future, I believe most applications will be cloud-native. Some systems might run on the edge, but even those will likely rely on the cloud in some way. That means everyone working in software today needs to think cloud-first.When it comes to resilience and adaptability, we’ve dedicated several chapters in the book to those topics. The development cycle is faster than ever, and new tools and practices emerge constantly. So we need architectures that can keep up.It starts with writing clean, observable code—code that’s tied to retries, performance metrics, and real-time feedback. If you’re building enterprise applications, there’s no room for downtime. The architecture needs to be designed from day one with 24/7 operation in mind.Francesco:In my view, cloud-native really means distributed computing, with added adaptability. The core idea is that your system must remain reliable even when distributed—and that means getting communication right.You need to adopt the right architectural patterns. Use orchestrators like Kubernetes, implement automatic scaling, collect metrics, and adapt your system based on those metrics. Modern microservices follow the theory of reliable communication. Messages can be delayed, but not lost. That’s essential.Microservices often work like an assembly line—processing and transferring data step by step. Any failure in that chain can break the system. So we go into depth in the book on the foundations of distributed computing and microservice design, because they’re central to resilient cloud-native architecture.Q: Considering how sophisticated modern threats have become, how can teams integrate security by design principles throughout the architecture?Francesco:Security by design is not a separate topic—it’s a way of thinking. It has to be part of how you code and architect systems from the very beginning.First and foremost, education is key. Teams need to understand the correct way to do things, rather than trying to invent their own solutions. You also need to choose your team carefully—skills and mindset matter.Code reviews, especially by security experts, are very effective. They help catch vulnerabilities and ensure best practices are actually followed.Another important point is to rely on trusted, well-tested libraries and stacks. Don’t try to build your own authentication system—use the tools that already exist and have been proven to work.Gabriel:I agree completely, and I’ll add a few examples. Architects should be familiar with OWASP guidelines—especially the top 10 vulnerabilities in APIs. These are things every architect should study and apply.In terms of implementation, think DevSecOps. Add static analysis tools to your CI/CD pipeline. They’ll flag security issues early and help the team build more secure code.And as Francesco mentioned, library choice is critical. One of the biggest risks in software security today is using outdated or vulnerable third-party components. So staying up to date isn’t just a maintenance task—it’s a security measure.Q: What strategies should architects use to ensure long-term architectural integrity?Gabriel:Architecture isn’t something you set and forget—it evolves. But if you build with the right principles in place—resilience, observability, security—you’ll know when and how to adapt it.My advice is to start simple. Not every project needs the most complex architecture from day one. Monitor your system continuously and evolve when the data tells you it’s time. Cloud platforms make this much easier than it used to be.A good pipeline also makes a difference. From analysis and code review to testing and release, your workflow should help you understand whether your application is doing what it’s supposed to—and whether it needs to change.Francesco:Yes, and I’d add that using Domain-Driven Design and microservices is key. These patterns make it easier to change just a part of the system without affecting everything else.If your architecture is modular, each microservice can use different internal designs. That flexibility is powerful. It lets you evolve small pieces of your application instead of rewriting it entirely every time something changes.Good monitoring helps, too. If you know how your system behaves in production, you’ll know when it’s time to adjust.Q: How do you see the integration of edge computing and increased data-centricity shaping the future of enterprise architecture?Francesco:The future is definitely in collecting and using peripheral data to make better decisions. That means your application has to work with data coming from different sources, at different levels of detail.But there’s a tension here. On one hand, each microservice should manage its own data—sometimes because of geography, sometimes due to business constraints. On the other hand, we need consolidated data for decision-making.That’s where worker microservices come in. They can aggregate data from different sources and transform it into a useful format for analysis.The key is to structure the data in a way that makes it meaningful and usable. Consolidation is going to be central to future systems—and AI and statistical tools will help us get there.Gabriel:Edge computing is going to affect every industry. Decisions will be made closer to where data is generated, and that data will need to flow back to central systems for deeper analysis.This reinforces the need for distributed systems. You don’t want to send all raw data from the edge—you want to send decisions or key insights. That means architectures need to be designed from the ground up for distribution and selective data flow.Patterns like microservices and DDD are going to be more important than ever.Q: How can architects ensure their designs contribute to real business outcomes—especially in high-impact industries?Francesco:It starts with changing how we think about requirements. Don’t just gather what users ask for—ask what adds value to the business. Every requirement should be evaluated through that lens.DevOps is key. It gives you feedback quickly, so you can measure whether your architecture is delivering the value it’s supposed to. Combine that with modular architecture—like DDD and microservices—and you’ll be able to make precise changes that maximise business value.The goal is to avoid having to rewrite large parts of your system. Instead, make small, well-targeted changes that align with business needs.Gabriel:That’s exactly it. DevOps creates a tight feedback loop. When you have a solid architecture and a good DevOps cycle, you can move faster, deliver better outcomes, and adapt to what the business really needs.With that in place, it becomes much easier to maintain alignment between the technical and the strategic—and that’s what turns a system into a success.To hear the full conversation—including insights on developer mentorship, working across distributed teams, and lessons from real-world enterprise projects—watch the complete video interview in our playlist here.For a deeper dive, check out Francesco and Gabriel’s book, Software Architecture with C# 12 and .NET 8, which offers practical guidance on building resilient, scalable, and secure .NET applications.As a bonus, you can now get 30% off the eBook and 20% off the print edition—no code required. Offer valid until the end of this month.Get the eBook for $39.99$27.98Get the Paperback for $49.99$39.98🛠️Useful Tools⚒️klavis: An open-source platform that provides scalable, production-ready MCP server and client integrations for AI applications across tools like Slack, Discord, GitHub, and more.outpost: An open-source, self-hosted infrastructure by Hookdeck that enables scalable outbound webhooks and event destinations with support for multiple protocols like Webhooks, AWS, GCP, and Kafka.aci: An open-source infrastructure platform that enables AI agents to securely access and use 600+ tools via unified function calls or MCP servers with built-in authentication and granular permissions.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 57

Divya Anne Selvaraj
01 May 2025
11 min read
Save for later

ProgrammingPro #99: BDD with Go’s gobdd, Docker & AWS AI Tooling, GCC 15.1 Rust/C++ Upgrades, and Netflix’s 2025 Java Stack

Divya Anne Selvaraj
01 May 2025
11 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#99:BDD with Go’s gobdd, Docker & AWS AI Tooling, GCC 15.1 Rust/C++ Upgrades, and Netflix’s 2025 Java StackSponsored:Build the Future of Apps on HubSpot:New developer products introduce deeper extensibility, flexible UI options, modern development tools, and more—shaping a more powerful, customisable platform experience.Learn more.Hi ,Welcome to a brand new issue of ProgrammingPro.In today’sExpert Insight, we bring you an excerpt from the recently published book, Domain-Driven Design with Golang, which explains how Behaviour-Driven Development (BDD) extends Test-Driven Development (TDD) by using natural language tests to improve collaboration between engineers and domain experts, illustrated with Go examples using the gobdd framework.News Highlights: AI tooling advances as Docker, Solo.io, and AWS launch new agent frameworks and benchmarks; GCC 15.1 delivers major Rust, C, C++, and Cobol upgrades; GitHub previews its AI-powered MCP Server; and InfoQ’s 2025 report highlights agentic AI, small LMs, and privacy engineering trends.My top 5 picks from today’s learning resources:14 Advanced Python Features🧩How Netflix Uses Java - 2025 Edition🎬This 150-Line Go Script Is Actually a Full-On Load Balancer⚖️Swift 6.2: A first look at how it’s changing Concurrency🚦Scaling API Independence: Akehurst on Mocking, Contract Testing, and Observability🔗But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefWEBINARSecuring Mobile Payments:Protecting Digital Wallets and SoftPOS from AttacksHosted byGuardsquareFeaturing:Sergio Castell-Security ResearcherDario Dallefrate-Product Marketing ManagerDate/time:Tuesday May 13, 20254 PM CET (10 AM EDT)Register NowSign Up |Advertise🗞️News and Analysis🔎AI updates from the past week: Docker announced an upcoming MCP tool catalog, Solo.io released Agent Gateway and Mesh for agent governance, and AWS launched SWE-PolyBench to benchmark AI coding agents.GCC 15 compilers arrive with Rust, C, C++, and Cobol enhancements: GCC 15.1 introduces major upgrades including full C23 support, initial C++26 features, improved vectorization, and faster compilation for large files.GitHub Announces Public Preview of GitHub MCP Server: The server enables AI-powered, natural language interactions with GitHub APIs through a standardised client-server protocol developed with Anthropic.InfoQ Software Architecture and Design Trends Report - 2025: Key architecture trends include agentic AI, small language models, RAG, AI-assisted development, and privacy engineering.Microsoft previews SignalR client for iOS: The client enables iOS developers to build real-time features like chat and live updates into SwiftUI and UIKit apps using ASP.NET SignalR and Azure SignalR services.Java News Roundup: Covers the release of Gradle 8.14, the debut of JBang’s Jash shell scripting library, Hibernate ORM 7.0 RC1, updates to Open Liberty and Spring projects, and the end of open-source support for Spring Cloud Data Flow.The hidden cost of dev stack diversity within an enterprise: ‘Engineering chaos’: A survey by Earthly has revealed that dev stack diversity, enabled by containerization, makes it hard to enforce security and quality policies across teams despite other gains.🎓Tutorials and Learning Resources💡Python💡14 Advanced Python Features:Presents 14 underused yet powerful Python features, including typing overloads, structural pattern matching, generics, protocols, and metaclasses, with code examples and references.For more Python resources, go to PythonProC# and .NET💡Why C#?: Explains why C# remains a powerful and relevant language, highlighting its modern features, cross-platform .NET ecosystem, strong tooling, and active community as key reasons for its continued appeal to developers.🎓Using ImmutableSortedSet in C# for memory sharing: Explains how the data structure is ideal for concurrent scenarios where data is frequently read, occasionally mutated, and needs safe, low-cost versioning without locking.🎓Effortless integration test isolation with .NET, XUnit and database transactions: Explains how to set up realistic, isolated integration tests in .NET using XUnit, EF Core, and PostgreSQL.C++ and C💡New C++ features in GCC 15: The version introduces pack indexing, variadic friends, =delete("reason") , and structured bindings in conditions—alongside improvements to constexpr support, modules, and more.📄Link-Time Optimization of Dynamic Casts in C++ Programs: Proposes a link-time optimisation (LTO) technique to improve performance and reduce code size for dynamic casts in C++.🎓How to program a text adventure in C: Explains how to build a text adventure game from scratch, progressing incrementally through 25 chapters covering key mechanics like locations, inventory, parsing, and even multiplayer.Java💡How ZGC allocates memory for the Java heap: Covers virtual-physical memory separation, NUMA-aware multi-partition handling, allocation paths, and latency considerations.💼🎥How Netflix Uses Java - 2025 Edition: Presents how Netflix modernised its Java infrastructure, what tools and frameworks power its services, and why it standardised on GraphQL, Spring Boot, and newer JVM features.JavaScript and TypeScript💡Making a small JavaScript blog static site generator (SSG) even smaller using the general async-tree library: Examines how the async-tree library simplifies and reduces the codebase of a minimalist SSG.🎓Go to Definition in Typescript Monorepos: Explains how to enable reliable “Go to Definition” functionality by configuring package.json exports with a custom condition and updating tsconfig.json and Vite settings accordingly.Go🎓This 150-Line Go Script Is Actually a Full-On Load Balancer: Demonstrates how to build a fully functional HTTP load balancer using round-robin request routing, health checks, and reverse proxying.🎓Organize your Go middleware without dependencies: Explains how to organize and manage middleware in Go web applications without third-party dependencies, using custom middleware chains and a simple router type.Rust🎓A Visual Journey Through Async Rust: Uses a graphical approach to explain how async execution, concurrency, and parallelism work in Rust by plotting sine wave computations across futures and tasks.💡Introducing Rust in security research: Describes how a team designed and delivered a Rust workshop for Radboud University’s iHub, focusing on Rust fundamentals and C interoperability.Swift🗞️Swift 6.2: A first look at how it’s changing Concurrency: Previews how the version aims to improve concurrency’s approachability, focusing on clearer migration paths, reduced compiler warnings, and easier adoption of async code.🎓SwiftUI ForEach Explained with Code Examples: Explains how to use SwiftUI’s ForEach to create dynamic, repeatable views, covering basics, the Identifiable protocol, and index-based iteration.PHP🎓Fast string compare function for PHP: Presents a fast, approximate PHP string comparison function that measures text differences by length, character counts, and word frequencies, offering 80–90% better performance.SQL💡Anatomy Of A SQL Engine: Breaks down how Dolt’s SQL engine processes queries, covering each phase from parsing (building an AST) to binding (resolving identifiers), plan simplification, join planning and costing.Ruby💼Past, Present, and Future of Sorbet Type Syntax: Reviews the evolution of Sorbet’s type syntax, explaining its origins at Stripe, trade-offs between various type system designs, and key constraints that shaped its current DSL approach.🌟Advanced Concepts🚀Scaling API Independence: Akehurst on Mocking, Contract Testing, and Observability: Discusses how combining mocking, contract testing, and observability enables API independence in large microservices systems.Closing the loop on agents with test-driven development (TDD): Explains how developers are applying TDD to AI agents by evaluating behaviours and refining workflows across experimentation, evaluation, deployment, and monitoring stages.Quality begins with planning: Building software with the right mindset: Argues that software quality must be a shared responsibility across the team and embedded from the planning phase, with developers playing a proactive role.🧠Expert Insight📚Here’s an excerpt from “Chapter 8: TDD, BDD, and DDD" in the book, Domain-Driven Design with Golang, by Matthew Boyle, published in December 2022.BDDBDD is an extension of TDD that aims to enable deeper collaboration between engineers, domain experts, and quality assurance engineers (if your company employs them). A diagram of how thisworks with TDD is shown (in Figure 8.6).The goal of BDD is to provide a higher level of abstraction from code through adomain-specific language (often referred to as a DSL) that can become executable tests. Two popular frameworks for writing BDD tests is the use of Gherkin (https://cucumber.io/docs/gherkin/reference/) and Cucumber (https://cucumber.io). Gherkin defines a set of keywords and a language specification. Cucumber reads this text and validates that the software works as expected. For example, the following is a valid Cucumber test:Feature: checkout IntegrationScenario: Successfully Capture a paymentGiven I am a customerWhen I purchase a cookie for 50 cents.Then my card should be charged 50 cents and an e-mail receiptis sent.Some teams work with their domain experts to ensure their acceptance criteria in their ticketing system are in this format. If it is, this criterion can simply become the test. This aligns nicely with DDD.Now that we have a high-level understanding of BDD, let’s take a look at implementing a test in Go. We are going to use the go-bdd framework, which you can find at https://github.com/go-bdd/gobdd.Firstly, let’s install go-bdd in our project:go get github.com/go-bdd/gobddNow, create a features folder:Inside the features folder, let’s add a file called add.feature with this inside it:Feature: Adding numbersScenario: add two numbers togetherWhen I add 3 and 6Then the result should equal 9Next, let’s add an add_test.go file and the following:package chapter8import ("testing""github.com/go-bdd/gobdd")func add(t gobdd.StepTest, ctx gobdd.Context, first, secondint) {res := first + secondctx.Set("result", res)}func check(t gobdd.StepTest, ctx gobdd.Context, sum int) {received, err := ctx.Geif err != nil {t.Fatal(err)return}if sum != received {t.Fatalf("expected %d but got %d", sum, received)}}func TestScenarios(t *testing.T) {suite := gobdd.NewSuite(t)suite.AddStep(`I add (\d+) and (\d+)`, add)suite.AddStep(`the result should equal (\d+)`, check)suite.Run()}In the preceding code, we add a bdd step function called add. This function name is important; the framework knows that when I add 3 and 6 gets mapped to this function. If you change the name of this function to “sum”, you’d need to update the feature file to say, when I sum 3 and 6 together. We then perform our logic and store it in the context so that we can recall it later.We then define a check function that is our actual test; it validates our assertions. Finally, we set up a test suite to run our code.If you run the preceding test, it should pass.This might be your first time seeing a BDD-style test, but I bet it’s not your first time seeing a unit test. Why is that?As you can see, although BDD tests are closer to natural language, it pushes a lot of the complexity down into the tests. The preceding example we used is trivial, but if you want to express complex scenarios (such as the cookie example we used previously) there is a lot of scaffolding the developer needs to implement to make the tests work correctly. This can be worthwhile if you have lots of access to your domain experts and you are truly going to work side by side. However, if they are absent or not invested in the process, unit tests are much faster and more engaging for engineering teams to work with. Much like DDD, BDD is a multidisciplinary team investment, and it is worth ensuring you have buy-in from all stakeholders before investing too much time in it.Domain-Driven Design with Golang was published in December 2022. Packt library subscribers can continue reading the entire book for free or you can buy the book here!Get the eBook for $35.99$31.99🛠️Useful Tools⚒️Magnitude: An AI-powered, open source end-to-end testing framework that uses visual agents and natural language to create and run adaptive tests for web apps.agenticSeek: A fully local, open-source AI assistant that autonomously browses the web, writes code, and plans tasks with complete on-device privacy.BitNet: A 1-bit LLM framework from Microsoft designed for ultra-efficient, fast inference on CPUs, enabling low-bit LLMs like BitNet b1.58 to run locally.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}.reverse{display:table;width: 100%;
Read more
  • 0
  • 0
  • 171

Divya Anne Selvaraj
25 Apr 2025
2 min read
Save for later

Welcome to ProgrammingPro — Here’s a little something to get you started

Divya Anne Selvaraj
25 Apr 2025
2 min read
Access expert commentary, interviews, and practical resources across programming and software architWelcome to ProgrammingPro!Thank you for subscribing to ProgrammingPro, a resource for discerning software professionals committed to advancing their expertise. Each week, we present curated insights spanning programming languages, software architecture, and emerging technologies. Our content includes expert commentary, interviews with industry leaders, and practical tutorials to support continuous learning.In addition to the newsletter, forthcoming articles and video interviews on our blog and YouTube channel will provide further opportunities for in-depth engagement with the Packt author base complementing our extensive collection of books.As a new subscriber, you are invited to explore our catalogue of technical publications with 15% off your first eBook. Please use the code GET15 at checkout.We recommend the following titles to begin:Start ExploringThank you for joining us. We look forward to supporting your learning journey across every stage of your career.*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 154
Divya Anne Selvaraj
24 Apr 2025
17 min read
Save for later

ProgrammingPro #98: System Design Lessons from Google & Netflix, AI CLI Tools, Java 25 LTS, and Faster Rust Builds

Divya Anne Selvaraj
24 Apr 2025
17 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#98:System Design Lessons from Google & Netflix, AI CLI Tools, Java 25 LTS, and Faster Rust BuildsBuild the Future of Apps on HubSpotNew developer products introduce deeper extensibility, flexible UI options, modern development tools, and more—shaping a more powerful, customisable platform experience.HubSpot’s AI-powered ecosystem is projected to become a $10.2 billion opportunity by 2028. To help developers tap into that growth, we're opening up the platform—introducing expanded APIs, customisable app UIs, and tools built to support a unified data strategy.Learn moreHi ,Welcome to a brand new issue of ProgrammingPro.In today’sExpert Insight, we bring you an excerpt fromour interview with Dhirendra Sinha (Google) and Tejas Chopra (Netflix), engineering leaders and authors of System Design Guide for Software Professionals, where they share lessons on building scalable, resilient systems, best practices from big tech, and career advice for engineers looking to grow in system design.News Highlights: Amazon Q and Claude Code bring AI to the CLI; Angular, React, Vue, and Svelte compared; Java 25 LTS finalises key features and drops 32-bit x86; WebAssembly adds async, multi-threading, and garbage collection.My top 5 picks from today’s learning resources:Choosing The Right Python Task Queue🧵Architecting AI Agents with TypeScript🛠️Cutting Down Rust Compile Times From 30 to 2 Minutes With One Thousand Crates⚡A Full Guide to Planning Your Authorization Model and Architecture🔐Renovate to Innovate: Fundamentals of Transforming Legacy Architecture🏗️But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSponsored:[Rubrik Guided Lab] AWS Cloud Native Protection: Cloud breaches are real and recovery is your responsibility. Camp Rubrik’s AWS track walks you through protecting EC2, RDS, and EBS workloads in a live lab.Save Your SpotSign Up|Advertise🗞️News and Analysis🔎Amazon Q and Claude Code Let AI Control the Developer CLI: Amazon Q Developer CLI gains autonomous AWS command execution, while Anthropic debuts Claude Code for project-wide code editing and debugging from the terminal.Comparing Angular, React, Vue, and Svelte: What you need to know: Evaluates the framworks' popularity, community involvement, learning curve, syntax, scalability, and performance to help you choose the right one for your needs.JDK 25: The new features in Java 25: The LTS release due September 2025, finalises module import declarations, compact source files, instance main methods, stable values, and removes the 32-bit x86 port.4 big changes WebAssembly developers need to know about: Async support, multi-threaded execution, shared memory, and garbage collection are expanding WebAssembly’s capabilities, but full adoption is conditional.Microsoft reveals upcoming changes to Microsoft 365 Developer Program: Updates include a streamlined tenant provisioning flow, optional Copilot licenses, improved tenant owner identification, and the ability to convert developer tenants into paid subscriptions.Gleam 1.10 improves compiler, JavaScript codegen: The version offers improved type tracking, project-wide refactoring tools, exhaustive string analysis, and faster JavaScript code generation, alongside security upgrades..NET Aspire 9.2 Released with Expanded Deployment Options and Dashboard Improvements: The version also introduces a resource graph for visualising application structure and enhances deep linking.🎓Tutorials and Learning Resources💡Python🎓Demystifying Decorators • They Don't Need to be Cryptic: Introduces closures and then progressively develops a general-purpose decorator that logs function arguments.💡Choosing The Right Python Task Queue: Compares Python task queues, focusing on Celery and RQ, outlining their trade-offs in complexity, performance, reliability, and scalability.🗞️Sneak peek: A new ASN.1 API for Python: This API for Python’s PyCA Cryptography, leverages a Rust-based parser to enhance performance, reduce parser inconsistencies, and modernise the interface with dataclass-style definitions.🗞️15,000 lines of verified cryptography now in Python: The verified cryptographic code from HACL* covers all default hash and HMAC algorithms and ensures higher security, better memory safety, and streaming APIs.C# and .NET🗞️Introducing the AI Dev Gallery: Your Gateway to Local AI Development with .NET: The Windows application offers interactive samples (RAG, chat, object detection), easy model downloads, and exportable C# source code for rapid prototyping and learning—all without cloud dependencies.🗞️Introducing .NET Support in Socket: The update provides supply chain security and SBOM accuracy for NuGet and MSBuild-based C# projects and detects package-level threats, risky updates, and more.🗞️Introducing Incrementalist, an Incremental .NET Build Tool for Large Solutions: Petabridge, the creators of Akka.NET have introduced an open source tool that reduces build times by analysing Git changes and project dependencies.C++ and C📄Exploiting Undefined Behavior in C/C++ Programs for Optimization: A Study on the Performance Impact by Lucian Popescu and Nuno P. Lopes: Finds UB exploitation delivers significant performance gains (e.g., +8.4% on SPEC 2017’s mcf), especially for signed overflows and pointer misalignments.💡Streamlined iteration: exploring keys and values in C++20: Compares different methods of iterating over key-value data structures in C++, focusing on C++20’s ranges (views::keys, views::values ) for cleaner, functional-style code.🎓Detecting if an expression is constant in C: Explores six methods to implement a C macro that checks whether an expression is a compile-time constant, using techniques like __builtin_constant_p, static_assert .Java🎥The Future of Write Once, Run Anywhere: From Java to WebAssembly by Patrick Ziegler & Fabio Niephaus: Demonstrates a new WebAssembly backend that compiles Java bytecode into WebAssembly, enabling Java applications, including tools like javac, to run entirely in the browser.🎓Guiding an LLM for Robust Java ByteBuffer Code: Demonstrates how expert developer guidance transforms LLM-generated Java ByteBuffer code into a robust, maintainable component by eliminating side effects.🎓Choosing Your Type: When to Use Enum vs. Object in Java Fields: Explains how to choose between the two using examples to demonstrate design considerations, serialization pitfalls, database mappings, and performance trade-offs.JavaScript and TypeScript🎓This minimalist static site generator pattern is only for JavaScript developers who want something small, fast, flexible, and comprehensible: Explains how to build a minimalist static site generator from scratch using pure JavaScript and no dependencies.🎓Modifying Websites with LLM-Generated Javascript Bookmarks: Demonstrates how to use LLMs to generate JavaScript bookmarklets that modify websites on the fly, using three examples.🎓Architecting AI Agents with TypeScript: Presents a modular architecture for building AI agents that integrate LLMs with external tools, memory systems, and functional programming patterns, with complete code examples.Go🎓Cheating the Reaper in Go: Demonstrates how to build an efficient, garbage-collected arena allocator in Go, leveraging the language's memory model and garbage collector internals to manually manage memory safely.💡Layered Design in Go: A descriptive guide focusing on structuring packages to avoid circular dependencies, outlining how Go’s import rules naturally create a layered system, and offering practical strategies for handling dependencies.Rust💼Cutting Down Rust Compile Times From 30 to 2 Minutes With One Thousand Crates: Explains how Feldera reduced Rust compile times by splitting large, auto-generated Rust codebases, allowing full CPU parallelisation during builds.💡How to Optimize your Rust Program for Slowness: Demonstrates how to write Rust programs that run for extraordinarily long periods, using techniques ranging from nested loops to Turing machines and hyperoperations.Swift🗞️Building Real‑Time iOS Apps with SignalR: Introducing the Official Swift Client (Public Preview): Microsoft's clientsupports core SignalR features like hubs, streaming, automatic reconnection, and integrates smoothly with SwiftUI or UIKit.💼Building a High-Performance SwiftUI App with a C++ Backend: Explores how the Kulve app uses Swift/C++ interop to achieve cross-platform performance and efficient memory management.PHP📖PHP: The Right Way: A living guide offering best practices, coding standards, and authoritative resources to help both new and experienced PHP developers write secure, maintainable code using modern approaches.🎓Quick guide to Laravel package development: A comprehensive tutorial on Laravel package development, detailing the steps to create, structure, configure, and publish reusable Laravel components.SQL💡Abusing DuckDB-WASM by making SQL draw 3D graphics (Sort Of): Describes an experiment where SQL queries are used to build a text-based 3D Doom clone, performing game logic and rendering via recursive CTEs.🎓A Deep Dive Into Ingesting Debezium Events From Kafka With Flink SQL: Compares the Apache Kafka SQL Connector (append-only and changelog modes) and the Upsert Kafka SQL Connector, detailing their best use cases.Ruby💼The One-Person Framework in practice: Recounts how the author built PlanGo, a €1M ARR business, as the sole developer using Ruby on Rails.🗞️Announcing Ruby Gem analytics powered by ClickHouse and Ruby Central: Developers can now query over 180 billion RubyGems download events using SQL, enabling insights into gem adoption trends since 2017.Kotlin🎓Kotlin 101: Type Classes Quickly Explained: Introduces type classes using the Arrow Kt library, demonstrating how they enable generic, reusable data validation logic without modifying data types.💡OpenAI vs. DeepSeek: Which AI Understands Kotlin Better?: Compares AI models on their ability to generate Kotlin code and answer Kotlin-related questions, showing DeepSeek-R1 leads in reasoning while OpenAI models offer faster performance.🧠Expert Insight: Designing Scalable Systems Means Planning for Failure📚An excerpt from an interview with Dhirendra Sinha (Google) and Tejas Chopra (Netflix), engineering leaders and authors of System Design Guide for Software ProfessionalsQ: What inspired you to write System Design Guide for Software Professionals? What key concepts or gaps did you aim to address?Dhirendra:I’ve been in the industry for more than two decades, working across startups and large organisations on complex, large-scale system designs. Around seven or eight years ago, I started teaching system design. There were two reasons for this: first, I wanted to give back to the community; second, moving into management was taking me away from core technology, and teaching helped me stay connected.I always thought I should write a book but never quite found the courage or time. When Packt approached me—actually, one of my mentors recommended my name—I saw it as a great opportunity. However, I insisted on having a co-author. I didn’t want to take on the whole process alone. Tejas was recommended, and we clicked immediately. He’s been a great collaborator.Our primary motivation was to go deeper into system design concepts and also prepare senior candidates for system design interviews. These interviews not only decide whether you get hired but also determine your levelling within a company. That was our intent when writing the book.Tejas:Like Dhirendra, I’ve worked at companies like Box and Netflix, where I’ve seen how software systems can fail in unobvious ways as they scale. Even senior engineers often struggle to bridge the gap in designing scalable systems. That was one of the motivations behind exploring this field further.We noticed that system design is often treated as an afterthought—mainly something you brush up on for interviews. But Dhirendra and I agreed that this shouldn’t be the case. We wanted the book to be more than a set of interview questions and answers. It’s meant to serve as a reference that explains why certain design choices are made, and how to think about architecture beyond the interview—to actual implementation in scalable organisations.We aimed to demystify distributed system principles and avoid the trap of just providing a checklist. Of course, there’s much more we could have written, but we felt this book lays a strong foundation to build upon.Q: What best practices do you apply in big tech to approach scalability and system robustness?Tejas:The first and most important principle is designing for failure. At Netflix, we assume the worst-case scenario—that everything will eventually fail. This mindset led to the creation of Chaos Monkey, which intentionally disrupts services to ensure systems are resilient enough to recover.Some of the key best practices we follow include:Automating routine tasks: This reduces manual effort and human error.Monitoring and observability at scale: We invest heavily in observability to ensure we can trace issues through our complex microservices architecture.Explicitly defining boundaries: It’s critical to be clear about how many users or requests a system can handle. Most failures stem from faulty assumptions about system capacity.Incremental rollouts: At Netflix, when deploying a new algorithm or feature—say, a recommendation engine—we roll it out to a small cohort first. We gather feedback, monitor performance, and only then scale it to larger user groups. This reduces risk and allows for adjustments along the way.These practices ensure that even when something goes wrong, the impact is contained, and recovery is swift.Dhirendra:I completely agree with Tejas. When I first heard about Chaos Monkey, I found it fascinating—this idea of deliberately causing failures to test system resilience.One example from my experience at Yahoo: An engineer once dismissed a corner case, saying it would only happen once in a million. The chief architect responded, “At our scale, that happens every hour.” That really stayed with me. Scale changes everything. Small assumptions that hold in low-scale systems can completely fall apart when you’re dealing with millions or billions of users.Another principle I encourage in my teams is thinking beyond launching features to landing them successfully. Launching is when you complete the code and push it out. Landing is about ensuring the feature operates smoothly in production, is maintainable, and doesn’t create operational burdens. I tell my engineers to focus on adoption, operational challenges, and long-term performance.Automation is crucial here too—not just for deployments, but also for monitoring, alerting, and scaling. We use infrastructure-as-code tools like Terraform and Kubernetes to define the expected state of the system and let the system evolve accordingly. But these automated systems must be well-tested to ensure they work reliably.Q: During system design interviews, what do you look for in candidates? What makes someone stand out?Dhirendra:System design interviews typically become relevant after around three to five years of experience. For fresh graduates, the focus is more on coding and algorithms. But for more experienced candidates, system design becomes crucial—not just for hiring, but also for levelling.In these interviews, I look for structured thinking. System design problems are open-ended and ambiguous—there’s no single correct answer. The way a candidate approaches and structures the problem, the questions they ask, and how they break it down are all important signals.Trade-offs are a key area I assess. It’s easy to choose between a good and a bad option. But at the senior level, you’re often choosing between two good options. I want to understand why a candidate makes a particular choice. What’s their reasoning? How do they evaluate different approaches under real-world constraints?I also like to dig into candidates' past projects—exploring trade-offs they made, how they handled failures, and what lessons they learned. Ultimately, I’m looking for engineers who can make practical, informed decisions in real-world scenarios.Tejas:I completely agree. For me, structured thinking and the ability to handle trade-offs are critical. But I also make interviews conversational. I expect candidates to ask questions and challenge assumptions. For instance, they should ask me how many users we’re designing for, or clarify the must-haves versus nice-to-haves. That’s what happens in real-world system design.I keep the problem intentionally broad to see how candidates scope it down. If they go too broad, they risk staying shallow. If they narrow it down, there’s an opportunity to go deeper into specific trade-offs.One area I like to probe is database selection. I’ll ask if they’d choose SQL or NoSQL and why. Then I might introduce a scenario where the user base grows tenfold—how does that affect their choice? Another area I like to explore is consistency models—strong consistency versus eventual consistency, and how they handle CAP theorem trade-offs.Q: Where do candidates typically struggle, and what advice would you give them?Tejas:One common struggle is jumping straight into diagrams without clarifying the problem. The first five or ten minutes should be about asking questions, defining the functional and non-functional requirements, and scoping the problem. Many candidates skip this and start designing based on assumptions.Another issue is lack of structure. Some candidates jump between different parts of the system without a coherent plan. Others over-engineer certain areas and lose track of the bigger picture. My advice: start with a simple, working solution. Once that’s established, layer in complexity as needed.Dhirendra:I’ve seen similar patterns. Many candidates don’t spend enough time clarifying and scoping the problem. They see something familiar and jump straight into designing everything that comes to mind. But without clear boundaries, they often design something different from what was asked.Time management is another pitfall. Some candidates get so caught up in one area that they run out of time to cover the core pieces. My advice: practise with mock interviews and time yourself. Make sure you pace the conversation and don’t get stuck in the weeds.Another key point is listening to interviewer hints. As interviewers, we want candidates to succeed. If we suggest moving on or exploring a different area, it’s important to pick up on that. Ignoring those cues can limit your opportunity to showcase your thinking.About the Authors:Dhirendra Sinha is a Software Engineering Manager at Google with nearly two decades of experience building scalable distributed systems and leading engineering teams. Alongside roles at Cisco, Oracle, Yahoo, and Google, he has held leadership positions at early and late-stage startups and serves as an angel investor and advisor. For the past seven years, he has taught Distributed System Design and has been mentoring engineers and managers for over a decade. Dhirendra holds a B.Tech from IIT Guwahati and an M.S. from Texas A&M University, College Station.Tejas Chopra is a Senior Engineer at Netflix, working on its Machine Learning Platform for recommendations and personalisation. He is Co-founder of GoEB1, a thought leadership platform for immigrants, and a recipient of the EB1A (Einstein) visa. Recognised as a Tech 40 under 40 awardee, 2x TEDx speaker, and BCS Fellow, Tejas is also an Adjunct Professor at the University of Advancing Technology, Arizona, an angel investor, and startup advisor. His experience spans Box, Apple, Samsung, Cadence, and Datrium, and he holds a Master’s in Electrical and Computer Engineering from Carnegie Mellon University.Their book System Design Guide for Software Professionals was published by Packt in August 2024.Get 15% off both the eBook and Paperback editions exclusively at Packtpub.com with code SYSTEM15. Offer valid until 30th April.Claim 15% Off – Offer Ends 30th April🌟Advanced Concepts🚀Renovate to Innovate: Fundamentals of Transforming Legacy Architecture: Presents strategies for modernising legacy systems through evolutionary architecture, deprecation-driven development, and intentional organisational design.We Have to Move Fast…But Where are We Going Again?: Advocates for adopting a technology radar to guide decision-making in fast-paced development environments to ensure consistent technology choices and prevent fragmentation across teams.A Full Guide to Planning Your Authorization Model and Architecture: Addresses user management, approval workflows, machine identities, auditability, and future-proofing.Building a Unified API: How Federated GraphQL Powers Our Microservice Architecture: Details how Rawkode Academy built a federated GraphQL API using GraphQL Yoga, Pothos, and WunderGraph Cosmo to unify data access across microservices.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 73

Divya Anne Selvaraj
17 Apr 2025
15 min read
Save for later

ProgrammingPro #97: Google's Python Agent Toolkit, C++ at Nanosecond Speed, JetBrains launches Junie, and Rebuilding Every Four Years

Divya Anne Selvaraj
17 Apr 2025
15 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#97:Google's Python Agent Toolkit, C++ at Nanosecond Speed, JetBrains launches Junie, and Rebuilding Every Four YearsBuild the Future of Apps on HubSpotNew developer products introduce deeper extensibility, flexible UI options, modern development tools, and more—shaping a more powerful, customisable platform experience.HubSpot’s AI-powered ecosystem is projected to become a $10.2 billion opportunity by 2028. To help developers tap into that growth, we're opening up the platform—introducing expanded APIs, customisable app UIs, and tools built to support a unified data strategy.Learn moreHi ,Welcome to a brand new issue of ProgrammingPro.In today’sExpert Insight, we bring you an excerpt from our interview with Francesco Abbruzzese and Gabriel Baptista, authors of Software Architecture with C# 12 and .NET 8, Fourth Edition, where they discuss how AI is being used in architecture today, why it won’t replace human expertise anytime soon, and the evolving skill set software architects need to stay relevant.News Highlights: Google releases an open source Python toolkit for building and deploying AI agents; JetBrains launches Junie AI agent, updates AI Assistant, and adds a free IDE tier; Symbiotic Security unveils an AI tool for real-time code vulnerability fixes; and .NET 10 Preview 3 boosts C# 14, Blazor WebAssembly, and AOT support.My top 5 picks from today’s learning resources:Python at the Speed of Rust✨When Nanoseconds Matter: Ultrafast Trading Systems in C++ - David Gross - CppCon 2024⏱️Some features that every JavaScript developer should know in 2025🧠Fitness Functions for Your Architecture🏗️You’ll Rebuild Everything Every Four Years Anyway🧱But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSign Up|Advertise🗞️News and Analysis🔎Google’s Agent Development Kit (ADK):Google has released an open-source Python toolkit for building, evaluating, and deploying AI agents with fine-grained control, offering code-first orchestration, multi-agent design, and seamless integration with Google Cloud services.JetBrains goes live with Junie AI agent, updates AI assistant, adds free tier: The multi-step AI coding agent now has an updated AI Assistant with new models and multi-file edit support, and a free tier for 2025.1 IDEs.Symbiotic Security launches AI tool for detecting and fixing vulnerabilities in code: The tool integrates into IDEs to detect and fix code vulnerabilities in real time and includes a chatbot for in-context security training and remediation..NET 10 Preview 3 bolsters standard library, C#, WebAssembly: Preview 3 adds an AOT-safe ValidationContext constructor, expands C# 14 extensions, and improves Blazor WebAssembly performance.PHP security audit of critical code reveals flaws, fixed in new release: A security audit of PHP’s core interpreter code has uncovered multiple high-severity flaws, including log tampering, memory errors, and data leaks, all of which were fixed in version 8.4.6.JRuby 10 brings faster startup times: The version improves startup times using modern JVM features like AppCDS and Project CRaC, adds support for Java 21, and aligns with Ruby 3.4.Trending Model Context Protocol (MCP) for AI Agents Gets C# SDK: Microsoft has released an official C# SDK for MCP, simplifying MCP integration into C# apps and server creation.Gleam 1.10 improves compiler, JavaScript codegen: The version enhances its compiler with improved type tracking, string exhaustiveness analysis, better operator handling, and cross-module rename support.🎓Tutorials and Learning Resources💡Python💡Python at the Speed of Rust:IntroducesFunction, a compiler that converts Python functions into native code using symbolic tracing and type annotations, achieving near-Rust performance.For more Python resources, go to PythonProC# and .NET💡Optimizing memory usage with modern .NET features: Shows how the author reduced memory allocations after migrating to .NET 8/9 by replacing inefficient patterns with modern .NET features.💡What's new in C# 14: Introduces C# 14 features such as the field keyword for simpler property backing, implicit Span<T> conversions, unbound generics in nameof, parameter modifiers in lambdas, partial constructors and events, and null-conditional assignments.🎓Foundations of Data Structures and Algorithms in C#: Introduces a foundational C# repository that teaches core data structures and algorithms including arrays, linked lists, sorting, searching, recursion, graphs, and more.C++ and C🎥When Nanoseconds Matter: Ultrafast Trading Systems in C++ - David Gross - CppCon 2024: Explains how to engineer low-latency trading systems in C++ by focusing on data structure design, CPU profiling, and performance-aware memory use.💡6 usability improvements in GCC 15: Improvements include clearer static analysis visuals, improved C++ template diagnostics, dual-format machine-readable SARIF output, C23 migration aids, and more.💡Compiler Options Hardening Guide for C and C++: The updated guide (April 2025) refines flag recommendations, clarifies usage contexts like -Werror, expands coverage of hardening options such as -fstrict-flex-arrays=3, and improves guidance for development versus production builds.Java💡When Inheritance is a Good Thing: Argues that while inheritance is often misused for code reuse—it remains valuable particularly in implementing design patterns like Decorator and Visitor.💡30 Advanced Spring Boot Interview Questions for Experienced Professionals: Presents a list of Q&As focusing on topics such as performance optimization, microservices architecture, security, and configuration management.💡Efficiently making (almost) any concurrency control mechanism serializable: Explains how the Serializable Safety Net (SSN) algorithm adds serializability to existing concurrency control methods by efficiently tracking transaction dependencies using minimal metadata.JavaScript and TypeScript💡Some features that every JavaScript developer should know in 2025: Covers iterator helpers for memory-efficient data transformation, Promise.withResolvers(), structuredClone() , tagged templates, and more.💡An Introduction to JavaScript Bundler Rspack: Introduces a high-performance JavaScript bundler written in Rust that offers fast builds, Webpack compatibility, built-in optimization features, and a smooth developer experience.💡Deploying TypeScript: recent advances and possible future directions: Discusses type stripping, isolated declarations, JSR support, the future of shipping .ts files, type annotations in JavaScript, and the evolving roles of JSX.Go🎓Unit testing using mocks in Go: Covers AWS S3 bucket creation, by refactoring functions to accept interfaces, implementing mock types to simulate success and failure scenarios, and using table-driven tests to streamline cases.🎓Using Signals With Go: Explains how to handle operating system signals in Go using the os/signal package, demonstrating how to listen for signals like SIGINT to implement features such as graceful shutdowns, and more.Rust💡Two Years of Rust: Reflects on the author's experience in backend development with Rust for a B2B SaaS product, examining its learning curve, performance, tooling, type safety, error handling, and developer experience.💡A 2025 Survey of Rust GUI Libraries: Assesses 23 libraries including Azul, Cacao, Core Foundation, Crux, and Floem, based on ease of setup, accessibility support, internationalization capabilities, and overall user experience.Swift🎓Using Instruments to profile a SwiftUI app: Explains how to profile SwiftUI apps using Instruments, covering how to detect slow code, track view redraws, and interpret performance data like view body evaluations and CPU usage.🎓Implementing Task timeout with Swift Concurrency: Shows how to implement timeouts in Swift Concurrency by racing a work task against a timed task using a TaskGroup, returning whichever completes first.PHP🎓Create User-Friendly Password Requirement Indicators with Laravel’s appliedRules() Method: Introduces a method which lets developers dynamically access password validation rules for display in views.💡PHP 8.5 & 9.0: What’s Changing, What’s Breaking, and What You’ll Love: Outlines new features including improved debugging tools, stricter error handling, cleaner function signatures, and the removal of legacy features.SQL💡SQL Plan Baseline, SQL Patch, SQL Profile: Differences and Use Cases: Explains the differences between the three Oracle mechanisms, detailing how each influences SQL execution plans and when to apply them for optimal plan stability and performance tuning.💡Some Thoughts on SQL v. NoSQL: Argues that for most early-stage startups, using DynamoDB over Postgres results in greater complexity with minimal benefit, particularly around schema management, query flexibility, and developer experience.Ruby💡Pre-build a Secure Authentication Layer with Authentication Zero for Ruby on Rails: Introduces Authentication Zero, a code generator for Ruby on Rails that scaffolds a secure, customisable authentication system with built-in best practices.🎓Migrating Sidekiq Background Jobs to Temporal in Ruby on Rails: Explains how Temporal enables reliable, stateful workflows with built-in retries, fault tolerance, and orchestration suited for long-running or complex processes.Kotlin💡Type-safe, multiplatform JSON serialization for Kotlin, generated at compile-time: Introduces kotlin-json-stream-serializer, a compile-time code generation tool for type-safe, multiplatform JSON serialization in Kotlin using OKIO streams.🎓Making Android Code Cleaner with Use Cases: A Practical Approach Using Kotlin Coroutines: Explains how replacing bulky interactors with single-responsibility Kotlin coroutine-based use cases improves Android app architecture.🌟Advanced Concepts🚀Fitness Functions for Your Architecture: Discusses how to implement and scale architectural fitness functions using tools like ArchUnit and JMolecules, and how this practice can improve system maintainability, agility, and team alignment.The problem with indirections: Critiques the overuse of indirections in software development, arguing that many common abstractions can complicate code, reduce readability, and hinder maintainability without sufficient benefit.You’ll Rebuild Everything Every Four Years Anyway: Argues that while full rebuilds of software systems occur frequently due to technical and organisational complexity, a modular architecture enabling incremental change is a more sustainable and pragmatic alternative.Why most technical documentation fails (and how to fix it with inclusive, accessible design): Outlines a science-based framework for creating inclusive, modular, and accessible documentation through clear language, visual support, progressive disclosure, and user-friendly navigation.Ingres vs Postgres MVCC Explained With Neo4j's LLM Knowledge Graph Builder: Shows how GraphRAG improves data retrieval accuracy by leveraging graph relationships, offering architectural insights for developers integrating LLMs into knowledge-intensive systems.🧠Expert Insight: Using AI in Software Architecture Starts with Good Design📚An excerpt from an interview with Francesco Abbruzzese and Gabriel Baptista, authors of Software Architecture with C# 12 and .NET 8, Fourth EditionQ: What inspired you to write Software Architecture with C# 12 and .NET 8?Francesco:The main point was that this book brings together various subjects that are hard to find in one place. I wanted to collect my experience and put it into something solid—a book that could be useful in my advisory work, in courses, and also for my customers. It’s a practical tool for all of that.Gabriel:For me, it marked a really important point in my career. I’ve worked both in the college environment and in industry for a long time. This opportunity allowed me to give back to the community a complete material, a full pipeline on how to create an enterprise solution.It was a great chance to work with Francesco too—we found a lot of common ground. I think readers will notice that the book reads as though it was written by a single person. We worked closely and it was a really enjoyable collaboration.Q: Could you give us a few examples of how AI-driven tools are currently being used in architectural design and what new paradigms you see emerging?Gabriel:AI is definitely the topic on everyone’s mind right now. But a good AI still depends on a good software architecture—because AI needs good data. Without good data, you can't have good AI.As architects, we’re going to be impacted by AI, positively or negatively, depending on how we work with it. For example, today it’s possible to upload an architectural design into a tool like ChatGPT and have a conversation about whether it’s good or bad. I’ve done this—it can suggest changes or provide feedback. But you still need to analyse that feedback and judge if it's correct, especially in enterprise environments where things are more complex.So AI will change the world, but we need to use our intelligence to evaluate its output. Architects need to design systems that can produce good AI—because poor architecture means poor data, and that leads to poor AI.Francesco:AI is a valuable tool, but it can’t fully replace a professional’s experience—at least not yet. It helps save time and can suggest options, but sometimes those suggestions are wrong. Other times they’re a useful starting point for further investigation.AI can write some code, create diagrams or designs that serve as a base to work from. It might remind you of something you’d forgotten to analyse. But that doesn’t mean it’s giving you the best solution—it’s just helping you avoid overlooking things.Right now, it’s still far from the kind of general intelligence that could fully take over an architect’s job.Q: What remains irreplaceable about human architects—and how they can use AI to enhance, rather than replace, their role?Francesco:Architects should use AI to save time—for instance, to generate some starting designs or initial code. In my company, we developed an AI tool that can generate a complete Visual Studio solution, with all the needed projects and some basic starting code. It doesn’t always work perfectly, but it’s a useful starting point and it saves time, especially with complex architectures like those based on microservices or onion architecture.In those cases, setting everything up manually would take a long time. With this tool, we can automate 50–60% of that groundwork. But even then, the hard part is modelling the real world—and AI doesn’t have enough understanding of the world to do that on its own. It still needs a human to interpret the requirements and guide the process.Gabriel:Our book focuses a lot on the architect’s role in a team. Architects design the solution pipeline and are responsible for the technical direction of enterprise projects.Today, AI can be used to accelerate things for the whole team—not just the architect. But it’s still just a starting point. You need someone with experience to evaluate whether the output fits the requirements. This is especially true for enterprise systems, where quality and correctness matter a lot.Even tools like GitHub Copilot don’t just help you write code—they also help analyse if you’re following best practices. But it’s still the architect’s responsibility to decide which tools are appropriate and whether they’re improving the team’s performance.Q: What skills do you see becoming essential for software architects as technology continues to evolve?Gabriel:If you look at everything we’ve talked about so far—distributed systems, AI, security—they all point to one thing: the future is distributed. So, understanding how to build distributed applications is going to be essential. Architects also need a solid grounding in information security.And beyond the technical, I’d say soft skills are critical too. When you introduce changes like DevOps or observability, you’re impacting the entire team. The ability to bring people along with you—to communicate, to influence—is just as important as technical skill.Francesco:I agree with Gabriel. Many developers and architects still think of security as something you add at the end—firewalls, updates, patches. That mindset has to change. Security needs to be part of how we design and write code from the beginning.Architects preparing for the future should update how they design, how they build, and how they think about development. That means learning about DevOps, distributed systems, and modern development methodologies—and making them second nature.About the AuthorsFrancesco Abbruzzese is a software architect and the creator of the MVC and Blazor Control Toolkit. He has extensive experience in designing enterprise-grade applications and consults on scalable architectural solutions. Francesco also trains development teams and contributes actively to the .NET ecosystem.Gabriel Lara Baptista is an Azure PaaS specialist and university instructor with a strong focus on cloud-native applications and team enablement. He brings together academic depth and real-world implementation in his work and is passionate about building resilient systems that scale with business needs.Their book Software Architecture with C# 12 and .NET 8, Fourth Edition was published in February 2024. It serves as a practical, end-to-end guide to designing scalable, secure, and modern enterprise applications using proven architectural patterns and real-world .NET tooling. It’s designed to help developers move confidently from high-level design to implementation across today’s complex cloud-native environments.Get the Paperback for $49.99$28.50!🛠️Useful Tools⚒️Koreo: An open-source toolkit that acts as a meta-controller programming language for Kubernetes, enabling unified configuration management and resource orchestration.ai-agents-for-beginners: A free, multi-language course of 10 lessons with hands-on Python examples and videos that teach developers how to build AI agents using Microsoft’s Azure AI Foundry, Semantic Kernel, and AutoGen.maxun: An open-source, no-code web data extraction platform that lets users create automated robots to scrape websites, handle pagination, and turn web pages into structured APIs or spreadsheets.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 176

Divya Anne Selvaraj
10 Apr 2025
14 min read
Save for later

ProgrammingPro #96: Rust 1.86 Trait Upcasting, GitHub Copilot Security Campaigns, Python Shell Commands, and Dangerous C++ Behaviors 

Divya Anne Selvaraj
10 Apr 2025
14 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#96:Rust 1.86 Trait Upcasting, GitHub Copilot Security Campaigns, Python Shell Commands, and Dangerous C++ BehaviorsUpgrade Your Mind for Half the PriceTwo bestselling tech books. Now 50% off. For a limited time.Get the Paperback for $57.99 $25.33!Get the Paperback for $54.99 $25.33!Hi ,Welcome to a brand new issue of ProgrammingPro.In today’sExpert Insight, we bring you an excerpt from the recently published book, C++ Memory Management, which discuses three major categories of dangerous behavior in C++—ill-formed code with no required diagnostics, undefined behavior that compilers may optimize around unpredictably, and implementation-defined behavior that risks portability.News Highlights: Sonatype flags 18,000 open source malware packages in Q1, most targeting data theft; GitHub rolls out security campaigns with Copilot autofix to reduce security debt; Rust 1.86 adds trait upcasting; and Kotlin, Swift, and Ruby drop from Tiobe’s top 20.My top 5 picks from today’s learning resources:Running External Commands in Python (Shell or Otherwise)🧨The C# Reinforcement Learning Revolution - Breaking Free from Python's Grip🧠Common Go Patterns for Performance🚴‍♂️Shadow Table Strategy for Seamless Service Extractions and Data Migrations🫥Beyond Chatbots: Architecting Domain-Specific Generative AI for Operational Decision-Making🧭But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSign Up|Advertise🗞️News and Analysis🔎Sonatype warns of 18,000 open source malware packages in Q1 2025: Over half of these were designed to exfiltrate sensitive data, signaling a sharp rise in sophisticated software supply chain threats.GitHub introduces security campaigns to help developers reduce security debt: The new feature will help teams by coordinating fixes across repos with prioritized tasks, templates, and Copilot-assisted autofixes.Rust language adds trait upcasting: Rust 1.86 introduces long-awaited trait upcasting, allowing trait objects to be upcast to supertrait objects, alongside new APIs, mutable indexing enhancements, and compiler safety improvements.Kotlin, Swift, and Ruby losing popularity – Tiobe index: The three languages have fallen out of Tiobe’s top 20 programming languages, signaling declining popularity due to platform-specific use and competition from more versatile languages like Python.EngFlow Makes C++ Builds 21x Faster and Software a Lot Safer: EngFlow has launched the public beta of CMake RE and acquired tipi.build to deliver significantly faster and safer C/C++ builds through remote execution, caching, and modern dependency management tools.Django 5.2 release touts automatic model importing: The version also introduces support for composite primary keys and easier BoundField overrides, while ending support for earlier 5.x versions.April 4, 2025: AI updates from the past week: Updates include Claude for Education’s guided learning features, Amazon's new site and SDK for Nova models, and Solo.io’s MCP Gateway for managing AI agent tool sprawl.🎓Tutorials and Learning Resources💡Python🎓Running External Commands in Python (Shell or Otherwise): Explains how to use subprocess.run() in Python to execute system commands safely and efficiently.For more Python resources, go to PythonProC# and .NET💡The C# Reinforcement Learning Revolution - Breaking Free from Python's Grip: Challenges Python’s dominance in reinforcement learning by presenting RLMatrix, a C# framework offering superior debugging, type safety, performance, and production integration for real-world applications.💼How we ended up rewriting NuGet Restore in .NET 9: Delves into Microsoft's rewrite of NuGet Restore to fix major performance bottlenecks caused by a legacy recursive graph resolution algorithm that failed at scale.🎓Migrate C# apps from the in-process model to the isolated worker model: Provides a detailed migration guide for moving C# Azure Functions apps from the in-process model to the isolated worker model before support ends in November 2026.C++ and C💡C++26: variadic friends: Introduces a new feature coming in C++26 through proposal P2893R3, which will enable you to grant friendship to a pack of types in templates, simplifying patterns like the passkey idiom and CRTP.🎓STL Demystified: A Practical Guide to C++ Standard Template Library (STL): An example-rich guide covering STL's core components—containers, iterators, algorithms, and function objects—along with detailed demonstrations.💡Writing C for curl: Covers curl’s coding guidelines and safety practices for writing secure, maintainable C code, including testing, memory management, code style, error handling, and the use of custom helper functions.Java🎓Choosing the Right Implementation Between ArrayList and LinkedList: Analyzes algorithm complexity, read/insert performance, iteration cost, and memory usage to help choose the right implementation.💡JDK 24 Security Enhancements: Compiles the most important security enhancements in the latest Java release including quantum-resistant cryptography with ML-KEM (key encapsulation) and ML-DSA (digital signatures).💡10 Java-based tools and frameworks for generative AI: Covers tools including Spring AI, LangChain4j, Deeplearning4J, and Jllama among others for tasks like LLM orchestration and vector database integration.JavaScript and TypeScript💡On JavaScript's Weirdness: Highlights surprising behaviors with eval, loop scoping, falsy values like document.all , inconsistent string iteration due to Unicode, sparse arrays that break array methods, and more.🎓Learning Clojure as a Javascript developer: Compares JavaScript patterns with Clojure idioms using real examples, especially around building strings, destructuring, and using threading macros (->>).🎓Use the Gemini API with OpenAI fallback in Typescript: Demonstrates how to implement a fallback strategy between Gemini and OpenAI APIs in TypeScript using the OpenAI TS/JS library.Go💡Cutting 70% of Infra Costs with Go: A benchmark between Go, NextJS, Java and GraalVM: Benchmarks REST APIs built with Go (Gin, Chi), Java (Spring Boot, Micronaut, Quarkus), Kotlin, and Node (NestJS), revealing Go (Chi) as the most performant.💡Common Go Patterns for Performance: Outlines 15 performance patterns across memory, concurrency, I/O, and compiler tuning, covering techniques like object pooling, preallocation, zero-copy, worker pools, atomic ops, and more.Rust💡Adaptive Lossless Floating Point (ALP) Rust is faster than C++: A Rust ALP compression implementation achieves 20–50% higher throughput than its C++ counterpart by leveraging Rust’s well-defined float-to-int casting semantics.🎓Pitfalls of Safe Rust: Explores issues like unchecked arithmetic, unsafe type casting, unbounded inputs, path manipulation quirks, improper use of unwrap , and misuse of serialization or default values and more.Swift🗞️Swift 6.1 Released: The version introduces concurrency enhancements, trailing comma support across more syntax, package traits for configurable APIs, and productivity-focused diagnostics.🎓SwiftUI Alert Guide + Code Examples: Explains how to present alerts in SwiftUI using view modifiers, including basic alerts, alerts with custom actions, and data-driven alerts using objects or errors.PHP🎓An opinionated HTML Serializer for PHP 8.4: Introduces a serializer built using PHP 8.4’s new Dom\HTMLDocument class to produce neatly indented, human-readable HTML output.🎓A cookieless, cache-friendly image proxy in Laravel (inspired by Cloudflare): Outlines how to build a cookieless, cache-friendly image proxy in Laravel, mimicking Cloudflare’s image resizing service.SQL🎓Building AI apps? You need sync: Using ElectricSQL, demonstrates how syncing state through a database solves UX and reliability challenges in handling key collaboration needs such as resumability and multi-device support.💡When parameterization fails: SQL injection in Nim's db_postgres module using parameterized queries: Reveals how Nim's db_postgres module can be vulnerable to SQL injection when standard_conforming_strings is disabled, due to flawed manual escaping in its parameterization logic.Ruby🎓Setting up Zed with Ruby LSP: Details steps for setup, diagnostics, and troubleshooting, while addressing feature gaps compared to VS Code.🎓Ruby makes advanced CLI options easy: Explains how Ruby’s built-in OptionParser makes building flexible, user-friendly CLI tools easy—without relying on external gems—by showcasing advanced usage.Kotlin🗞️Introducing Kotlin-bench: Introduces a benchmark designed to evaluate LLMs on 100 real-world Kotlin and Android development tasks using GitHub issue-PR pairs and unit test validation.🗞️Bringing Fuzz Testing to Kotlin with kotlinx.fuzz: Introduces a Kotlin-native fuzz testing framework built on Jazzer, enabling developers to uncover edge cases and hidden bugs by generating randomized input for target functions.🌟Advanced Concepts🚀Shadow Table Strategy for Seamless Service Extractions and Data Migrations: Introduces a zero-downtime data migration method that maintains a synchronized copy of production data using triggers or CDC, enabling seamless database migrations, microservice extractions, and schema refactoring.Beyond Chatbots: Architecting Domain-Specific Generative AI for Operational Decision-Making: Argues that LLMs fall short for real-time, domain-specific business decisions and introduces domain-specific generative models as a better alternative.Architectural Experimentation in Practice: Frequently Asked Questions: Clarifies when to use experiments, how to structure them for actionable outcomes, and how they differ from unstructured exploration.The single-writer Database Architecture: Explains how Bugsink uses a single-writer database architecture built on SQLite’s concurrency model to ensure stable, consistent, and simple event processing.JetBrains Terminal: A New Architecture: Introduces JetBrains’ reworked terminal architecture which restores full shell compatibility by returning to a standards-compliant core (JediTerm) while using the IDE’s editor.🧠Expert Insight📚Here’s an excerpt from “Chapter 2: Things to Be Careful With" in the book, C++ Memory Management, by Patrice Roy, published in March 2025.Different kinds of evilBefore delving into some actual practices that require care, it’s interesting to look at the main categories of risks we could run into if our code does not respect the rules of the language. With each such category comes a form of unpleasantness we should striveto avoid.Ill-formed, no diagnostic requiredSome constructs in C++ are said to beIll-Formed, No Diagnostic Required(IFNDR). Indeed, you will find quite a few occurrences in the standard of“if […], the program is ill-formed, with no diagnostic required.”When something is IFNDR, it means your program is broken. Bad things could happen, but the compiler is not required to tell you about them (indeed, sometimes, the compiler does not have sufficient information to diagnose theproblematic situation).One Definition Rule(ODR) violations, to which we will return in theThe ODRsection later in this chapter, fall under IFNDR. However, there are other such cases, such as having a global object that has different alignment requirements (throughalignas) in different translation units (different source files, essentially), or having a constructor that delegates to itself either directly or indirectly. Here isan example:class X {public: // #0 delegates to #1 which delegates to #0 which... X(float x) : X{ static_cast<int>(x) } { // #0 } X(int n) : X{ n + 0.5f } { // #1 }};int main() {}Note that your compiler might give a diagnostic; it’s just not required to do so. It’s not that compilers are lazy – they might even be unable to provide a diagnostic in some cases! So, be careful not to write code that leads toIFNDR situations.Undefined behaviorWe mentionedUndefined Behavior(UB) inChapter 1. UB is often seen as a source of headaches and pain for C++ programmers but it refers to any behavior for which the C++ standard imposes no requirement. In practice, this means that if you write code that contains UB, you have no idea what’s going to happen at runtime (at least if you’re aiming for somewhat portable code). Canonical examples of UB include dereferencing a null pointer or an uninitialized pointer: do that and you’ll be inserious trouble.To compilers, UB is not supposed to happen (code that respects the rules of the language does not contain UB, after all). For that reason, compilers “optimize around” code that contains UB, to sometimes surprising effect: they might begin removing tests and branches, optimizing loops away, andso on.The effects of UB tend to be local. For instance, in the following example, there is a test that ensures thatpis not null before using*pin one case, but there is at least one access to*pthat is unchecked. This code is broken (the unchecked access to*pis UB), so the compiler is allowed to rewrite it in such a way that all tests to verify thatpis not null are effectively removed. After all, the damage would be done ifpwerenullptr, so the compiler is entitled to assume that the programmer passed a non-null pointer tothe function!int g(int);int f(int *p) { if(p != nullptr) return g(*p); // Ok, we know p is not null return *p; // oops, if p == nullptr this is UB}The whole body off()could legitimately be rewritten by your compiler asreturn g(*p)in this case, with thereturn *pstatement being turned intounreachable code.The potential for UB hides in various places in the language, including signed integer overflow, accessing an array out of bounds, data races, and so on. There are ongoing efforts to reduce the number of potential UB cases (there’s even a study group,SG12, dedicated to this effort), but UB will likely remain part of the language for the foreseeable future, and we need to be awareof it.Implementation-defined behaviorSome parts of the standard fall under the umbrella ofimplementation-defined behavior, or behavior that you can count on with a specific platform. This is behavior that your platform of choice is supposed to document, but that is not guaranteed to be portable toother platforms.Implementation-defined behavior occurs in many situations and includes such things as implementation-defined limits: the maximum number of nested parentheses; the maximum number of case labels in a switch statement; the actual size of an object; the maximum number of recursive calls in aconstexprfunction; the number of bits in a byte; and so on. Other well-known cases of implementation-defined behavior include the number of bytes in anintobject or whether thechartype is a signed or an unsignedintegral type.Implementation-defined behavior is not really a source of evil, but it can be problematic if one strives for portable code but depends on some non-portable assumptions. It is sometimes useful to spell one’s assumptions in code throughstatic_assertwhen the assumption can be validated at compile-time or some similar, potentially runtime mechanisms in order to realize—before it’s too late—that these assumptions are broken for a given target platform.For example:int main() { // our code supposes int is four bytes wide, a non- // portable assumption static_assert(sizeof(int)==4); // only compiles if condition is true...}Unless you are convinced that your code will never need to be ported to another platform, strive to rely as little as possible on implementation-defined behavior, and if you do, make sure that you validate (throughstatic_assert if possible, at runtime if there’s no other choice) and document this situation. It might help you avoid some nasty surprises in the future...C++ Memory Managementwas published in March 2025. Packt library subscribers can continue reading the entire book for free or you can buy the book here!Get the eBook for $33.99$29.99🛠️Useful Tools⚒️MonkeysPaw: A Ruby web framework that generates entire web pages from natural language prompts, using LLMs to interpret and fulfill developer "wishes."markitdown: A Python tool that converts various file types to Markdown for LLMs, preserving structure for accurate analysis and supporting plugins, format-specific dependencies, and LLM integration.mcp-go: A Go library that implements the Model Context Protocol, enabling LLM applications to interact with external tools and data through simple, high-level server and tool definitions.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 109
Divya Anne Selvaraj
27 Mar 2025
12 min read
Save for later

ProgrammingPro #95: C++98–23 Benchmarks, GitHub AI Secret Scans, Fancy F-Strings in Python, and Hardware-Aware Coding🏎️

Divya Anne Selvaraj
27 Mar 2025
12 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#95:C++98–23 Benchmarks, GitHub AI Secret Scans, Fancy F-Strings in Python, and Hardware-Aware Coding🏎️The ACCU Conference: By Programmers, For ProgrammersRunning since 1997, ACCU is one of the longest-standing dev conferences—originally C/C++ focused, now covering everything from Python and Rust to Kotlin, Go, and more.Use code PACKT2025 for 10% off your ticket.Book Your Spot!Hi ,Welcome to a brand new issue of ProgrammingPro.In today’s Expert Insight, we share an original article by Ferenc-Lajos Deák, coauthor of Debunking C++ Myths, tracing C++ from 98 to 23 with real code and performance benchmarks that reveal how each standard holds up.News Highlights: GitHub launches AI-powered secret scanning to cut false positives; critical Next.js auth bypass patched in v14+; Claude, Gemini, and OpenAI roll out major AI updates; and Oracle’s ML-optimized GraalVM boosts Java microservice performance by 7.9%.My top 5 picks from today’s learning resources:I Want My Own Fancy F-String Format Specifiers… Sure You Can🪡Options Pattern Validation in ASP.NET Core With FluentValidation🧪UI Algorithms: A Tiny Undo Stack⏮️Hardware-Aware Coding: CPU Architecture Concepts Every Developer Should Know🏎️Applying Flow Metrics to Design Resilient Microservices🌊But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSign Up|Advertise🗞️News and Analysis🔎GitHub Leverages AI for More Accurate Code Secret Scanning: GitHub's AI-powered secret scanning now uses context analysis and multiple LLM techniques to reduce false positives and improve secret detection accuracy in code.Next.js team fixes vuln that allows auth bypass when middleware is used, revises documentation recommending this method: The critical vulnerability allowed easy auth bypass via a specific request header, affecting all versions and is fixed in v14+.Mar 21, 2025: AI updates from the past week: Claude can now browse the web for real-time responses; Google launched Gemini Canvas for collaborative coding; and OpenAI upgraded its audio models for better transcription and speech synthesis.Oracle releases ML-optimized GraalVM for JDK 24: The version introduces GraalNN, an ML-based profiling system delivering 7.9% peak performance gains in microservices..NET 10 Preview 2: Enhanced Reconnection UI, Improved Blazor Features, and Updates across the Stack: Preview 2 also introduces enhanced navigation behavior, OpenAPI metadata generation, and UI updates in .NET MAUI.The future of Scala: Pioneering features are now commonplace so what comes next?: Many features once unique to Scala are now mainstream, and adoption of Scala 3 remains slow due to incompatibility with Scala 2.Microsoft introduces Hyperlight Wasm for WebAssembly workloads: The experimental micro-VM enables secure, low-latency execution of WebAssembly workloads in languages like C, Python, and Rust.🎓Tutorials and Learning Resources💡Legend:🎓 Tutorial/Course | 💼 Case Study | 💡 Insight/Analysis |📖Open Access Book or Comprehensive Resource | 🗞️Something NewPython🎓I Want My Own Fancy F-String Format Specifiers… Sure You Can: Shows you how to implement custom f-string format specifiers in Python by defining the .__format__() method, enabling tailored string output logic within your classes. 💡fastplotlib: driving scientific discovery through data visualization: Introduces fastplotlib, a new Python library for GPU-accelerated, interactive scientific visualization built on modern graphics APIs like WGPU. 💡Defining AI tools in python: compares three approaches to defining AI agent tools in Python: using function docstrings, pydantic models, or supporting both.C# and .NET🎓How To Validate Email Addresses in C#?: Compares regex-based, built-in .NET classes, and simplified logic, ultimately recommending a lightweight custom method that avoids regex complexity and is resilient to malformed inputs.🎓How to Build a 2D Safe Code Breaker Mini-Game in Unity: Walks you through building a 2D “Safe Code Breaker” mini-game in Unity using UI elements, C# scripting, and audio feedback.🎓Options Pattern Validation in ASP.NET Core With FluentValidation: Shows you how to use FluentValidation with ASP.NET Core’s Options Pattern to validate configuration settings at startup, offering a more powerful alternative to Data Annotations.C++ and C💡C++26 Expansion Tricks: Demonstrates advanced compile-time expansion techniques in C++26 using reflection (P2996), structured bindings (P2686), and expansion statements (P1306).🗞️C++ Dynamic Debugging: Full Debuggability for Optimized Builds: The feature introduced in Visual Studio 2022 (v17.14 Preview 2) enables full debugging of optimized C++ code by dynamically deoptimizing breakpoints or stepped-into functions.📖Open Access Book | Beej's Guide to C Programming by Brian "Beej Jorgensen" Hall: A comprehensive resource designed for individuals who have prior experience with other programming languages and wish to learn C.Java🎓Stream Gatherers: The Missing Piece in Java Stream Processing: Explains how to build and apply custom gatherers, including stateful, stateless, and parallel-capable examples.🎓How to query CSV as a database table in Java with esProc: Shows you how to use esProc to query CSV files in Java as if they were database tables, by embedding SPL statements via esProc's JDBC driver.JavaScript and TypeScript🎓UI Algorithms: A Tiny Undo Stack: Explains how to implement a lightweight, robust undo stack for UI actions using two arrays—past and future—instead of index-based stacks.💡JavaScript numbers have an (adoption) problem: Explores how JavaScript’s exclusive use of floating-point numbers causes precision issues, bitwise limitations, and unexpected behavior and recommends using BigInt.💡Speeding up Typescript Go by 100x: Delves into how caching subtlety in TypeScript's type system can dramatically affect compiler performance and how tsgo’s internals diverged from tsc before the fix.Go💼Faster interpreters in Go: Catching up with C++: Explains the design evolution of Vitess’s SQL evaluation engine — from an AST interpreter to a specialized bytecode virtual machine.🗞️Goodbye core types - Hello Go as we know and love it!: Go 1.25 removes the concept of “core types” from the language spec, replacing it with clearer, operation-specific rules.Rust🗞️Rust Additions For GCC 15 Bring Support For if-let Statements, Other Improvements: The version's Rust front-end (gccrs) now also supports Clone, and Copy derives, with upcoming support for PartialOrd and PartialEq.🗞️Fastrace: A Modern Approach to Distributed Tracing in Rust: This high-performance, zero-cost distributed tracing library for Rust integrates seamlessly with standard logging and supports automatic context propagation.Swift🗞️Introducing SwiftMCP: This open-source Swift macro framework turns documented Swift functions into AI-callable tools using Model Context Protocol, generating metadata, wrappers, and server integration with minimal setup.🎓SwiftUI TabView: Explained with Code Examples: Explains how to implement and customize tab-based navigation in SwiftUI using practical examples for both simple and advanced app structures.PHP🗞️Rusty string formatting in PHP: Introduces f, a PHP package inspired by Rust's format!() macros, offering cleaner, {} -based string formatting with support for positional, named, and padded placeholders.SQL🗞️SQLCritic: Correcting Text-to-SQL Generation via Clause-wise Critic: Proposes a novel method to improve text-to-SQL accuracy by evaluating and correcting generated SQL queries clause-by-clause using a critic model.Ruby📖Ruby, Ractors, and Lock-Free Data Structures: A comprehensive online resource authored by Ilya Bylich, focusing on concurrent data structures within the Ruby programming language.💡My Ruby Debugging Tips in 2025: Shares tips focussed on improved workflows using debug.gem, Ruby LSP, and integrations like Code Lens and RSpec support.Kotlin🗞️Kotlin bolsters K2 compiler plugin support, WebAssembly debugging: Kotlin 2.1.20’s enhancements to K2 compiler plugins make kapt default and improve Kotlin/Wasm debugging with DWARF support.💡Migration of an iOS/Android Application to Kotlin Multiplatform: Methodology and Key Steps: Recommends gradually shifting cross-cutting modules, data, business logic, and presentation layers to shared Kotlin code.🧠Expert Insight: From C++98 to C++23: The Arithmetic Mean, Benchmarked and Optimized📚Exploring the evolution of C++ through arithmetic mean calculations and performance analysis.by Ferenc-Lajos Deák, coauthor of Debunking C++ MythsAveraging algorithms are computational techniques used to determine the mean or average value of a set of numbers. They are widely used in machine learning (model optimization), signal processing (noise reduction), finance (trend analysis), and networking (traffic smoothing). Some common averaging algorithms include Arithmetic Mean (Simple Average), Moving Average (Sliding Window Average), Harmonic Mean, and Geometric Mean.In this article we will explore one of the most common averaging algorithms: the Arithmetic Mean, and its implementation in C++. We will explore how to compute the average of a vector using five different approaches, each corresponding to a major C++ standard, from C++98 to C++23. Additionally, we will benchmark these implementations to analyze their performance and efficiency. Finally, we will dig into the code generated by the two most used compilers on Linux platforms, GCC and Clang, and perform a thorough analysis and see which one comes out the winner.Readers will gain a deeper understanding of Practical C++ implementation across different standards: you will see how to compute the arithmetic mean of a vector using various C++ techniques and understand the evolution of the language from C++98 to C++23. You will also gain insights into optimizing code for performance, while keeping Modern C++ coding practices in mind and learn how they can be used to write efficient and readable code...Computing the Average: Five ApproachesLet us now delve into five versions of a function that calculates the average of a vector of random integers. Each version utilizes a different C++ standard, demonstrating how modern C++ simplifies and makes common programming tasks more readable, but before introducing them, here is the code that generates the vector:// Initialize random number generatorstd::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<int> value_dist(1, 100);// Generate random vectorstd::vector<int> numbers(50000);std::ranges::generate(numbers, [&]() { return value_dist(gen); });1. C++98: Classic for-loop ApproachIn C++98, we relied on manual iteration using a basicforloop:// C++98: Classic for-loop approachdouble average_cpp98(const std::vector<int>& numbers) { int sum = 0; for (size_t i = 0; i < numbers.size(); ++i) { sum += numbers[i]; } return static_cast<double>(sum) / numbers.size();}This approach was straightforward but lacked modern conveniences like range-based loops or built-in algorithms.2. C++11: Range-based LoopWith C++11, we gained access to range-based loops, making iteration more concise and readable:// C++11: Range-based loopdouble average_cpp11(const std::vector<int>& numbers) { int sum = 0; for (int num : numbers) { sum += num; } return static_cast<double>(sum) / numbers.size();}This improved readability by removing explicit indexing and is one of the many usability improvements introduced in C++11.3. C++14: Using std::accumulateC++14 introduced functional-style algorithms such as std::accumulate, which simplified summing the elements:// C++14: Using std::accumulatedouble average_cpp14(const std::vector<int>& numbers) { auto sum = std::accumulate(numbers.begin(), numbers.end(), 0); return static_cast<double>(sum) / numbers.size();}This approach is more declarative and eliminated the need for a loop. C++14 focused on minor refinements and usability improvements over C++11.4. C++17: Using std::reduceC++17 introducedstd::reduce, which is optimized for parallel execution:// C++17: Using std::reduce (supports parallel execution)double average_cpp17(const std::vector<int>& numbers) { int sum = std::reduce(std::execution::seq, numbers.begin(), numbers.end()); return static_cast<double>(sum) / numbers.size();}std::reduceprovides potential performance gains by allowing parallel execution when used withstd::execution::par. C++17 marked a shift towards greater use of parallelism and optimization in the Standard Library.👉 See the C++23 version, benchmark results, and which compiler comes out ahead in real-world performance tests.[Read the complete article →]Author Bio: Ferenc-Lajos Deák is a seasoned software developer with a strong foundation in mathematics and theoretical computer science, currently based in Trondheim, Norway. His career spans roles across diverse domains, including autonomous vehicles, real-time traffic systems, multimedia, and telecommunications. An avid open-source enthusiast, he maintains several live projectsand has authored more than a dozen articles for various technical publications, focusing on one of his passions: programming.His book Debunking C++ Myths coauthored alongside Alexandru Bolboaca, was published by Packt in December 2024.Get the eBook for $31.99$27.99🌟Advanced Concepts🚀Applying Flow Metrics to Design Resilient Microservices: Explains how flow metrics such as Work-in-Progress (WIP), age, cycle time, and throughput can be applied to microservices to detect and contain system congestion.AI Trends Disrupting Software Teams: Outlines five trends including generative development with code assistants and autonomous agents, AI-powered operations and observability, dynamic documentation, AI-integrated SaaS interfaces, and agentic systems for business automation.Hardware-Aware Coding: CPU Architecture Concepts Every Developer Should Know: Explains instruction pipelining, memory caching, and speculative execution using a drive-through analogy.Timescale architecture for real-time analytics: Explores how to build scalable, high-ingest, low-latency analytics apps using familiar SQL while gaining real-time insights over large time-series datasets.🛠️Useful Tools⚒️Lynx: An open-source framework that lets developers build native mobile and web apps using familiar web technologies, with high performance, Rust-based tooling, and cross-platform flexibility.Unvibe: A Python tool that uses AI to generate and refine code until it passes your unit tests, making it especially effective for large projects with good test coverage.STUMPY: A BSD-licensed, NumFOCUS-affiliated Python library for scalable time series analysis using matrix profiles, with support for docs, testing, and reproducibility.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 491

Divya Anne Selvaraj
20 Mar 2025
13 min read
Save for later

ProgrammingPro #94: Python Developer Tooling, Theia AI & IDE, Java 24’s Big Changes, and Diamond AI Code Reviewer

Divya Anne Selvaraj
20 Mar 2025
13 min read
Bite-sized actionable content, practical tutorials, and resources for programmers#94:Python Developer Tooling, Theia AI & IDE, Java 24’s Big Changes, and Diamond AI Code ReviewerLevel up your coding skills with the Python: From Beginner to Advanced Bundle by Packt. Learn to code and gain amazing insights from books like Learn Python Programming,Building AI Intensive Python Applications,Modern Time Series Forecasting with Python, and more. This library of 20+ programming books are perfect for novice coders and seasoned pros in growing your career. Plus, your purchase helps support the Python Software Foundation. Starting at US$1.Check out the Python Humble BundleHi ,Welcome to a brand new issue of ProgrammingPro.In today’s Expert Insight, we share an excerpt from our conversation with Fabrizio Romano, author of Learn Python Programming, Fourth Edition. He discusses Python’s strengths, limitations, evolving concurrency, AI-powered coding tools, and its future.News Highlights: Eclipse Foundation launches Theia AI and AI-powered Theia IDE; Java 24 launches with 24 new features, including generational GC and 32-bit x86 removal; Google’s Gemma 3, OpenAI’s Responses API, and Visual Studio's GPT-4o code completion debut; and Graphite unveils Diamond AI code reviewer.My top 5 picks from today’s learning resources:Python Developer Tooling Handbook📖Reverse Engineering OpenAI Code Execution to make it run C + JavaScript🔍Speeding up C++ code with template lambdas⚡Were multiple return values Go's biggest mistake?🤔Beyond Trends: A Practical Guide to Choosing the Right Message Broker📡But there’s more, so dive right in.Stay Awesome!Divya Anne SelvarajEditor-in-ChiefSign Up|Advertise🗞️News and Analysis🔎Eclipse Foundation unveils open source AI development tools: Theia AI (a customizable open-source AI integration framework) and an AI-powered Theia IDE (an AI-enhanced development environment), have been launched.Java 24 Delivers New Experimental and Many Final Features:Oracle has released Java 24 with 24 new features, including experimental generational garbage collection, and the removal of the Windows 32-bit x86 port and Security Manager.Mar 14, 2025: 10 AI updates from the past week: Updates include the release of Gemma 3 by google, launch of Responses API by OpenAI, availability of Boomi AI Studio and Visual Studio's GPT-4o code completion, and more.OpenSilver 3.2 Takes WPF Apps to Mobile with .NET MAUI Hybrid Integration: The open-source, WebAssembly-based reimplementation of the deprecated Microsoft Silverlight, now enables applications to run on mobile and desktop platforms while maintaining a single XAML/C# codebase.Graphite debuts Diamond AI code reviewer, insists “AI will never replace human code review”: The AI-powered code review tool detects bugs, style issues, and security vulnerabilities.GCC 15 compilers move toward completion: The version set for release in late April or early May, introduces a Cobol front end, defaults C compilation to C23, and adds C++23 and C++26 features.Oracle reveals five new features coming to Java: These include stable values (JDK 25), enhanced primitive boxing, null-restricted value classes, value classes and objects, and derived record creation.🎓Tutorials and Learning Resources💡Legend:🎓 Tutorial/Course | 💼 Case Study | 💡 Insight/Analysis | 📖Open Access BookPython📖Python Developer Tooling Handbook: A guide to navigating Python's development ecosystem, covering package management, linting, formatting, and dependency tools, structured using the Diátaxis framework with tutorials.💡Which Python GUI library should you use?: Compares Python GUI libraries available in 2025, evaluating their strengths, use cases, and licensing, with recommendations for different project types.For more Python resources, go to last week's PythonProC# and .NET🎓Delegates (C# Programming Guide): Covers the types' characteristics, usage, and related concepts like lambda expressions and multicast delegates.🎓Streamlining .NET 9 Deployment With GitHub Actions and Azure: Explains how to set up a CI/CD pipeline for .NET 9 applications using GitHub Actions and Azure App Service, covering automated builds, and more.🎓Neural Network Quantile Regression Using C#: Presents an end-to-end demonstration of neural network quantile regression in C#, explaining how to train a model that predicts numeric values with quantile-based confidence.C++ and C💡Speeding up C++ code with template lambdas: Explains different approaches, from basic template functions to C++20 template lambdas, and evaluates alternative strategies, including template metaprogramming.💡Polymorphic, Defaulted Equality: Uncovers the pitfalls of defaulted equality in polymorphic hierarchies and how to implement safe, efficient comparisons in C++.💡Stupid Smart Pointers in C: Introduces free_on_exit(), a function that automatically frees memory when a function returns by hijacking the return address using inline assemblyJava🎓Finding Java classes that are only used by tests: Explains how to identify and remove Java classes that are only referenced in tests by analyzing class dependencies, filtering test-only references, and systematically deleting unused code.💡Why Java endures: The foundation of modern enterprise development: Explores Java’s enduring relevance in enterprise development, highlighting its evolution, ecosystem, and adaptability to modern needs like AI.JavaScript and TypeScript💡Reverse Engineering OpenAI Code Execution to make it run C + JavaScript: Covers OpenAI’s code execution environment's secure sandbox structure, prompt injection vulnerabilities, and techniques to run C and JavaScript within the Python-based Jupyter kernel system.🎓Understanding DOM Node Types in JavaScript (With Examples!): ExplainsElement, Attribute, Text, Comment, Document, and Document Fragment nodes, with practical examples of their use.🎓Agentic TDD in Typescript with Minimal Dependencies: Demonstrates using an AI agent to iteratively generate and refine code until all tests pass, leveraging OpenAI’s SDK, Vitest, and Vite while minimizing dependencies.Go💡Were multiple return values Go's biggest mistake?: Critiques Go’s multiple return values, arguing that their lack of tuple support complicates error handling, concurrency, and generic abstractions, leading to unnecessary workarounds.💼My 6 months with the GoTH stack: Building front-ends with Go, HTML and a little duct tape: Reviews the author’s six-month experience using the GoTH stack (Go, Templ, Tailwind, and HTMX) highlighting its benefits and challenges.Rust💡Is Rust a good choice for business apps?: Argues that Rust is a poor choice for business applications due to its complex dependency ecosystem, strict borrow checker, painful async model, and higher development effort.📖The Embedded Rust Book: An introductory book about using the Rust Programming Language on "Bare Metal" embedded systems, such as Microcontrollers.Swift💡Behind the scenes of async functions: Explains how Swift Concurrency works internally, focusing on async functions, tasks, jobs, executors, and the Cooperative Thread Pool.SwiftUI Closures on the Main Thread: Why@MainActor Is a Game-Changer: Explains how @MainActor in SwiftUI ensures UI-related closures run on the main thread automatically, reducing the need for manual dispatching.PHP🎓Monitor HTTP Interactions with Laravel’s New Http::record() Method: Introduces Laravel’s new Http::record() method, which enables monitoring real HTTP requests without blocking them, making debugging, logging, and testing API interactions easier.SQL💡Think About SQL MERGE in Terms of a RIGHT JOIN: Demonstrating howthe SQL MERGE statement updates, inserts, or deletes records based on matching criteria between source and target tables.💡Optimizing Cloud SQL Memory Performance: An SRE’s Guide: Provides an SRE-focused guide to optimizing Cloud SQL memory performance, covering key memory metrics, their interpretation, and mitigation strategies.Ruby💡Ruby Debugging Tips and Recommendations in 2025: Provides updated Ruby debugging best practices for 2025, covering tools like Ruby LSP, debug.gem , and integration with IRB, along with configuration tips.Kotlin💡Using the Android Context and Manifest to Unveil the Android System Mechanics (2025 Edition): Explains how the Android Context and Manifest enable communication between applications and the Android system, manage app components, and facilitate inter-process communication.🧠Expert Insight: Exploring Python with Fabrizio Romano📚An author's insights on Python’s strengths, challenges, and futureExtracted from a converstation with Fabrizio Romano, co-author of Learn Python Programming, Fourth Edition.Fabrizio Romano, a seasoned software developer and author of Learn Python Programming (now in its fourth edition), has spent over a decade teaching Python. He has taught Python to professional software engineers and data students through collaborations with Oxford University and other institutions. In this part of the discussion, he shares his journey with Python, its strengths and limitations, and how the language continues to evolve.Discovering Python: A Journey from C# to SimplicityQ: What originally drew you to Python?Fabrizio: In the early 2000s, I was primarily working with C#, Java, and PHP. I also enjoyed competitive programming challenges in my spare time. On one of these platforms, I noticed another competitor using Python. His solutions were conceptually similar to mine but significantly more concise. That intrigued me—I decided to explore Python and was struck by its readability, indentation-based syntax, and expressive nature. What started as an experiment soon became a long-term professional relationship with the language.One of the platforms I used early on was Project Euler, which is heavily math-oriented. Solving problems with Python allowed me to learn its built-in data structures and understand which were optimal for different algorithms. Through these challenges, I developed a deep appreciation for Python’s efficiency and elegance.The Allure of Python: Why It Stands OutQ: Why would you recommend Python to new developers?Fabrizio: Python has a gentle learning curve, making it accessible to beginners. Its syntax is close to natural language, and its standard library and extensive third-party ecosystem reduce the need to reinvent the wheel. The language is also highly versatile, spanning web development, automation, machine learning, and more.Another key advantage is Python’s expressiveness. Compared to Java or C++, Python code is significantly shorter, allowing developers to focus on solving problems rather than dealing with verbose syntax. It also maintains consistency across different data structures. For example, regardless of the collection type, you can simply use len(collection) to get its size, eliminating inconsistencies found in other languages.Python is also backed by a strong global community, which means there is a vast amount of support available through documentation, tutorials, and open-source contributions. The ecosystem includes a wide range of tools that make development smoother, from testing frameworks to packaging solutions.Navigating Python’s LimitationsQ: Where does Python fall short?Fabrizio: Performance is often a consideration—while Python is flexible, it is not the fastest language. That’s why libraries like NumPy and TensorFlow, which handle computationally intensive tasks, are built in C. Python is also not ideal for mobile development. While frameworks like Kivy and BeeWare exist, native languages like Swift and Kotlin are better suited for mobile applications.Concurrency has traditionally been a challenge due to Python’s Global Interpreter Lock (GIL). However, Python 3.13 introduces an experimental free-threaded mode, signaling improvements in this area. Despite the GIL, many high-performance applications already circumvent these limitations using multiprocessing, async I/O, and JIT-compilation techniques.Additionally, while Python is widely used in back-end development, JavaScript and TypeScript still dominate the front-end space. That said, frameworks exist that allow Python to be used in front-end development by compiling into JavaScript, though it is still a translation layer rather than a native approach.The Role of AI in CodingQ: What are your thoughts on AI-powered coding assistants like GitHub Copilot?Fabrizio: AI tools are changing how developers write code. At Sohonet, we adopted GitHub Copilot across the team, and it has proven valuable in handling repetitive tasks and structuring code efficiently. It also helps developers by intelligently predicting test cases and speeding up refactoring.However, I caution against over-reliance on AI. Programming is not just about writing code—it’s about problem-solving and understanding logic. AI should be used to enhance productivity, not replace fundamental thinking skills. Developers should still challenge themselves with problems to keep their critical thinking skills sharp.Additionally, developers should be mindful of how AI suggestions influence their approach to coding. While AI can generate solutions, understanding why a particular approach is valid remains crucial. Developers should maintain a balance between leveraging AI’s speed and honing their own problem-solving skills.Looking AheadQ: How do you see Python evolving in the coming years?Fabrizio: Python continues to improve in performance, tooling, and concurrency management. The introduction of structural pattern matching, type annotations, and enhanced tooling like Black and Ruff simplifies development. Additionally, efforts to unify package management, such as the UV project, are making Python’s ecosystem more beginner-friendly.Python’s adaptability ensures it remains a dominant force across industries. With AI advancements and optimizations to the core language, it will continue to be a top choice for developers worldwide. The tooling around Python is also evolving—Jupyter Notebooks have revolutionized how we teach and document code, and deployment processes have been transformed by containerization and tools like Docker.Python’s strength lies in its ability to evolve while maintaining its core philosophy of simplicity and readability. As the ecosystem continues to grow, developers can expect even more powerful tools and streamlined workflows to enhance productivity.Author Bio:Fabrizio Romano holds a master’s degree in computer science engineering from the University of Padova and has been working as a professional software developer since 1999 and with Python since 2007. Today, he is the development manager of the Sohonet product development team.He gave talks at Europython (Berlin 2014, Bilbao 2015) and ProgSCon 2016, on the topics of teaching Python programmingto every employee of a whole company, and TDD and testing with Python. In 2022, he also collaborated with Oxford University, teaching Python to professional software engineers, and data science students. In his free time, he mostly enjoys playing the guitar and teaching meditation, maths, and Python programming.His book Learn Python Programming, Fourth Edition was published in November 2024.Buy along with the Humble Bundle for only $25!Get the eBook for $35.99$31.99🌟Advanced Concepts🚀Beyond Trends: A Practical Guide to Choosing the Right Message Broker: Examines key characteristics, such as ordering, throughput, auto-scaling, poison pill handling, and batch processing, and aligns them with common messaging patterns.The Hidden Burden of Architectural Decision Fatigue (And How to Fix It): Explains how to reduce architectural decision fatigue by implementing a structured decision-making process using an Architectural Decision Matrix and ADR.Four kinds of software: Categorizes software into four types—Control, Interactive, Streaming, and Computational—andexplores their architectural styles, design patterns, and implementation details.🛠️Useful Tools⚒️open_deep_research: An open-source AI assistant that automates research and report generation with customizable models, prompts, and search tools.build-your-own-x: A collection of guides for building technologies from scratch, aiding deep learning through hands-on projects.That’s all for today.We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most usefulhere.If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want toadvertise with us.If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, just respond to this email!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}}
Read more
  • 0
  • 0
  • 378