<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sushrut Mishra</title>
    <description>The latest articles on DEV Community by Sushrut Mishra (@sushrutkm).</description>
    <link>https://dev.to/sushrutkm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F648549%2F095d6e22-b5a9-4eaf-a1bf-8f46e02975f0.jpg</url>
      <title>DEV Community: Sushrut Mishra</title>
      <link>https://dev.to/sushrutkm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sushrutkm"/>
    <language>en</language>
    <item>
      <title>Claude Code got the architecture wrong (so we ran a controlled experiment to find out why)</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Tue, 17 Mar 2026 16:25:57 +0000</pubDate>
      <link>https://dev.to/sushrutkm/claude-code-got-the-architecture-wrong-so-we-ran-a-controlled-experiment-to-find-out-why-28p1</link>
      <guid>https://dev.to/sushrutkm/claude-code-got-the-architecture-wrong-so-we-ran-a-controlled-experiment-to-find-out-why-28p1</guid>
      <description>&lt;p&gt;If you have used Claude Code on a large codebase, you have probably felt this. The output compiles. The tests pass. But something feels off. The API surface is parallel to something that already exists. The approach is a workaround dressed up as an implementation. A senior engineer on your team would have done it differently. The instinct is to blame the model. The actual problem is something else entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding agents explore large codebases through trial and error
&lt;/h2&gt;

&lt;p&gt;Claude Code, Cursor, and every other coding agent navigates your codebase the same way: grep, glob, read files, repeat. On a small codebase this works well enough. On a codebase with millions of lines across thousands of files, this process produces a systematically incomplete picture.&lt;/p&gt;

&lt;p&gt;The agent makes the best architectural decision it can with what it found. When extension points exist but the agent never found them, it creates a parallel implementation instead of extending what already exists. When conventions exist but the agent never saw them, it writes code that a senior engineer would reject in review. The model is capable. The context is incomplete.&lt;/p&gt;

&lt;h2&gt;
  
  
  The experiment
&lt;/h2&gt;

&lt;p&gt;We ran a controlled test to measure exactly how much this matters. Same agent (Claude Code with Opus 4.6), same task, same codebase (Elasticsearch, 3.85 million lines of Java across 29,000+ files), one variable: whether Bito's AI Architect, a codebase intelligence layer that builds a knowledge graph of your entire system and exposes it to coding agents via MCP, was providing context or not.&lt;/p&gt;

&lt;p&gt;The task was implementing deterministic terms aggregation using the TPUT algorithm, a multi-phase distributed coordination problem that requires changes across Elasticsearch's entire search pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without AI Architect
&lt;/h3&gt;

&lt;p&gt;Claude Code concluded the framework could not support multi-round shard communication and built a workaround instead. It created a separate aggregation type that forces every shard to return all unique terms in a single pass. Technically functional. Severe memory risk on high-cardinality fields. Zero multi-shard tests. 6 files changed. And critically, not actually TPUT.&lt;/p&gt;

&lt;h3&gt;
  
  
  With AI Architect
&lt;/h3&gt;

&lt;p&gt;Claude Code understood exactly where to extend the pipeline, identified the correct integration point, followed Elasticsearch's own API conventions, and implemented genuine multi-phase TPUT with threshold computation, refinement rounds, and gap resolution. 27 files changed. Full test coverage across all coordination layers.&lt;br&gt;
Same agent. Same codebase. Completely different architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the gap exists
&lt;/h2&gt;

&lt;p&gt;The agent without context made a reasonable conclusion based on incomplete information. It explored a 3.85-million-line codebase without a map and missed the extension points entirely. That is not a failure of reasoning. It is a failure of information.&lt;/p&gt;

&lt;p&gt;AI Architect builds a knowledge graph of your entire codebase, mapping architecture, extension points, conventions, dependencies, and call graphs, and delivers that context to your coding agent before it writes a single line of code. The agent stops guessing and starts reasoning about your actual system.&lt;/p&gt;

&lt;p&gt;The difference in output reflects the difference in understanding. A 6-file workaround versus a 27-file production-grade implementation. Both came from the same model on the same day.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for your team
&lt;/h2&gt;

&lt;p&gt;Most engineering teams accept the 6-file version because they never saw the 27-file version was possible. The architectural shortcuts your coding agents take today are a direct reflection of what they understand about your codebase, and most of them understand very little.&lt;/p&gt;

&lt;p&gt;If your team is running Claude Code or Cursor on a large codebase, this experiment is worth reading in full. We published the complete side-by-side comparison, the layer-by-layer breakdown of what TPUT actually required, and links to both pull requests so you can read the code yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the full experiment:&lt;/strong&gt; &lt;a href="https://bito.ai/blog/tput-implementation-with-ai-architect/" rel="noopener noreferrer"&gt;The TPUT implementation Claude Code got wrong and AI Architect got right&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to connect AI Architect to your coding agent and run it on your own codebase, get started at &lt;a href="//bito.ai"&gt;bito.ai&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>learning</category>
    </item>
    <item>
      <title>How I got Cursor to write code that could actually ship</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Sun, 30 Nov 2025 08:34:12 +0000</pubDate>
      <link>https://dev.to/sushrutkm/how-i-got-cursor-to-write-code-that-could-actually-ship-16ei</link>
      <guid>https://dev.to/sushrutkm/how-i-got-cursor-to-write-code-that-could-actually-ship-16ei</guid>
      <description>&lt;p&gt;AI code generators write more code than ever, and they do it fast. Sahil Lavingia said it well in a recent tweet. If developers now produce five to ten times more code with AI, we need something that can review five to ten times more code too.&lt;/p&gt;

&lt;p&gt;That is the real problem. Tools like Cursor generate code that looks right but often contains small mistakes that only show up when the project runs. Wrong Prisma fields, missing checks, loose validation, repeated logic, or scripts that fail silently. None of this feels dramatic. It is just enough to slow you down or break production.&lt;/p&gt;

&lt;p&gt;I hit all of this while building an Express TypeScript API. Cursor helped me create the project fast, then I spent real time fixing the parts it got wrong. That is when the pattern became clear. AI code generation is not the bottleneck anymore. Code review is.&lt;/p&gt;

&lt;p&gt;The only way to keep up is to bring AI into the review step, not just the generation step.&lt;/p&gt;

&lt;p&gt;The rest of this post walks through how that played out in my project, what went wrong, and how AI code review solved the gap Cursor left. I will talk about the tool I used later in the post.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project I used to test this
&lt;/h2&gt;

&lt;p&gt;I used an Express TypeScript API that handled auth, user management, Prisma, JWT, validation middleware, and a few automation scripts. It had routes, controllers, types, a Prisma schema, and a small shell toolchain for creating pull requests through the GitHub API.&lt;/p&gt;

&lt;p&gt;Everything tied together.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The DTOs shaped the request data.&lt;/li&gt;
&lt;li&gt;The controllers expected those shapes.&lt;/li&gt;
&lt;li&gt;The Prisma model enforced its own contract.&lt;/li&gt;
&lt;li&gt;The middleware ran checks before the handlers.&lt;/li&gt;
&lt;li&gt;The scripts needed correct error handling and clean parsing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That structure made it clear when something went wrong. If Cursor guessed a field name, the query failed. If it added logic in the wrong layer, the flow broke. If it skipped error checks in the scripts, automation stopped working.&lt;/p&gt;

&lt;p&gt;This project gave me a clear view into where AI generated code drifts from the actual codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Cursor started breaking things
&lt;/h2&gt;

&lt;p&gt;When I asked Cursor to generate code for this project, the gaps showed up fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  It used wrong field names in Prisma queries
&lt;/h3&gt;

&lt;p&gt;Cursor produced queries with fields that did not exist in the Prisma schema. The handlers failed as soon as they hit the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  It placed validation in the wrong layer
&lt;/h3&gt;

&lt;p&gt;I already had middleware for input checks. Cursor added the same checks inside controllers, which created duplication and forced updates in two places.&lt;/p&gt;

&lt;h3&gt;
  
  
  It drifted from the actual DTOs
&lt;/h3&gt;

&lt;p&gt;Some controllers expected request shapes that did not match the DTO definitions. TypeScript let a few of these slip through because the structures looked close enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  It skipped error handling in bash scripts
&lt;/h3&gt;

&lt;p&gt;The pull request scripts used curl and git commands with no exit code checks. If an API call failed, the script continued as if nothing happened.&lt;/p&gt;

&lt;h3&gt;
  
  
  It parsed JSON in fragile ways
&lt;/h3&gt;

&lt;p&gt;Cursor relied on grep and cut to extract fields from GitHub responses. That approach broke as soon as the response shape changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  It exposed the GitHub token
&lt;/h3&gt;

&lt;p&gt;One script printed the token to the terminal. That leaked it to shell history and anyone watching the screen.&lt;/p&gt;

&lt;p&gt;...and many more.&lt;/p&gt;

&lt;p&gt;All of this came from a simple pattern. Cursor generated each file on its own, while the project depended on consistent behavior across routes, controllers, models, middleware, and scripts. Once the pieces drifted, problems stacked up.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AI code review filled the gap
&lt;/h2&gt;

&lt;p&gt;Cursor generated large chunks of this project fast, but it introduced inconsistencies across files. To keep the codebase stable, I needed something that reviewed the entire diff, not just the file I was currently editing.&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://bito.ai/" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; for this. The review on PR #1 in the repo showed exactly why this layer is required. Here are the concrete issues Bito surfaced in that pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Incorrect assumptions about project flow
&lt;/h3&gt;

&lt;p&gt;Bito traced the request path across files and produced an interaction diagram. It showed the exact flow:&lt;/p&gt;

&lt;p&gt;Client → Express App → Route Handler → ValidationMiddleware → AuthController → Database → Response.&lt;/p&gt;

&lt;p&gt;Cursor did not maintain this order. Bito caught cases where Cursor placed logic in the wrong layer or duplicated it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Duplicate validation across middleware and controllers
&lt;/h3&gt;

&lt;p&gt;In authRoutes.ts, Cursor generated:&lt;/p&gt;

&lt;p&gt;router.post('/register', register);&lt;br&gt;
router.post('/register', validateRegister, register);&lt;/p&gt;

&lt;p&gt;Same for login.&lt;br&gt;
Bito flagged these as duplicate routes and pointed out that the controller still performed its own validation.&lt;br&gt;
It specifically referenced the sections in validation.middleware.ts (lines 10–50) and authController.ts (lines 11–26).&lt;br&gt;
This was not a style preference. It broke the request flow and doubled maintenance work.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Prisma field and type drift
&lt;/h3&gt;

&lt;p&gt;Cursor produced controller logic that assumed certain fields existed. In the PR review, Bito cross-checked controller usage with schema.prisma and flagged mismatches in user lookup and update logic.&lt;br&gt;
Cursor did not verify the fields across files. Bito did.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Missing branch checks and error handling in bash scripts
&lt;/h3&gt;

&lt;p&gt;The automation scripts were the worst offenders.&lt;br&gt;
For example, in push-and-create-prs.sh:&lt;/p&gt;

&lt;p&gt;git push -u origin main&lt;/p&gt;

&lt;p&gt;Cursor wrote this with zero checks.&lt;br&gt;
Bito flagged:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no error handling&lt;/li&gt;
&lt;li&gt;no branch existence check&lt;/li&gt;
&lt;li&gt;no exit status fallback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It suggested explicit guards, such as verifying refs/heads/branch-a before checkout and returning a non-zero exit code if the push fails.&lt;/p&gt;

&lt;p&gt;This tightened the entire CI path.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Unreliable JSON parsing
&lt;/h3&gt;

&lt;p&gt;Cursor parsed GitHub API responses with grep and cut, for example:&lt;/p&gt;

&lt;p&gt;echo "$RESPONSE_A" | grep -o '"html_url":"[^"]*' | cut -d'"' -f4&lt;/p&gt;

&lt;p&gt;This breaks on any format change.&lt;br&gt;
Bito called this out directly in the PR and recommended using structured parsing (jq) or capturing HTTP status codes first.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Token exposure in interactive scripts
&lt;/h3&gt;

&lt;p&gt;In create-prs-now.sh, Cursor prompted for token input like this:&lt;/p&gt;

&lt;p&gt;read -p "Enter your GitHub token: " GITHUB_TOKEN&lt;/p&gt;

&lt;p&gt;This prints the token in plain text and stores it in shell history.&lt;br&gt;
Bito flagged this as a security issue and suggested:&lt;/p&gt;

&lt;p&gt;using read -s to hide input&lt;/p&gt;

&lt;p&gt;validating token prefix&lt;/p&gt;

&lt;p&gt;avoiding echo statements that leak secrets&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Missing exit codes for automation reliability
&lt;/h3&gt;

&lt;p&gt;Cursor ended the script with:&lt;/p&gt;

&lt;p&gt;echo "Done!"&lt;/p&gt;

&lt;p&gt;No exit status.&lt;br&gt;
CI cannot detect failures without exit codes.&lt;br&gt;
Bito explained why exit codes matter and gave an explicit fix:&lt;/p&gt;

&lt;p&gt;if [ ! -z "$PR_URL_A" ] &amp;amp;&amp;amp; [ ! -z "$PR_URL_B" ] &amp;amp;&amp;amp; [ ! -z "$PR_URL_C" ]; then&lt;br&gt;
    exit 0&lt;br&gt;
else&lt;br&gt;
    exit 1&lt;br&gt;
fi&lt;/p&gt;

&lt;p&gt;This alone prevents silent deployment failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Repeated code that violated DRY
&lt;/h3&gt;

&lt;p&gt;In create-prs-automated.sh, Cursor duplicated the entire PR creation block three times.&lt;br&gt;
Bito highlighted the repetition and suggested extracting a reusable function.&lt;br&gt;
Cursor rarely attempts global refactors on its own.&lt;br&gt;
Bito is designed to detect them because it reviews the diff holistically.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Cross-file consistency issues
&lt;/h3&gt;

&lt;p&gt;This was the biggest win.&lt;br&gt;
Bito reviewed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authRoutes.ts&lt;/li&gt;
&lt;li&gt;validation.middleware.ts&lt;/li&gt;
&lt;li&gt;authController.ts&lt;/li&gt;
&lt;li&gt;userRoutes.ts&lt;/li&gt;
&lt;li&gt;userController.ts&lt;/li&gt;
&lt;li&gt;all four bash scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cursor did not track how these pieces interacted.&lt;br&gt;
Bito cross-referenced them.&lt;br&gt;
This prevented logic drift across layers.&lt;/p&gt;

&lt;p&gt;All of this came from one insight. Cursor can write code fast. It cannot guarantee consistency across the entire project. AI code review filled that gap in a measurable, concrete way, and the PR made that clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow that produced code I could ship
&lt;/h2&gt;

&lt;p&gt;Once I saw how Cursor and Bito behaved on the same project, I locked in a workflow that kept speed and removed breakage. The sequence is simple, but every step matters.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Generate code with the Cursor in small steps
&lt;/h4&gt;

&lt;p&gt;I stopped asking Cursor to create large chunks at once. I asked for one file or one change at a time. This reduced cross-file drift and made each review cycle easier to reason about.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Run Bito inside the IDE immediately after each change
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://bito.ai/product/ai-code-review-agent-ide/" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; reviewed the updated file in the context of the full codebase.&lt;br&gt;
If a controller referenced the wrong field, Bito pointed back to the Prisma model.&lt;br&gt;
If the change introduced duplicated validation or unnecessary checks, Bito flagged both spots.&lt;br&gt;
If a script skipped exit code checks, the review highlighted the exact line.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Fix the issues while the context is fresh
&lt;/h4&gt;

&lt;p&gt;I applied the suggestions right away.&lt;br&gt;
If the issue required refactoring, I asked Cursor for a targeted fix. For example, if Bito flagged repeated PR creation blocks, I asked Cursor to extract a function and replaced the duplicates.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Open a pull request and run &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; again on the full diff
&lt;/h4&gt;

&lt;p&gt;This is where most AI generated code breaks. Single-file checks miss cross-file inconsistencies.&lt;br&gt;
In the PR review for this project, Bito identified duplicate register and login routes, repeated validation in controllers, missing error handling across scripts, fragile JSON parsing, and token exposure.&lt;br&gt;
The second review pass ensured nothing slipped into the main.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Merge only when the review produced zero high-risk issues
&lt;/h4&gt;

&lt;p&gt;Once Bito showed a clean review, I merged the PR.&lt;br&gt;
This kept the repo stable while still letting Cursor generate large amounts of code.&lt;/p&gt;

&lt;p&gt;This loop removed the guesswork. Cursor handled generation. Bito handled cross-file review. Together, they gave me a development flow where the output moved fast and stayed consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI helps you write more code, but it also adds more chances to slip. I saw that every time Cursor moved faster than the rest of the project could keep up. Once I added AI code review, the whole workflow settled. The code lined up across files, the scripts stopped failing in silence, and I spent less time chasing small errors.&lt;/p&gt;

&lt;p&gt;If you use AI to generate code, pair it with an AI reviewer. Do not rely on one without the other. I use Bito for this, and it has saved me a lot of cleanup time. Try any AI code review tool you trust, but use one. It makes the entire process far more stable.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>code</category>
      <category>ai</category>
    </item>
    <item>
      <title>Code Smells Explained: Common Patterns to Watch Out For</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Thu, 25 Sep 2025 12:00:01 +0000</pubDate>
      <link>https://dev.to/sushrutkm/code-smells-explained-common-patterns-to-watch-out-for-28ah</link>
      <guid>https://dev.to/sushrutkm/code-smells-explained-common-patterns-to-watch-out-for-28ah</guid>
      <description>&lt;p&gt;I spend a lot of time at &lt;a href="https://bito.ai" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; running AI code reviews, both on my own projects and with the team. &lt;/p&gt;

&lt;p&gt;Over time, I started noticing a pattern. The reviews weren’t just pointing out syntax issues or missing tests. They kept surfacing something subtler — code smells.&lt;/p&gt;

&lt;p&gt;At first, I didn’t think much of it. If the code compiles and the feature works, isn’t that good enough? But the more I worked with smelly code, the more I realized how quickly it drags you down. &lt;/p&gt;

&lt;p&gt;You open a file and suddenly it takes 20 minutes just to understand what’s happening. You go to fix a bug, and you’re scared to touch anything because one change might break five other things. You hand it off to a teammate, and they look at you like you just cursed them.&lt;/p&gt;

&lt;p&gt;That’s when it clicked for me: code smells are not bugs, but they’re warning signs. Ignore them, and you end up buried in technical debt. Spot them early, and you save yourself a lot of pain later.&lt;/p&gt;

&lt;p&gt;Since I keep running into this during AI code reviews, I thought I’d put together some thoughts on what code smells are, the ones that show up the most, and a few practical ways to deal with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Code Smells Matter
&lt;/h2&gt;

&lt;p&gt;Code smells are easy to ignore in the beginning. The program runs, tests pass, and everything looks fine on the surface. But over time, those small issues start to grow.&lt;/p&gt;

&lt;p&gt;A long function becomes harder to follow each time someone adds a new condition. A giant class turns into a dumping ground where nobody remembers what belongs where. Copy-pasted logic means fixing one bug in three different places.&lt;/p&gt;

&lt;p&gt;The problem isn’t that the code stops working. The problem is that it slowly becomes harder to read, harder to test, and harder to change without breaking something else. This is how technical debt sneaks in.&lt;/p&gt;

&lt;p&gt;I’ve seen it firsthand during reviews. A piece of code that seemed “good enough” in the beginning later took twice as long to debug because the design had rotted. If you work in a team, it also slows everyone else down, because they need to untangle the mess before they can even start adding new features.&lt;/p&gt;

&lt;p&gt;That is why code smells matter. They are not just about clean code for the sake of clean code. They are about saving yourself and your team from pain later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Most Common Code Smell Patterns
&lt;/h2&gt;

&lt;p&gt;Over time you start to notice the same kinds of smells showing up again and again. They look different in every codebase, but the patterns are surprisingly common. Here are a few that stand out the most.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long Methods
&lt;/h3&gt;

&lt;p&gt;Long methods make it hard to follow logic, and hard to test. Break them into small functions that do one thing.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function processOrder(order) {
  // validate
  if (!order.id || !order.items) throw new Error('invalid')
  // calculate totals
  let subtotal = 0
  for (const item of order.items) {
    subtotal += item.price * item.qty
  }
  let tax = subtotal * 0.08
  // apply discounts
  if (order.coupon) {
    subtotal -= order.coupon.amount
  }
  // build payload
  const payload = { id: order.id, total: subtotal + tax }
  // send to billing
  sendToBilling(payload)
  // notify user
  sendEmail(order.userEmail, 'order processed')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function validateOrder(order) {
  if (!order.id || !order.items) throw new Error('invalid')
}

function calculateTotal(items, coupon) {
  let subtotal = 0
  for (const item of items) subtotal += item.price * item.qty
  if (coupon) subtotal -= coupon.amount
  const tax = subtotal * 0.08
  return subtotal + tax
}

function processOrder(order) {
  validateOrder(order)
  const total = calculateTotal(order.items, order.coupon)
  sendToBilling({ id: order.id, total })
  sendEmail(order.userEmail, 'order processed')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Duplicate Code
&lt;/h3&gt;

&lt;p&gt;Duplicate logic causes multiple fixes. Extract shared code once, then reuse it.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createAdminUser(data) {
  const user = {
    name: data.name,
    email: data.email,
    role: 'admin',
    createdAt: new Date()
  }
  saveUser(user)
}

function createGuestUser(data) {
  const user = {
    name: data.name,
    email: data.email,
    role: 'guest',
    createdAt: new Date()
  }
  saveUser(user)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function buildUser(data, role) {
  return {
    name: data.name,
    email: data.email,
    role,
    createdAt: new Date()
  }
}

function createAdminUser(data) {
  saveUser(buildUser(data, 'admin'))
}

function createGuestUser(data) {
  saveUser(buildUser(data, 'guest'))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Large Classes (God Objects)
&lt;/h3&gt;

&lt;p&gt;A class with many responsibilities becomes hard to change. Split responsibilities into focused classes.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class OrderService {
  constructor(db) { this.db = db }

  createOrder(data) { /* validate, calculate, save, notify */ }
  calculateTotals(items) { /* lots of logic */ }
  sendInvoice(order) { /* email logic */ }
  exportOrdersCsv() { /* file logic */ }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class OrderCalculator {
  calculate(items, coupon) { /* totals logic */ }
}

class OrderRepository {
  constructor(db) { this.db = db }
  save(order) { /* db save */ }
}

class OrderNotifier {
  sendInvoice(order) { /* email logic */ }
}

class OrderService {
  constructor(calc, repo, notifier) {
    this.calc = calc
    this.repo = repo
    this.notifier = notifier
  }

  createOrder(data) {
    const total = this.calc.calculate(data.items, data.coupon)
    const order = { ...data, total }
    this.repo.save(order)
    this.notifier.sendInvoice(order)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Primitive Obsession
&lt;/h3&gt;

&lt;p&gt;Passing raw primitives hides intent, and it makes validation and behavior scattered. Create small types or objects.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createUser(name, email, addressLine1, addressLine2, city, zip) {
  const user = { name, email, addressLine1, addressLine2, city, zip }
  saveUser(user)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function buildAddress(line1, line2, city, zip) {
  return { line1, line2, city, zip }
}

function createUser(name, email, address) {
  const user = { name, email, address }
  saveUser(user)
}

// usage
const addr = buildAddress('123 St', '', 'Pune', '411001')
createUser('Asha', 'asha@example.com', addr)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Feature Envy
&lt;/h3&gt;

&lt;p&gt;When a method reaches into another object to pull data, the logic likely belongs closer to that data. Move behavior to the right place.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class OrderFormatter {
  format(order) {
    return `${order.user.firstName} ${order.user.lastName} placed order ${order.id}`
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }

  fullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

class OrderFormatter {
  format(order) {
    return `${order.user.fullName()} placed order ${order.id}`
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Clumps
&lt;/h3&gt;

&lt;p&gt;If the same group of values travels together, pack them into an object. This reduces errors and clarifies intent.&lt;/p&gt;

&lt;p&gt;Smell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function scheduleMeeting(title, startDate, endDate, organizerName, organizerEmail) {
  // lots of params passed around
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function scheduleMeeting(title, range, organizer) {
  // range is { startDate, endDate }
  // organizer is { name, email }
}

const range = { startDate: '2025-09-01', endDate: '2025-09-01' }
const organizer = { name: 'Sam', email: 'sam@example.com' }
scheduleMeeting('sync', range, organizer)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Spot Code Smells in Practice
&lt;/h2&gt;

&lt;p&gt;Code smells are tricky because they do not break your build or throw an error. The code still runs, which makes it easy to miss them. But once you know what to look for, they start standing out everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Peer reviews and pair programming
&lt;/h3&gt;

&lt;p&gt;Having another set of eyes on your code helps a lot. A teammate who has not been staring at the same file for hours will quickly notice when a method is too long, a class is too heavy, or logic feels out of place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated tools
&lt;/h3&gt;

&lt;p&gt;Linters and static analysis tools can catch certain smells, like duplicate code or unused variables. AI code review tools go a step further and point out design-level issues that humans might overlook during a busy sprint. This is something I see every day using Bito. Our blog on &lt;a href="https://bito.ai/blog/code-smell-detection/" rel="noopener noreferrer"&gt;code smell detection&lt;/a&gt; goes deeper into how AI reviews help spot these patterns early.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your gut feeling as a developer
&lt;/h3&gt;

&lt;p&gt;Sometimes you just know something smells off. If you have to scroll too much, pass around too many parameters, or write the same code twice, that is usually a sign. Trust that feeling and take a closer look.&lt;/p&gt;

&lt;p&gt;The goal is not to obsess over every small thing, but to develop awareness. Once you can recognize these signals, you can choose which ones are worth fixing now and which can wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Fix vs When to Let Go
&lt;/h2&gt;

&lt;p&gt;One of the hardest parts of dealing with code smells is knowing when to act. Not every smell deserves your attention right away. Some are harmless quirks, while others will slow your team down if you leave them alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix right away
&lt;/h3&gt;

&lt;p&gt;If a code smell is blocking readability, slowing down debugging, or creating duplicate logic, it is usually worth fixing on the spot. For example, a long method that you are already editing is the perfect candidate for a quick cleanup. Small changes made in context are the easiest wins.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let it go (for now)
&lt;/h3&gt;

&lt;p&gt;If the code works, is rarely touched, and nobody is struggling with it, you might not need to refactor immediately. A messy utility function that runs once a month is not as urgent as a controller that every developer touches daily.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Boy Scout Rule
&lt;/h3&gt;

&lt;p&gt;A good way to balance this is to follow the Boy Scout Rule: leave the code cleaner than you found it. If you touch a file for a new feature or a bug fix, take a moment to clean up the worst smells while you are in there. Over time, the whole codebase improves without big refactor projects.&lt;/p&gt;

&lt;p&gt;The real skill is not fixing everything, but knowing what to fix now and what to leave alone. That discipline saves you from wasting time while still keeping the codebase healthy.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>codesmell</category>
      <category>programming</category>
    </item>
    <item>
      <title>Will AI Replace Developers?</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Mon, 18 Aug 2025 04:08:35 +0000</pubDate>
      <link>https://dev.to/sushrutkm/will-ai-replace-developers-340e</link>
      <guid>https://dev.to/sushrutkm/will-ai-replace-developers-340e</guid>
      <description>&lt;p&gt;I wrote code full time for two years, then switched to marketing because I liked telling the story behind the product more than shipping the product itself. I’m not a developer anymore, but a question I come across every day is: “Will AI replace developers?” &lt;/p&gt;

&lt;p&gt;Since ChatGPT and Copilot blew up, every other message in my inbox is the same question. It is a fair worry. Tools can now spit out a React component or a Python script in a single prompt. That feels radical if you last checked in on AI back when autocomplete meant guessing the next three letters. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why you should listen to me?
&lt;/h3&gt;

&lt;p&gt;Because I have lived on both sides of the screen. I have shipped features, and I have sold them. The short answer from where I sit is no, AI is not walking into your stand-up and taking your laptop. &lt;/p&gt;

&lt;p&gt;The longer answer is that the job is changing in real time. The keyboard work that used to eat a morning now takes minutes, and the skills that keep you valuable are moving up the stack toward architecture, review, and product sense. &lt;/p&gt;

&lt;p&gt;This post breaks down why that shift is happening, what the big studies and forums really say, and what you should do now to stay ahead. Plus a quick note on how an AI code review layer like Bito fits into the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will AI really replace software engineers? What the numbers show:
&lt;/h2&gt;

&lt;p&gt;I skimmed the biggest studies and news pieces to see if the chatter lines up with reality. The &lt;a href="https://www.coursera.org/articles/will-ai-replace-programmers" rel="noopener noreferrer"&gt;Coursera&lt;/a&gt; deep dive on the question “Will AI replace developers” lands on a clear answer:  &lt;/p&gt;

&lt;p&gt;AI tools handle routine chores, yet they still lean on human skill for design, security, and new ideas. A full handoff is not coming any time soon. &lt;/p&gt;

&lt;p&gt;Another signal comes from the GitHub Copilot lab trial. Developers who used the tool finished a standard JavaScript task 55.8% faster, yet nothing in the paper hints at removing the human role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F030rlgjvr82jde2xf0hv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F030rlgjvr82jde2xf0hv.png" alt="Copilot stats" width="800" height="785"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fear still shows up in surveys. An Evans Data poll highlighted by &lt;a href="https://www.computerworld.com/article/1659019/one-in-three-developers-fear-ai-will-replace-them-2.html?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Computerworld&lt;/a&gt; found that 29% of engineers worry they could be replaced by AI one day. That number is real, but the same article notes broader concerns about platforms going obsolete, which reminds me that tech anxiety is nothing new.  &lt;/p&gt;

&lt;p&gt;The bottom line so far: research shows AI boosts throughput, articles warn about limits, and a slice of developers stays nervous, but none of the evidence says the job itself is disappearing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer tasks that AI already handles well
&lt;/h2&gt;

&lt;p&gt;AI tools shine in the repetitive layer of software development. Automated code generation, static analysis, and predictive analytics are no longer science fiction.  &lt;/p&gt;

&lt;p&gt;Here is where they save the most time right now: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Boilerplate and docstring generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paste a prompt, get a clean class with constructors, getters, setters, and clear docstrings. Tools like Cursor or Copilot cut the grunt work so you focus on the core logic. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI code review and quick bug fixes&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;AI code review tools today scan your code in seconds. I’m biased here but Bito does this with a private local index, leaves inline suggestions on style, security, and logic, and links to docs for a quick fix.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;Bito’s AI Code Review Agent&lt;/a&gt; plugs into GitHub, GitLab, Bitbucket, and your IDE (coming soon), posts comments like a real teammate, and learns from each review. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Timeline estimation from commit history&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feed past commits into a model and you get shipping dates that beat gut instinct. The algorithm maps similar tickets, crunches cycle times, and offers a realistic delivery window, boosting project planning accuracy and developer productivity. &lt;/p&gt;

&lt;p&gt;I may be thinking way ahead, but this is already a reality not too far from 2025. &lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI still falls short
&lt;/h2&gt;

&lt;p&gt;Large language models feel impressive in a demo, yet they still miss key parts of real software development work. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. New algorithms and greenfield design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ask the model to combine two known patterns and it shines, ask it to build a data structure for an unseen edge case and it stalls. Creative problem-solving still sits with the engineer who understands both the codebase and the customer need. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Hallucinated code that compiles but breaks in production&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The model predicts tokens, it does not reason about runtime state. I have seen a neat looking fix that passes the tests, only to leak memory on day one in prod. Someone must read the output, trace the path, and prove it safe. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Security, IP, and data leaks&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.coursera.org/articles/will-ai-replace-programmers" rel="noopener noreferrer"&gt;Coursera&lt;/a&gt; flags a risk most hype posts skip. Models can repeat licensed snippets or suggest logic that opens a door for attackers. Teams have to run checks, scrub prompts, and own the final call on what ships.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real numbers on productivity
&lt;/h3&gt;

&lt;p&gt;A controlled experiment on GitHub Copilot (&lt;a href="https://arxiv.org/abs/2302.06590" rel="noopener noreferrer"&gt;arXiv&lt;/a&gt;) asked professional developers to build an HTTP server in JavaScript. Those with Copilot finished the task 55.8% faster than the control group. Speed jumped, but every participant still wrote tests, reviewed diffs, and approved the merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade kit for today’s coder
&lt;/h2&gt;

&lt;p&gt;I no longer push code to production, yet I still speak with dev teams every week. The fastest teams I see have three habits in common. If you write software for a living, stack these on top of whatever you already do. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Sharpen your prompt craft&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Save prompt templates the same way you save bash aliases. Each template holds three parts: short context, exact task, and required output format. The clearer the prompt, the fewer edits you make later. &lt;/p&gt;

&lt;p&gt;Test each prompt at least a dozen times. Use &lt;a href="//cursor.ai"&gt;Cursor&lt;/a&gt;, &lt;a href="//windsurf.ai"&gt;Windsurf&lt;/a&gt;, or Copilot and see what works for you. I bet you use VS Code as your IDE. But my recommendation is to find an AI IDE alternative for VS Code. Use AI, code fast, grow faster. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Keep computer-science basics tight&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data structures, algorithmic thinking, and solid design patterns let you judge AI output on sight. When a model suggests a quadratic loop on a hot path, you swap in a hashmap without blinking. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Run an AI code-review layer before peer review&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bito’s AI Code Review Agent drops straight into GitHub, GitLab, and Bitbucket (coming to IDE soon). One click and it indexes the whole repository with abstract syntax trees and vector embeddings, so every comment arrives in proper context.  &lt;/p&gt;

&lt;p&gt;It posts a pull-request summary, flags security issues, suggests test cases, and offers one-click fixes. It also offers incremental reviews. That means Bito scans only new commits, and its changelist view highlights the files you really need to open.  &lt;/p&gt;

&lt;p&gt;Bito is SOC 2 Type II certified, it doesn’t store your code, and offers &lt;a href="https://bito.ai/blog/secure-code-review-process/" rel="noopener noreferrer"&gt;secure code reviews&lt;/a&gt;. You can run it in the cloud or on-prem.  &lt;/p&gt;

&lt;p&gt;My favorite feature is &lt;a href="https://bito.ai/blog/custom-guidelines/" rel="noopener noreferrer"&gt;Custom Review Guidelines&lt;/a&gt;. This feature is built for teams with specific code review standards. Whether you follow internal naming conventions, prefer a certain formatting style, or want the agent to avoid flagging certain patterns, you can now set all that yourself.  &lt;/p&gt;

&lt;p&gt;You can add general rules or rules for specific languages. You can use a template or write everything from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I wrote code for two years before I crossed the hall into marketing, and that switch taught me something useful for anyone still in the editor. Your real worth was never the lines you typed per day, it was the way you solve problems and guide a product from idea to release.  &lt;/p&gt;

&lt;p&gt;The new wave of AI tools, from Copilot to Bito’s AI code review agent, just makes that truth louder. They sweep up boilerplate, spot bugs, and keep a steady eye on security, which means you have more room for architecture decisions, performance trade-offs, and, yes, the occasional late night inspiration that a model cannot fake. &lt;/p&gt;

&lt;p&gt;So the next time someone asks, Will AI replace developers, tell them it is already replacing the boring parts. The thinking parts, the bits that need context and judgment, are still yours.  &lt;/p&gt;

&lt;p&gt;Use the tools, direct them with clear prompts, and keep your fundamentals sharp. That is how you stay ahead and how the craft moves forward. &lt;/p&gt;

</description>
      <category>code</category>
      <category>ai</category>
      <category>codereview</category>
    </item>
    <item>
      <title>AI Code Reviews: My 150-Day Experience</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Tue, 08 Jul 2025 08:04:46 +0000</pubDate>
      <link>https://dev.to/sushrutkm/ai-code-reviews-my-150-day-experience-4l79</link>
      <guid>https://dev.to/sushrutkm/ai-code-reviews-my-150-day-experience-4l79</guid>
      <description>&lt;p&gt;In 2021, I was deep in Salesforce development, reviewing pull requests, fixing edge cases, and trying to ship clean code. &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;AI code reviews&lt;/a&gt; weren’t a thing back then.  &lt;/p&gt;

&lt;p&gt;A few years ago, code reviews meant reading every line closely, juggling context across files, bugging other developers for explainers, and dropping comments that often went unnoticed. &lt;/p&gt;

&lt;p&gt;Then in 2025, I joined &lt;a href="//bito.ai"&gt;Bito.ai&lt;/a&gt;. It’s been more than 5 months, and I’ve been using Bito’s &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;AI Code Review Agent&lt;/a&gt; on real pull requests.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why I chose to work with Bito
&lt;/h2&gt;

&lt;p&gt;I came across Amar Goel, Bito’s cofounder and CEO, while I was working in technical writing and developer marketing. We started talking, and he shared what they were building. An AI agent that reviews pull requests in GitHub without storing your code. &lt;/p&gt;

&lt;p&gt;That felt so cool. I kept thinking about 2021.  &lt;/p&gt;

&lt;p&gt;Back then, every pull request I opened meant asking teammates to review logic, naming, structure, and edge cases. It took time, added friction, and sometimes, things slipped through. &lt;/p&gt;

&lt;p&gt;The idea of getting instant, contextual suggestions inside a PR, without giving up your code, felt like something I would have wanted as a developer. It made sense, felt practical. It felt like something made for how developers actually work. &lt;/p&gt;

&lt;p&gt;I joined Bito shortly after.  &lt;/p&gt;

&lt;p&gt;This post is the result of 150 days working with Bito and using the AI Code Review Agent on my own code. Every example I share here comes from that experience. &lt;/p&gt;

&lt;h2&gt;
  
  
  AI in pull requests: What changed for me?
&lt;/h2&gt;

&lt;p&gt;Back in 2021, most of my pull request reviews used to follow the same pattern. I would open the diff, scroll through my changes, and try to catch anything that felt off.  &lt;/p&gt;

&lt;p&gt;Sometimes I would miss things. Sometimes I would forget what I was thinking when I wrote the logic in the first place. &lt;/p&gt;

&lt;p&gt;Once I started using &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;Bito’s AI Code Review Agent&lt;/a&gt;, I noticed the difference right away.  &lt;/p&gt;

&lt;p&gt;The AI-generated comments showed up directly in the pull request.  &lt;/p&gt;

&lt;p&gt;They pointed out specific lines and explained why something could be improved. &lt;/p&gt;

&lt;p&gt;The suggestions were clear. If a function was too long or a condition could be simplified, the agent said so. &lt;/p&gt;

&lt;p&gt;If I reused a pattern that could be abstracted, it highlighted that too.  &lt;/p&gt;

&lt;p&gt;I did not need to change how I reviewed pull requests. I just had more context in the same place. That saved time and made the feedback loop tighter. &lt;/p&gt;

&lt;p&gt;The inline suggestions inside my PRs were the easiest part of the experience to adopt. I wrote more about that experience in this post on &lt;a href="https://bito.ai/blog/chatting-with-my-ai-code-review-agent/" rel="noopener noreferrer"&gt;how I started chatting with my AI code reviewer&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Next, I’ll walk through what Bito is doing now, what new features we are working on, and why I’m betting on it. &lt;/p&gt;

&lt;h2&gt;
  
  
  AI code reviews: What we’re doing at Bito?
&lt;/h2&gt;

&lt;p&gt;Over the past 150 days, Bito kept adding features that made pull request reviews smoother and more aligned with real-world development. And I tried them all.  &lt;/p&gt;

&lt;p&gt;We’ve already listed out all the major features that Bito’s AI Code Review Agent offers in the product page. Here’s a quick overview: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reviews pull requests &lt;/li&gt;
&lt;li&gt;Gives inline, contextual suggestions &lt;/li&gt;
&lt;li&gt;Catches code smells, logic issues, and style problems &lt;/li&gt;
&lt;li&gt;Learns from your feedback and adapts &lt;/li&gt;
&lt;li&gt;Doesn’t store your code or use it for training 
… and much more. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this section, I specifically want to talk about the major updates Bito released and things I did, since I joined: &lt;/p&gt;

&lt;h3&gt;
  
  
  1/ Custom code review rules
&lt;/h3&gt;

&lt;p&gt;This is one of the latest and coolest updates Bito dropped after I joined. Bito’s AI Code Review Agent lets you enforce your own coding standards directly in PRs: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automatic learning from feedback: When I mark a suggestion as irrelevant, the AI learns not to offer that again. Once you mark a similar suggestion as irrelevant three time, Bito creates a custom rule. Read about it &lt;a href="https://docs.bito.ai/ai-code-review-agent/implementing-custom-code-review-rules" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom rule uploads: This is the latest update! You can now create a custom guideline directly within your Bito dashboard. I created a video walkthrough. &lt;a href="https://www.youtube.com/watch?v=-Y9Jq6mGILo" rel="noopener noreferrer"&gt;Watch it on YouTube here&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More on this is detailed in &lt;a href="https://bito.ai/blog/how-i-personalized-bitos-ai-code-review-suggestions/" rel="noopener noreferrer"&gt;How I Personalized Bito’s AI Code Review Suggestions&lt;/a&gt;, which is actually about defining rules. The feature works as expected! &lt;/p&gt;

&lt;h3&gt;
  
  
  2/ Multi-product seat based billing
&lt;/h3&gt;

&lt;p&gt;Earlier in June, Bito also rolled out a redesigned dashboard for managing users and billing. This was a big deal for teams. &lt;/p&gt;

&lt;p&gt;The new member management view shows exactly how many seats your workspace has, how they’re distributed between IDE users and pull request reviewers, and who’s using what.  &lt;/p&gt;

&lt;p&gt;It’s now seat-based by product, which makes scaling much easier to track. &lt;/p&gt;

&lt;p&gt;There’s also an auto-assignment option. Meaning: new dev joins and they get a seat automatically. Or turn it off and do it manually. That’s up to the admin. &lt;/p&gt;

&lt;p&gt;I also created a video walkthrough to explain this update. &lt;a href="https://www.youtube.com/watch?v=Xx8vSb5HhXk" rel="noopener noreferrer"&gt;Watch it on YouTube here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3/ Chatting with the AI Code Review Agent
&lt;/h3&gt;

&lt;p&gt;This feature was launched in April. It gives you the ability to chat directly with Bito’s AI Code Review Agent. You can ask the agent follow-up questions on its suggestions. Things like: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Why is this a problem?” &lt;/li&gt;
&lt;li&gt;“Can you suggest a cleaner way to do this?” &lt;/li&gt;
&lt;li&gt;“What’s an alternative approach?” &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tried this in one of my own PRs and wrote about it in &lt;a href="https://bito.ai/blog/chatting-with-my-ai-code-review-agent/" rel="noopener noreferrer"&gt;Chatting With My AI Code Review Agent&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Also worth noting: Bito supports over 20 human languages in this chat experience. I mostly use English, but I tested a few queries in Hindi just to see. Works just fine. &lt;/p&gt;

&lt;h3&gt;
  
  
  4/ Agentic code reviews
&lt;/h3&gt;

&lt;p&gt;This was a game-changer. Bito’s AI Code Review Agent is now fully agentic. That means it no longer follows a fixed chain-of-thought pipeline.  &lt;/p&gt;

&lt;p&gt;Instead, it dynamically figures out what context matters, explores the code more freely, and generates suggestions based on real structure and patterns. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.bito.ai/whats-new#:~:text=Agentic%20code%20reviews%20are%20here" rel="noopener noreferrer"&gt;Read the doc&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5/ Multilingual code reviews
&lt;/h3&gt;

&lt;p&gt;Bito now supports over 20 human languages in review comments. That includes English, Hindi, Chinese, and Spanish.  &lt;/p&gt;

&lt;p&gt;If you’re working with global teams or reviewing code with non-English speakers, this is just one less thing to worry about. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.bito.ai/whats-new#:~:text=Multilingual%20code%20reviews" rel="noopener noreferrer"&gt;Read the doc&lt;/a&gt; for the steps. &lt;/p&gt;

&lt;h3&gt;
  
  
  6/ Amazon Nova Lite 1.0 in Bito
&lt;/h3&gt;

&lt;p&gt;With the release of Bito’s free tier, Nova Lite became a key model powering the Code Review Agent for individual developers.  &lt;/p&gt;

&lt;p&gt;What that means for developers? You get free AI code reviews for everyday tasks that don’t need deep reasoning. The experience still feels tight and helpful. &lt;/p&gt;

&lt;p&gt;Amazon even featured this in a case study with Bito. You can read it here: &lt;a href="https://bito.ai/case_studies/amazon-nova/" rel="noopener noreferrer"&gt;Amazon Nova + Bito Case Study&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Updates
&lt;/h3&gt;

&lt;p&gt;Bito rolls out updates weekly. You can find all release notes and documentation on our official site. &lt;/p&gt;

&lt;p&gt;Most of the features I used during these 120 days came from regular product iterations that improved my workflow quietly in the background. &lt;/p&gt;

&lt;p&gt;See the full release changelog and docs here: &lt;a href="https://docs.bito.ai/whats-new" rel="noopener noreferrer"&gt;Bito documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bito, its competitors, and benchmarking
&lt;/h2&gt;

&lt;p&gt;If you’re a marketer in tech, you can’t just skim docs and pitch jargons. You need to understand the product deeply. And that means using it.  &lt;/p&gt;

&lt;p&gt;For me, that also meant trying out the competition. Because if I’m going to talk about Bito, I need to know exactly how it stacks up. &lt;/p&gt;

&lt;p&gt;So I did what any curious developer-marketer would do. I opened real pull requests and used Bito side by side with the other tools. A few examples: &lt;/p&gt;

&lt;h3&gt;
  
  
  Bito vs Coderabbit
&lt;/h3&gt;

&lt;p&gt;This one was a full comparison. I took the same PR and ran it through both tools. Bito gave sharper, more relevant suggestions. It caught things I actually cared about.  &lt;/p&gt;

&lt;p&gt;Coderabbit left more noise than value. Less signal, more cleanup. I documented everything here: &lt;a href="https://bito.ai/blog/bito-vs-coderabbit/" rel="noopener noreferrer"&gt;Bito vs Coderabbit&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bito vs GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;Then came Copilot. It’s great for writing code in the IDE, sure. But when it comes to reviewing code in pull requests, it’s just not built for that. No inline feedback, no context, no real review flow.  &lt;/p&gt;

&lt;p&gt;Bito, on the other hand, lives inside your PR. It gives you comments where they matter, grounded in the actual diff. You can see my detailed comparison here: &lt;a href="https://bito.ai/blog/bito-vs-github-copilot-how-is-bito-different-from-github-copilot/" rel="noopener noreferrer"&gt;How is Bito Different from GitHub Copilot? &lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmarking AI code review tools
&lt;/h3&gt;

&lt;p&gt;After using Bito for a few months, I also wanted to see how it stacked up in more structured comparisons. The team at Bito has actually built a proper benchmarking setup for this.  &lt;/p&gt;

&lt;p&gt;We test the tool on a known set of code issues across multiple languages, and compare it with other tools in the space. Based on the benchmarking: &lt;/p&gt;

&lt;p&gt;Bito performed well. It had the highest issue coverage and consistently caught more high-severity bugs in languages like TypeScript, Python, JavaScript, Go, and Java. That kind of data gave me more confidence in what I was seeing in my own pull requests. &lt;/p&gt;

&lt;p&gt;You can check out the whole thing here: &lt;a href="https://bito.ai/blog/benchmarking-the-best-ai-code-review-tool/" rel="noopener noreferrer"&gt;Benchmarking the Best AI Code Review Tool&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;150 days ago, I joined Bito to understand how AI fits into real code reviews. Since then, I have used Bito on live PRs, tried every feature it shipped, and compared it directly with other tools. &lt;/p&gt;

&lt;p&gt;As someone in developer marketing, I believe in understanding the product deeply. That means using it the way real developers do.  &lt;/p&gt;

&lt;p&gt;After five months, I see why Bito is different. It provides codebase aware PR suggestions, keeps your code private, respects your coding standards, and makes PR reviews more efficient. &lt;/p&gt;

&lt;p&gt;Security matters. Many AI (or non-AI) tools still store your code or use it to train their models. That should not happen in a secure code review process. I wrote about that here: &lt;a href="https://bito.ai/blog/secure-code-review-process/" rel="noopener noreferrer"&gt;Secure Code Review Process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are curious, try Bito on a real pull request. That is the only way to see what it can actually do: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://bito.ai" rel="noopener noreferrer"&gt;Sign up here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Code Security for Developers: How to Write &amp; Review Code Securely</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Thu, 05 Jun 2025 19:06:13 +0000</pubDate>
      <link>https://dev.to/sushrutkm/code-security-for-developers-how-to-write-review-code-securely-5330</link>
      <guid>https://dev.to/sushrutkm/code-security-for-developers-how-to-write-review-code-securely-5330</guid>
      <description>&lt;p&gt;When people say code security, most developers think about things like SQL injection, broken auth, or insecure APIs. All of these matter, no doubt. But that is not why I'm writing this like.&lt;/p&gt;

&lt;p&gt;This is about something simpler. What happens to your code when you send it for review? Where it goes? Who sees it? And whether it gets stored somewhere you never agreed to.&lt;/p&gt;

&lt;p&gt;When I first started writing code in 2021, I knew nothing about code security or code review. For me, development and review meant: You push your changes, someone leaves comments, you clean things up. That was it. &lt;/p&gt;

&lt;p&gt;What I did not think about was where that code might end up. A lot of tools, especially the AI ones, take your code and send it out of your dev environment. Some of them store it. Some of them train on it. And most of the time, they do not tell you that clearly.&lt;/p&gt;

&lt;p&gt;That is a problem. Because if you care about code security, you have to care about the review process too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is code security
&lt;/h2&gt;

&lt;p&gt;Code security is one of those terms that gets thrown around a lot. People usually connect it to OWASP lists or app vulnerabilities or something that the security team deals with once the code is already written. &lt;/p&gt;

&lt;p&gt;That is not wrong. But it is only part of the picture.&lt;/p&gt;

&lt;p&gt;At the most basic level, code security means writing code that does not put your users or systems at risk. &lt;/p&gt;

&lt;p&gt;That includes avoiding things like SQL injection, hardcoded secrets, or logic that can be abused. It also means following secure coding practices like input validation, access control, and safe error handling.&lt;/p&gt;

&lt;p&gt;But there is another part that does not get talked about enough. And that is keeping your actual source code protected while you are working on it. That includes the way you share it, review it, and run it through tools. &lt;/p&gt;

&lt;p&gt;Because the code itself is valuable. It holds your product logic, your architecture, and sometimes things like internal tokens or data structures that should not leave your environment.&lt;/p&gt;

&lt;p&gt;So code security is not just about writing safe code. It is also about protecting that code during the entire development process. &lt;/p&gt;

&lt;p&gt;That includes reviews. &lt;br&gt;
That includes automation. &lt;br&gt;
And that includes AI tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  How secure code gets exposed during review
&lt;/h2&gt;

&lt;p&gt;When you hear the word "code review," you probably think of inline comments, feedback on naming, maybe some logic suggestions. That is what most of us learn. The whole process is meant to improve code quality. And that part still matters.&lt;/p&gt;

&lt;p&gt;But here is what most devs never get told.&lt;/p&gt;

&lt;p&gt;A lot of tools that help with code review are doing more than just reading your code. They are moving it. &lt;/p&gt;

&lt;p&gt;Some of them upload it to their own servers. Some keep logs. Some save it for product analytics. And a few even use it to train large language models. All of this can happen silently.&lt;/p&gt;

&lt;p&gt;The problem is, you usually do not know. You install a plugin, connect your IDE, and suddenly your pull request is part of someone else's training data. &lt;/p&gt;

&lt;p&gt;And unless you are reading every privacy policy and security FAQ, you probably will not catch it. I'm talking so much about this because once your code leaves your machine, you do not control what happens next. &lt;/p&gt;

&lt;p&gt;Even if it is encrypted in transit. &lt;br&gt;
Even if it is deleted later. &lt;br&gt;
There is still a window where something could go wrong.&lt;/p&gt;

&lt;p&gt;This is how secure code gets exposed. Only because you trusted a tool that moved your code somewhere it should not have gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to actually review code securely
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvaeosp8qpdd461njn27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvaeosp8qpdd461njn27.png" alt="Secure Code Review Cycle" width="800" height="697"&gt;&lt;/a&gt;&lt;br&gt;
Writing secure code is only half the job. You also need to make sure the way you review it does not open up new risks. That starts with being a little more curious about the tools you use.&lt;/p&gt;

&lt;p&gt;The first thing to check is where the tool runs. If it runs locally, inside your IDE, that is a good sign. It means your code stays on your machine. &lt;/p&gt;

&lt;p&gt;If the tool needs to connect to the internet or send your code to a server for processing, that is where things get risky.&lt;/p&gt;

&lt;p&gt;The second thing is storage. &lt;/p&gt;

&lt;p&gt;Some tools store code temporarily. Some keep it longer. Some train models on it. You need to check for that. &lt;/p&gt;

&lt;p&gt;Read the docs. Look for clear statements about how your code is handled. If you cannot find that, assume the worst. (Paranoid, maybe?)&lt;/p&gt;

&lt;p&gt;The third thing is access. &lt;/p&gt;

&lt;p&gt;Who can see your code once it leaves your laptop? Is it going to a third-party cloud service? Is it getting logged somewhere? Even tools that say your data is secure might still be copying it around for “product improvement.” &lt;/p&gt;

&lt;p&gt;That is not safe.&lt;/p&gt;

&lt;p&gt;So here is a simple way to review code securely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use tools that process code locally&lt;/li&gt;
&lt;li&gt;Avoid tools that store your code or send it to external servers&lt;/li&gt;
&lt;li&gt;Check for clear data handling policies&lt;/li&gt;
&lt;li&gt;Ask your team who has access to your source code during reviews&lt;/li&gt;
&lt;li&gt;Keep sensitive logic out of third-party tools if you are not sure how they work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should not have to give up convenience or automation. You just need tools that were built with security in mind from the start.&lt;/p&gt;

&lt;p&gt;The good news is those tools exist. And they are getting better.&lt;/p&gt;

&lt;h2&gt;
  
  
  A safe way to review code with AI
&lt;/h2&gt;

&lt;p&gt;There is nothing wrong with using AI to speed up your code reviews. In fact, it helps a lot. You catch issues faster. You get help refactoring. You waste less time on obvious stuff. &lt;/p&gt;

&lt;p&gt;The problem only starts when those tools take your code and store it somewhere you do not control.&lt;/p&gt;

&lt;p&gt;That is where &lt;a href="https://bito.ai/product/ai-code-review-agent/" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; fits in.&lt;/p&gt;

&lt;p&gt;Bito runs inside your IDE. It reviews your code locally. It gives you real-time suggestions without uploading anything to the cloud. There is no storage, no data training or tracking. &lt;/p&gt;

&lt;p&gt;Your code stays where it should stay — on your machine.&lt;/p&gt;

&lt;p&gt;It can still flag security risks like SQL injection, hardcoded secrets, or unsafe input handling. It can help simplify functions, reduce complexity, and make reviews less painful. &lt;/p&gt;

&lt;p&gt;You get all of that, but without giving up your code.&lt;/p&gt;

&lt;p&gt;For teams that work on sensitive logic or internal systems, this matters even more. You cannot risk your source code showing up in some model later. Bito keeps that from happening by never storing or sharing any part of it.&lt;/p&gt;

&lt;p&gt;If you want to go deeper into why this matters, I wrote more here: &lt;a href="https://bito.ai/blog/secure-code-review-process/" rel="noopener noreferrer"&gt;Secure Code Review Process: A gap in Code Security&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pydovhg3lwp7f80m78k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pydovhg3lwp7f80m78k.png" alt="Secure Code Review - Bito Blog" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Secure code is not just about what you write. It is also about how you review it. Bito helps you keep both parts tight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;If you are learning how to write secure code, do not stop at the code itself. Think about where it goes. Think about how it is reviewed. The tools you use are part of your security story, whether you realize it or not.&lt;/p&gt;

&lt;p&gt;You do not need to ditch AI or slow down your workflow. You just need to stay in control of your code. That means knowing what your tools are doing behind the scenes and picking ones that respect your boundaries.&lt;/p&gt;

&lt;p&gt;Start simple. Keep your reviews local. Ask questions when something feels off. And use tools that were actually built for developers who care about security.&lt;/p&gt;

&lt;p&gt;That is how you build secure habits early. That is how you ship safe code later.&lt;/p&gt;

</description>
      <category>security</category>
      <category>codenewbie</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Cursor AI : A Code Editor That Refused to Be Acquired</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Thu, 29 May 2025 16:37:43 +0000</pubDate>
      <link>https://dev.to/sushrutkm/cursor-ai-a-code-editor-that-refused-to-be-acquired-9ja</link>
      <guid>https://dev.to/sushrutkm/cursor-ai-a-code-editor-that-refused-to-be-acquired-9ja</guid>
      <description>&lt;p&gt;If you are wondering what is Cursor, it is an AI-powered code editor built on top of VS Code. Cursor does not just drop suggestions into your file. It actually understands your codebase. It reads your logic. It figures out what you are trying to build and helps you get there faster.&lt;/p&gt;

&lt;p&gt;Cursor was built by a team of engineers from MIT. They launched it through a company called Anysphere. The tool spread fast through dev circles. It felt different from other AI tools. It slowly became the main editor for a lot of people.&lt;/p&gt;

&lt;p&gt;Then things got interesting. OpenAI wanted to buy Cursor. This was around the time they were also looking at another tool called Windsurf (not too long ago). &lt;/p&gt;

&lt;p&gt;In the end, OpenAI picked Windsurf. Cursor said no to the offer. There is a thread about this on &lt;em&gt;r/LocalLLaMA&lt;/em&gt; where people broke down what happened. Cursor turned it down because the team has bigger plans. They want to build a fullstack developer platform. Something more than a tool that just sits in your workflow.&lt;/p&gt;

&lt;p&gt;This article walks through the whole thing. From the start of Cursor to how it works today. Why it matters. Why the team stayed independent. And which other tools are out there if you want to compare.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who built Cursor and why
&lt;/h2&gt;

&lt;p&gt;Cursor came out of a company called Anysphere. The team behind it started at MIT. Four engineers. They were not trying to raise hype or chase funding. They were just tired of fighting their editors.&lt;/p&gt;

&lt;p&gt;They were dealing with large codebases. The kind where grep starts to fall apart. Context switching eats your focus. Every time you jump between files or revisit old logic, you lose time. They built Cursor to fix that.&lt;/p&gt;

&lt;p&gt;The editor started as a side project. They dropped it quietly, with almost no noise. A few devs picked it up. Then word spread. People were sharing screenshots, test results, even full feature breakdowns in Discord and Reddit threads. Cursor started doing something other AI tools could not. It followed your train of thought.&lt;/p&gt;

&lt;p&gt;Instead of just spitting out code from prompts, it looked at the whole repo. It followed function calls. It answered questions with actual context. And it let you edit code the way you think about it—one layer at a time.&lt;/p&gt;

&lt;p&gt;The team shipped fast. Every week there was something new. Better context depth. Faster responses. Real codebase indexing. It felt like they were building for themselves, not for show.&lt;/p&gt;

&lt;p&gt;At this point, Cursor was still free. They had not launched some giant pricing plan. There were no flashy launches. Just updates and a growing user base of actual developers.&lt;/p&gt;

&lt;p&gt;That early momentum is what caught OpenAI’s attention later on. We will get into that in a bit. First, let’s talk about what Cursor actually does differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes Cursor different
&lt;/h2&gt;

&lt;p&gt;Most AI coding tools feel like helpers. Cursor feels like another dev on your team. Not some floating text box. Not a one-off reply generator. It sits inside your editor, watches how you code, and helps without getting in the way.&lt;/p&gt;

&lt;p&gt;You can select a block of code and ask it to explain what it does. You can ask it to refactor. You can even ask why a test might be failing, and it will trace back through your code to give a real answer. It looks at the full picture.&lt;/p&gt;

&lt;p&gt;The biggest difference is how it handles context. Cursor pulls in actual code files, not just lines around your cursor. It understands project structure. It knows what your functions connect to. It follows imports. It knows what changed between commits.&lt;/p&gt;

&lt;p&gt;You do not need to write long prompts either. You can say something simple like "make this cleaner" or "convert this to use hooks" and it gets the job done.&lt;/p&gt;

&lt;p&gt;There is also a built-in chat. It sits in the sidebar, like a teammate you can talk to. You can ask how a file works. You can ask it to find where something breaks. The best part is, you never leave your flow. No browser. No copy and paste. No API juggling.&lt;/p&gt;

&lt;p&gt;Cursor also handles search better than most editors. You can ask it stuff like "where is this function used across the app" or "what causes this error" and it returns actual answers, not just file hits.&lt;/p&gt;

&lt;p&gt;It still works with all your VS Code extensions. You do not have to rebuild your whole setup. You just get smarter behavior inside something you already use.&lt;/p&gt;

&lt;p&gt;This is why people started switching full time. Cursor is not just helping write code. It is helping understand it. That changes everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Cursor said no to OpenAI
&lt;/h2&gt;

&lt;p&gt;Sometime in early 2024, OpenAI started looking for a serious AI coding assistant. They were already behind tools like Cursor, Replit Ghostwriter, and even their own Copilot collab with GitHub. They wanted something better. Something that could go deep inside the code. Something with momentum.&lt;/p&gt;

&lt;p&gt;Cursor was on that list.&lt;/p&gt;

&lt;p&gt;From what leaked out in dev threads, including a long one on r slash LocalLLaMA, OpenAI made an offer to acquire Cursor. That never happened. Cursor said no.&lt;/p&gt;

&lt;p&gt;OpenAI moved on and ended up acquiring another tool called Windsurf. The deal went quiet for a while, but once Windsurf showed up in OpenAI’s ecosystem, the dev community started putting the pieces together.&lt;/p&gt;

&lt;h3&gt;
  
  
  So why did Cursor walk away?
&lt;/h3&gt;

&lt;p&gt;The short answer is focus. The team at Anysphere is not trying to build a feature. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are not trying to get absorbed into someone else's stack. &lt;/li&gt;
&lt;li&gt;They want to turn software into something more than just apps and frameworks. &lt;/li&gt;
&lt;li&gt;They are thinking about software itself as a platform. A place where devs can work with AI at every step. Not just when typing code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the outside, it looked like a wild move. Who says no to OpenAI?&lt;/p&gt;

&lt;p&gt;From the inside, it makes some sense. Cursor is growing fast. Devs are switching full time. Feedback is rolling in from real projects. They did not need to sell. (though i still can't fathom how can someone refuse a multi-billion dollar deal?)&lt;/p&gt;

&lt;p&gt;Anyway, that decision set the tone. Cursor is not a side project anymore. It is playing long game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cursor is great, but not flawless
&lt;/h2&gt;

&lt;p&gt;I have used Cursor enough to know where it shines. I have also run into stuff that made me want to shut it down and switch back.&lt;/p&gt;

&lt;p&gt;The biggest problem is that it sometimes guesses too much. When you ask it to fix something, it tries to rewrite more than you expected. It might change logic that did not need to change. Sometimes it over-explains. Other times, it gets stuck in vague answers that look smart but do not help.&lt;/p&gt;

&lt;p&gt;The chat can get annoying if you are deep in a complex bug. It starts losing track of what you asked a few messages ago. You have to rephrase or start over. When it works, it works really well. When it breaks, it feels like trying to debug with someone who did not read the code properly.&lt;/p&gt;

&lt;p&gt;There are also limits on context. Cursor pulls in more than Copilot, but it still misses edge cases in larger repos. Especially in monorepos or projects with nested services, it can lose track of cross-references.&lt;/p&gt;

&lt;p&gt;And yeah, it is not lightweight. Cursor feels heavier than plain VS Code. Startup time is slower. The AI features take some time to kick in, especially on cold starts. You feel that lag when you are jumping into a new project or switching branches.&lt;/p&gt;

&lt;p&gt;Pricing is also starting to become a question. It was free at first, which helped it spread. Now it is starting to cost real money. For some people, it is worth it. For others, especially folks who only use the AI once in a while, it might feel like overkill.&lt;/p&gt;

&lt;p&gt;I am not saying Cursor is bad. I still use it. I just do not want to pretend it solves everything. It is a great tool, not a perfect one.&lt;/p&gt;

&lt;h2&gt;
  
  
  If Cursor does not click, try these
&lt;/h2&gt;

&lt;p&gt;Not every dev wants to switch their whole editor. Some people want lightweight. Some want in-browser. Some want to keep VS Code but add smarter suggestions. Cursor is not the only option out there. I have tried a bunch of others, and here is what I found.&lt;/p&gt;

&lt;p&gt;For a full breakdown, you can check this list I put together earlier: &lt;a href="https://bito.ai/blog/best-cursor-alternatives/" rel="noopener noreferrer"&gt;Best Cursor Alternatives&lt;/a&gt; — it goes deeper into features, pricing, and which tools work best for what kind of workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;Copilot is the most well-known. It is built into VS Code and backed by OpenAI. It gives solid autocomplete suggestions as you type. For small functions or boilerplate, it works fine. It does not understand full context very well. You can’t ask questions like you would in Cursor. It also gets stuck in loops sometimes and repeats itself. Good for fast typing, not great for deep debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bito
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://bito.ai" rel="noopener noreferrer"&gt;Bito&lt;/a&gt; is built for devs who want AI help without leaving their flow. It works inside your IDE and helps with code explanations, suggestions, documentation, and test cases. It is faster than most browser-based tools and does not require tons of setup. You can also use it with private codebases safely, which is a big plus if you care about keeping things in-house. If you are looking for a no-nonsense AI pair dev that fits inside your setup, Bito is worth checking out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cody by Sourcegraph
&lt;/h3&gt;

&lt;p&gt;Cody is somewhere between Copilot and Cursor. It comes with a built-in chat, can look at your whole repo, and ties into Sourcegraph’s code intelligence system. If you are already using Sourcegraph, Cody makes sense. It is more mature than Cursor in some areas, like search, but a bit clunky when it comes to editing. Still improving.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replit Ghostwriter
&lt;/h3&gt;

&lt;p&gt;Ghostwriter lives inside the Replit IDE. If you are coding in the browser or working on quick prototypes, this is one of the best setups. It helps with both code and docs. You can ask it to build something and it gives you a full layout. Problem is, you have to work in Replit. It is not for local dev or long-term projects unless your whole team is on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Continue
&lt;/h3&gt;

&lt;p&gt;Continue is an open-source extension that brings AI chat to VS Code. It is not as polished as Cursor, but it is lightweight and flexible. You can bring your own model. You can use local setups. If you are tired of closed tools and want something you can tweak, Continue is worth trying. Just expect more setup and less magic out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  CodeWhisperer by AWS
&lt;/h3&gt;

&lt;p&gt;If you are deep in the AWS ecosystem, CodeWhisperer makes sense. It is focused more on security, cloud integration, and dev environments tied to AWS services. For general-purpose coding, it feels behind the others. It is slower. Suggestions are not as sharp. But if your day is full of Lambda functions and IAM configs, it might help.&lt;/p&gt;

</description>
      <category>cursor</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>The impasse of SQL performance optimizing</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Tue, 19 Sep 2023 14:04:52 +0000</pubDate>
      <link>https://dev.to/sushrutkm/the-impasse-of-sql-performance-optimizing-1gb</link>
      <guid>https://dev.to/sushrutkm/the-impasse-of-sql-performance-optimizing-1gb</guid>
      <description>&lt;p&gt;Many big data calculations are implemented in SQL. When running slowly, we have to optimize SQL, but we often encounter situations that we can do nothing about it.&lt;br&gt;
For example, there are three statements in the stored procedure, which are roughly like this, and execute very slowly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select a,b,sum(x) from T group by a,b where …;&lt;br&gt;
select c,d,max(y) from T group by c,d where …;&lt;br&gt;
select a,c,avg(y),min(z) from T group by a,c where …;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;T is a huge table with hundreds of millions of rows. It needs to be grouped by three methods, and the grouped result sets are not large.&lt;/p&gt;

&lt;p&gt;The grouping operation needs to traverse the data table. These three SQL statements will traverse the huge table three times. It takes a long time to traverse hundreds of millions of rows of data once, not to mention three times.&lt;/p&gt;

&lt;p&gt;In this grouping operation, the CPU calculation time is almost negligible relative to the time of traversing the hard disk. If we can calculate multiple group aggregations in one traversal, although the amount of CPU calculation is not reduced, it can greatly reduce the amount of data read from the hard disk and double the speed.&lt;/p&gt;

&lt;p&gt;If SQL could support syntax like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from T&lt;br&gt;
select a,b,sum(x) group by a,b where … -- the first grouping in the traversal&lt;br&gt;
select c,d,max(y) group by c,d where … -- the second grouping in the traversal&lt;br&gt;
select a,c,avg(y),min(z) group by a,c where …; -- the third grouping in the traversal&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It would be able to return multiple result sets in one traversal, and the performance can be greatly improved.&lt;br&gt;
Unfortunately, SQL does not have this syntax and cannot code like this. We can only use an alternative method, that is, use group a,b,c,d to calculate a more detailed grouping result set first, but first save it into a temporary table before we can further calculate the target results with SQL. The SQL statements are rough as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;create table T_temp as select a,b,c,d,&lt;br&gt;
sum(case when … then x else 0 end) sumx,&lt;br&gt;
max(case when … then y else null end) maxy,&lt;br&gt;
sum(case when … then y else 0 end) sumy,&lt;br&gt;
count(case when … then 1 else null end) county,&lt;br&gt;
min(case when … then z else null end) minz&lt;br&gt;
group by a,b,c,d;&lt;br&gt;
select a,b,sum(sumx) from T_temp group by a,b where …;&lt;br&gt;
select c,d,max(maxy) from T_temp group by c,d where …;&lt;br&gt;
select a,c,sum(sumy)/sum(county),min(minz) from T_temp group by a,c where …;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this way, we only need to traverse once, but we have to transfer different where conditions to the previous case when, the code is much more complex and the amount of calculation will be increased. Moreover, when calculating the temporary table, the number of grouping fields becomes large, and the result set may be large. The temporary table is traversed many times, and the calculation performance is not good. Large result set grouping calculation needs hard disk buffer, and its performance is also very poor.&lt;/p&gt;

&lt;p&gt;We can also use the database cursor of the stored procedure to fetch the data one by one, but we have to implement the actions of where and group by ourselves. It's too cumbersome to code, and the performance of the database cursor traversing the data will only be worse!&lt;/p&gt;

&lt;p&gt;We can do nothing about it!&lt;br&gt;
TopN operation will also encounter this helpless situation. For example, top5 written in Oracle SQL is rough as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select * from (select x from T order by x desc) where rownum&amp;amp;lt;=5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are 1 billion pieces of data in table T. As can be seen from the SQL statement, the way to get the top five is to sort all the data and then get the first five, and the remaining sorting results are useless! The cost of large sorting is very high. The amount of data is too large to be loaded into memory. There will be multiple hard disk data buffering, and the computing performance will be very poor!&lt;/p&gt;

&lt;p&gt;It is not difficult to avoid large sorting. Keep a small set of 5 records in memory. When traversing the data, save the top 5 calculated data in this small set. If the new data is larger than the current fifth, insert it and discard the current fifth. If it is smaller than the current fifth, no action will be taken. In this way, we only need to traverse 1 billion pieces of data once, and the memory occupation is very small, and the computing performance will be greatly improved.&lt;/p&gt;

&lt;p&gt;In essence, this algorithm regards TopN as the same aggregate operation as sum and count, but returns a set rather than a single value. If the SQL could be written like this: select top (x, 5) from T, it would have been able to avoid large sorting.&lt;br&gt;
Unfortunately, SQL does not have an explicit set data type. Aggregate functions can only return a single value and cannot write such statements!&lt;/p&gt;

&lt;p&gt;However, fortunately, the TopN of the whole set is relatively simple. Although the SQL is written like that, the database can usually do some optimization in practice, and the above method is adopted to avoid large sorting. As a result, Oracle is not slow to calculate that SQL statement.&lt;/p&gt;

&lt;p&gt;However, if the situation of TopN is complex, the optimization engine usually doesn't work when it is used in subqueries or mixed with join. For example, to calculate the TopN of each group after grouping, it is a little difficult to write it in SQL. The SQL of Oracle is written as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select * from&lt;br&gt;
(select y,x,row_number() over (partition by y order by x desc) rn from T)&lt;br&gt;
where rn&amp;amp;lt;=5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this case, the database optimization engine will faint and will no longer use the above method of understanding TopN as an aggregate operation. It can only do the big sorting, and the operation speed drops sharply!&lt;br&gt;
If only the SQL statement could be written as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select y,top(x,5) from T group by y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Considering top as an aggregate function like sum, it would have been not only easier to read, but also easy to calculate at high speed.&lt;br&gt;
Unfortunately, No.&lt;br&gt;
We still can do nothing about it!&lt;/p&gt;

&lt;p&gt;Join calculation is also very common. Take the filtering calculation after the order table is associated with multiple tables as an example. The SQL is basically like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select o.oid,o.orderdate,o.amount&lt;br&gt;
 from orders o&lt;br&gt;
 left join city ci on o.cityid = ci.cityid&lt;br&gt;
 left join shipper sh on o.shid=sh.shid&lt;br&gt;
 left join employee e on o.eid=e.eid&lt;br&gt;
 left join supplier su on o.suid=su.suid&lt;br&gt;
 where ci.state='New York'&lt;br&gt;
 and e.title = 'manager'&lt;br&gt;
 and ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are tens of millions of data in the order table, and the data in city, shipper, employee, supplier and other tables are not large. The filter condition fields may come from these tables, and the parameters are given from the front end and will change dynamically.&lt;/p&gt;

&lt;p&gt;Generally, SQL uses the hash join algorithm to implement these associations. The hash values will be calculated and compared. Only one join can be resolved at a time, and the same action will have to be performed n times if there are n joins. After each join, the intermediate results need to be kept for the next round. The calculation process is complex, the data will be traversed many times, and the calculation performance is poor.&lt;/p&gt;

&lt;p&gt;Usually, these associated tables are small and can be read into memory first. If each associated field in the order table is serialized in advance, for example, convert the employee id field value to the sequence number of the corresponding employee table record, when calculating, we can use the employee id field value (that is, the sequence number of employee table) to directly get the record at the corresponding position of the employee table in memory. The performance is much faster than hash join, and we only need to traverse the order table once, and the speed will be greatly improved!&lt;/p&gt;

&lt;p&gt;That is, the SQL should be written as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select o.oid,o.orderdate,o.amount&lt;br&gt;
from orders o&lt;br&gt;
 left join city c on o.cid = c.#&lt;br&gt;
 left join shipper sh on o.shid=sh.#&lt;br&gt;
 left join employee e on o.eid=e.#&lt;br&gt;
 left join supplier su on o.suid=su.#&lt;br&gt;
 where ci.state='New York'&lt;br&gt;
 and e.title = 'manager'&lt;br&gt;
 and ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, SQL uses the concept of unordered sets. Even if these ids have been serialized, the database can't take advantage of this feature. It can't use the mechanism of rapid sequence number positioning on these unordered sets of the corresponding associated tables. It can only use index search. Moreover, the database doesn't know that the ids have been serialized, and it still calculates hash values and makes comparisons, and the performance is still very poor!&lt;/p&gt;

&lt;p&gt;Although there are good methods, they cannot be implemented. And we can still do nothing about it!&lt;br&gt;
There are also highly concurrent account queries. This operation is very simple:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select id,amt,tdate,… from T&lt;br&gt;
where id='10100'&lt;br&gt;
and tdate&amp;amp;gt;= to_date('2021-01-10', 'yyyy-MM-dd')&lt;br&gt;
and tdate&amp;amp;lt;to_date('2021-01-25', 'yyyy-MM-dd')&lt;br&gt;
and …&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the hundreds of millions of historical data in the T table, quickly find several to thousands of details of an account. It is not complicated to code with SQL. The difficulty is that the response time should reach the second level or even faster in case of large concurrency. In order to improve the query response speed, the ID field of the T table is generally indexed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;create index index_T_1 on T(id)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the database, the speed of using the index to find a single account is very fast, but it will be significantly slower in the case of large concurrency. The reason is also the theoretical unordered basis of SQL mentioned above. The total amount of data is huge and cannot be totally read into memory, and the database cannot ensure that the data of the same account is physically stored continuously. &lt;/p&gt;

&lt;p&gt;The hard disk has the smallest reading unit. When reading discontinuous data, many irrelevant contents will be fetched, and the query will be slow. If each query under high concurrency is a little slower, the overall performance will be very poor. Who dares to let users wait for more than ten seconds at a time when user experience is so very important?!&lt;/p&gt;

&lt;p&gt;An easy way to think of is to sort hundreds of millions of data according to accounts in advance and ensure the continuous storage of data of the same account. In this way, almost all of the data blocks read out from the hard disk during query are target values, and the performance will be greatly improved.&lt;/p&gt;

&lt;p&gt;However, the relational database using SQL system does not have this awareness and will not force the physical order of data storage! This problem is not caused by SQL syntax, but is related to the theoretical basis of SQL. It is still impossible to implement these algorithms in a relational database.&lt;/p&gt;

&lt;p&gt;Now, what can we do? Can we do anything about it?&lt;br&gt;
We can no longer use SQL and relational databases. We need to use other computing engines.&lt;br&gt;
Based on the innovative theoretical basis, the open-source esProc SPL supports more data types and operations and can describe the new algorithms in the above scenarios. To code with simple and convenient SPL can greatly improve the computing performance in a short time!&lt;br&gt;
The code examples of the above tasks written in SPL are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculate multiple groupings in one traversal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzec133voyr6aps565ts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzec133voyr6aps565ts.png" alt="Image description" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculate top5 by aggregation method
Top5 of the total set (multithreaded parallel computing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu79bncnxemef0oobb9b7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu79bncnxemef0oobb9b7.png" alt="Image description" width="800" height="158"&gt;&lt;/a&gt;&lt;br&gt;
Top5 of each group (multithreaded parallel computing)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjay9pqogckjpb0s876w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjay9pqogckjpb0s876w.png" alt="Image description" width="800" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Join：
System initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyixkph9dv5xrxxa8hrod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyixkph9dv5xrxxa8hrod.png" alt="Image description" width="800" height="125"&gt;&lt;/a&gt;&lt;br&gt;
Query&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3knpgsclcfxnnadxq1y1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3knpgsclcfxnnadxq1y1.png" alt="Image description" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High concurrency account query：
Data preprocessing and orderly storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y6nmlxul03wcgyk0ab2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y6nmlxul03wcgyk0ab2.png" alt="Image description" width="800" height="190"&gt;&lt;/a&gt;&lt;br&gt;
Account query&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvf75sutqhtm630a1oxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frvf75sutqhtm630a1oxt.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;br&gt;
In addition to these simple examples, SPL can also implement more high-performance algorithms, such as orderly merging for the association between orders and details, pre-association technology for multi-layer dimension table association in multidimensional analysis, bit storage technology for the statistics of thousands of tags, Boolean set technology to speed up the query of multiple enumeration values filtering conditions, timing grouping technology for complex funnel analysis and so on. &lt;/p&gt;

&lt;p&gt;Checkout the esProc_SPL GitHub for more info - &lt;a href="https://github.com/SPLWare/esProc" rel="noopener noreferrer"&gt;https://github.com/SPLWare/esProc&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why a SQL Statement Often Consists of Hundreds of Lines, Measured by KBs？</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Sat, 11 Mar 2023 04:39:40 +0000</pubDate>
      <link>https://dev.to/sushrutkm/why-a-sql-statement-often-consists-of-hundreds-of-lines-measured-by-kbs-52l8</link>
      <guid>https://dev.to/sushrutkm/why-a-sql-statement-often-consists-of-hundreds-of-lines-measured-by-kbs-52l8</guid>
      <description>&lt;p&gt;Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for non-IT people. Simple SQL statements read like English, and even people without any programming experience can write them.&lt;/p&gt;

&lt;p&gt;However, the language becomes clumsy as query needs become even slightly more complicated. It often needs hundreds of rows of multilevel nested statements to achieve a computing task. Even professional programmers often find it hard to write, let alone the non-IT people. As a result, such computing tasks become the popular main question in programmer recruitment tests of many software companies. In real-world business situations, the size of SQL code for report queries is usually measured by KBs. The several-line SQL statements only exist in programming textbooks and training courses.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL problem analysis
&lt;/h2&gt;

&lt;p&gt;What is the reason behind the sheer bulk of the code? Let’s try to find the answer, that is, SQL’s weaknesses, through an example.&lt;/p&gt;

&lt;p&gt;Suppose we have sales performance table sales_amount consisting of three fields (date information is omitted to make the analysis simpler):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mgf86izj0s7iiv0lkm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mgf86izj0s7iiv0lkm5.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are trying to find salespeople whose sales amounts rank in top 10 in terms of both air conditioners and TV sets.&lt;/p&gt;

&lt;p&gt;The task is not difficult. It is easy for us to think of the following natural computing process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sort the sales performance table by sales amount of air conditioners and get the top 10;&lt;/li&gt;
&lt;li&gt;Sort the sales performance table by sales amount of TV sets and get the top 10;&lt;/li&gt;
&lt;li&gt;Perform intersection operation on step 1 and step 2’s result sets to get the final result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's try to solve it in SQL.&lt;/p&gt;

&lt;p&gt;Early SQL did not support stepwise coding. The first two steps had to be written in subqueries, and the whole process looked a little complicated:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select *from (select top 10 sales from sales_amount where product='AC' order by amount desc) intersect (select top 10 sales from sales_amount where product='TV' order by amount desc)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The language later identified the issue and specifically offers CTE syntax, which uses WITH keyword to name an intermediate result set that can be referenced in subsequent parts of the computation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;withAas select top 10 sales from sales_amount where product='AC' order by amount desc Bas select top 10 sales from sales_amount where product='TV' order by amount desc select *fromA intersect B&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The statement is still long but becomes clearer.&lt;/p&gt;

&lt;p&gt;Now, we make the task a little harder. We will find salespeople whose sales amounts for all products rank in top 10. It’s easy to think up the following algorithm according to the above solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List all products;&lt;/li&gt;
&lt;li&gt;Find salespeople whose sales amounts rank in top 10 for each product and store them separately;&lt;/li&gt;
&lt;li&gt;Calculate the intersection between all top-10 result sets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem is that CTE only works when the number of intermediate results is already known. In this case, we do not know the number of products. This means that the number of clauses under WITH keyword is indefinite and we are not able to write the statement.&lt;/p&gt;

&lt;p&gt;Let’s try a different approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Group the original table by product, sort each group, and find top 10 records meeting the specified condition in each group;&lt;/li&gt;
&lt;li&gt;Calculate intersection of all top 10 records.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But it requires to store the grouping result in step 1. The intermediate result is a table where one field will store the top 10 of members in each group, which means the field values will be sets. As SQL does not support set-type values, the solution becomes infeasible.&lt;/p&gt;

&lt;p&gt;If we have window functions at hand, we can switch to another route. It will group the original table by product, calculate the number of appearances of every salesperson in the top 10 sales amounts of each group, and find those whose total appearances are equal to the number of products – they are the ones whose sales amounts rank in top 10 for all products.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select sales from( select sales, from( select sales, rank()over(partition by product order by amount desc ) ranking from sales_amount) where ranking &amp;amp;lt;=10) group by sales having count(*)=(select count(distinct product) from sales_amount)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This way we are able to accomplish the computing task in SQL. But such a complicated SQL statement is beyond most users.&lt;/p&gt;

&lt;p&gt;As the first two simple algorithms cannot be implemented in SQL, we have to adopt the roundabout third one. This reveals one important weakness of SQL - &lt;strong&gt;insufficient set-orientation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Though SQL has the concept of sets, it does not offer them as a basic data type. A variable or field in the SQL context cannot have set type values. The only set type SQL object is table. This results in roundabout algorithms and complicated code for the large number of set-oriented calculations.&lt;/p&gt;

&lt;p&gt;The keyword top is used in the above SQL sample programs. Actually, there isn’t such an operator in relational algebra (but it can be constructed using a series of other operations), and the code is not standard SQL.&lt;/p&gt;

&lt;p&gt;Let me show you how difficult it is when the top keyword is not available for finding top N.&lt;/p&gt;

&lt;p&gt;Here’s the general way of thinking: For each member, get the number of members where the sales amounts are greater than the current amount, define ranking of the current salesperson according to the number, and get members whose rankings are not greater than 10. Below is the SQL query:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select sales from( select A.sales sales,A.product product, (select count(*)+1 from sales_amount where A.product=product ANDA.amount&amp;amp;lt;=amount) ranking from sales_amount A) where product='AC'AND ranking&amp;amp;lt;=10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select sales from( select A.sales sales,A.product product,count(*)+1 ranking from sales_amount A, sales_amount B where A.sales=B.sales and A.product=B.product ANDA.amount&amp;amp;lt;=B.amount group by A.sales,A.product ) where product='AC'AND ranking&amp;amp;lt;=10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even professional programmers find it hard to write. The code is too complicated for such a simple top 10 computation.&lt;/p&gt;

&lt;p&gt;Even if SQL supports the keyword top, it can only solve top N problem conveniently. If the task becomes a bit more complex, such as getting members/values from the 6th to the 10th and finding salespeople whose sales amounts are 10% higher than their directly next, the above problems still exist and we have to resort to a roundabout way if we still trying to achieve it in SQL.&lt;/p&gt;

&lt;p&gt;This is due to SQL’s another key weakness – lack of order-based syntax. SQL inherits mathematical unordered sets, which is the direct cause of difficulties in handling order-based calculations that are prevalent in real-world business situations (such as calculating link relative ratio, YOY, top 20%, and rankings).&lt;/p&gt;

&lt;p&gt;SQL2003 standard adds window functions to try to improve the computing ability for dealing with order-based calculations. They have enabled simpler solutions to the above computing tasks and helped mitigate this SQL problem. However, the use of window functions is usually accompanied by nested queries, and the inability to let users access members of a set directly according to their positions leaves many order-based calculations hard to solve.&lt;/p&gt;

&lt;p&gt;Suppose we are trying to find the gender ratio among the above top salespeople by calculating the number of females and that of males. Generally, the gender information of salespeople is recorded in employee table instead of the sales performance table, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh87ihcyg4rmrem6lptig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh87ihcyg4rmrem6lptig.png" alt="Image description" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the list of top salespeople is available, our first thought might be finding their genders from the employee table and then count the numbers. To achieve this cross-table query, SQL needs a table join. So, the SQL code following the above top 10 task is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select employee.gender,count(*) from employee, (( select top 10 sales from sales_amount where product='AC' order by amount desc ) intersect ( select top 10 sales from sales_amount where product='TV' order by amount desc ))A where A.sales=employee.name group by employee.gender&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Only one table join has already made the code complicated enough. In fact, related information is, on many occasions, stored in multiple tables and often of multilevel structure. For instance, salespeople have their departments and the latter has managers, and we might want to know the managers under whom those top salespeople work. A three-table join is needed to accomplish this, and it is not easy to write smooth and clear WHERE and GROUP for this join.&lt;/p&gt;

&lt;p&gt;Now we find out the next SQL weakness – &lt;strong&gt;lack of object reference mechanism&lt;/strong&gt;. In relational algebra, the relationship between objects is maintained purely by foreign keys match. This results in slow data searching and the inability to treat the member record in the related table pointed by the foreign key directly as an attribute of the current record. Try rewriting the above SQL as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select sales.gender,count(*) from(…)// … is the SQL statement for getting the top 10 records of salespeople group by sales.gender&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Apparently, this query is clearer and will be executed more efficiently (as there are no joins).&lt;/p&gt;

&lt;p&gt;The several SQL key weaknesses shown through a simple example are causes of hard to write and lengthy SQL statements. The process of solving business problems based on a certain computational system is &lt;strong&gt;one that expressing an algorithm with the syntax of a formalized language&lt;/strong&gt; (like solving word problems in primary school by transforming them into formalized four arithmetic operations). The SQL defects are great obstacles to translation of solutions computing problems. In extreme cases, the strangest thing happens – &lt;strong&gt;the process of converting algorithms to syntax of a formalized language turns out to be much harder and more complicated than finding a solution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In other words, using SQL to compute data is like using an assembly language to accomplish four arithmetic operations – which might be easier to understand for programmers. A simple formula like 3+5*7 will become as follows if it is written in an assembly language, say X86:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mov ax,3 mov bx,5 mul bx,7 add ax,bx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Compared with the simple formula 3+5*7, the above code is complicated to write and hard to read (it is even more difficult when fractions are involved). Though it may be not a big deal for veteran programmers, it is almost unintelligible for most business people. In this regard, FORTRAN is a great invention.&lt;/p&gt;

&lt;p&gt;Our examples are simple because I want you to understand my point easily. But real-world computing tasks are far more complicated, and users will face various SQL difficulties. Several more lines here and a few more lines there, it is therefore no wonder that SQL generates multilevel nested statements of hundreds of lines for a slightly complicated task. What’s worse, often the hundreds of lines of code are a single statement, making it hard to debug in terms of engineering aspect and increasing difficulty in handling complex queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  More examples
&lt;/h2&gt;

&lt;p&gt;Let’s look at SQL problems through more examples.&lt;/p&gt;

&lt;p&gt;In order to simplify the SQL statement as much as possible, the above sample programs use many window functions and thus the Oracle syntax that supports window functions well. Syntax of the other databases will only make the SQL statement more complicated.&lt;/p&gt;

&lt;p&gt;Even for these simple tasks that are common in daily analytic work, SQL is already sufficiently hard to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unordered sets
&lt;/h3&gt;

&lt;p&gt;Order-based calculations are prevalent in batch data processing (such as getting top 3 or record/value in 3rd position, and calculating link relative ratio). SQL switches to an unusual way of thinking and take a circuitous route because it cannot perform such a calculation directly thanks to its inheritance of the concept of mathematical unordered sets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 1&lt;/strong&gt;: Find employees whose ages are equal to the median.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select name, birthday from(select name, birthday,row_number()over(order by birthday) ranking from employee ) where ranking=(select floor((count(*)+1)/2) from employee)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Median calculation is common, and the process is simple. We just need to sort the original set and get the member at the middle position. SQL’s unordered-sets-based computational mechanism does not offer position-based member access method. It will invent a field of sequence number and select the eligible members through a conditional query, where subqueries are unavoidable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 2&lt;/strong&gt;: Find the largest number days when a stock rises consecutively.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select max(consecutive_day) from(select count(*)(consecutive_day from(select sum(rise_mark)over(order by trade_date) days_no_gain from(select trade_date, case when closing_price&amp;amp;gt;lag(closing_price)over(order by trade_date) then 0else1END rise_mark from stock_price)) group by days_no_gain)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Unordered sets also lead to tortuous ways of solving problems.&lt;/p&gt;

&lt;p&gt;Here is the general way of doing the task. Set a temporary variable to record the number of consecutive rising days with the initial value as 0, compare the current closing price with the previous one, reset the variable’s the current value as 0 if the price does not rise and add 1 to it if the price rises, and get the largest number when the loop is over.&lt;/p&gt;

&lt;p&gt;SQL cannot express the algorithm and it gives an alternative, which first counts the non-rising frequency for each date from the initial one to the current one. The dates that have the same frequency contain prices rising consecutively. Then it groups these dates to get continuously rising intervals, counts members in each, and finds the largest number. It is extremely difficult to understand and even more hard to express.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insufficient set-orientation
&lt;/h2&gt;

&lt;p&gt;There is no doubt that sets are the basis of batch data processing. SQL is a set-oriented language, but it can only express simple result sets and does not make it a basic data type to extend its application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 3&lt;/strong&gt;: Find employees whose birthdays are on the same date.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select * from employee where to_char(birthday, ‘MMDD’)in ( select to_char(birthday,'MMDD') from employee group by to_char(birthday,'MMDD') having count(*)&amp;amp;gt;1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The original purpose of grouping a set is to divide it into multiple subsets, so a grouping operation should have returned a set of subsets. However, SQL cannot express such a “set of sets” and thus cannot help forcing an aggregate operation on the subsets to return a regular result set.&lt;/p&gt;

&lt;p&gt;At times, what we need isn’t aggregate values but the subsets themselves. To do this, SQL will query the original set again according to the grouping condition, which unavoidably results in a nested query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 4&lt;/strong&gt;: Find students whose scores of all subjects rank in top 10.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select name from(select name from(select name, rank()over(partition by subject order by score DESC) ranking from score_table) where ranking&amp;amp;lt;=10) group by name having count(*)=(select count(distinct subject) from score_table)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The set-oriented solution is to group data by subject, sort each subset by score, select top 10 from each subset, and calculate intersection between the subsets. As SQL’s inability to phrase “a set of sets” and support intersection operations on an indefinite number of sets, the language takes an unusual route to achieve the task. It finds top 10 scores in terms of subjects using a window function, group the result set by student, and find the group where the number of students is equal to the number of subjects. The process is hard to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lack of object reference method
&lt;/h2&gt;

&lt;p&gt;A SQL reference relationship between data tables is maintained through matching foreign key values. Records pointed by these values cannot be used directly as an attribute of the corresponding records in the other table. Data query needs a multi-table join or a subquery, which is complicated to code and inefficient to run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 5&lt;/strong&gt;: Find male employees whose managers are female.&lt;/p&gt;

&lt;p&gt;Through multi-table join:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select A.* from employee A, department B, employee C where A.department=B.department and B.manager=C.name and A.gender='male' and C.gender='female'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Through subquery:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select * from employee where gender='male' and department in (select department from department where manager in (select name from employee where gender='female'))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the department field of the employee table is the foreign key pointing to records of the department table and the manager field of the department table is the foreign key that points to records of the employee table, the query condition can be written in the following simple, intuitive and efficient way:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;where gender='male' and department.manager.gender='female'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;SQL can only use a multi-table join or a subquery to generate difficult to understand statements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 6&lt;/strong&gt;: Find the companies where employees obtained their first jobs.&lt;/p&gt;

&lt;p&gt;Through multi-table join:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select name, company, first_company from(select employee.name name, resume.company company, row_number()over(partition by resume. name order by resume.start_date) work_seq from employee, resume where employee.name = resume.name) where work_seq=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Through subquery:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;select name, (select company from resume where name=A.name and start date=(select min(start_date) from resume where name=A.name)) first_company from employee A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;SQL is also unable to treat the sub table as an attribute (field) of the primary table because it lacks object reference method and has inadequate set-orientation. A query on the sub table uses either a multi-table join, which makes the statement particularly complex and needs to align the result set to records of the primary table in a one-to-one relationship through a filtering or grouping operation (since records of the joining result set has such a relationship with the sub table), or a subquery that calculates ad hoc the subset of records of the sub table related to each record in the primary table one by one – which increases amount of computations (the subquery cannot use the WITH subclause) and coding difficulty.&lt;/p&gt;

&lt;h2&gt;
  
  
  SPL as the solution
&lt;/h2&gt;

&lt;p&gt;SQL problems need to have a solution.&lt;/p&gt;

&lt;p&gt;Actually, the above analysis implies a way out. That is, designing a new language that gets rid of those SQL weaknesses.&lt;/p&gt;

&lt;p&gt;And this is the original intention of creating SPL.&lt;/p&gt;

&lt;p&gt;SPL is the abbreviation for Structured Process Language while SQL’s full name is Structured Query Language. It is an open-source programming language intended to facilitate structured data computations. SPL emphasizes orderliness and supports object reference method to achieve complete set-orientation, sharply reducing the difficulty of “algorithm translation”.&lt;/p&gt;

&lt;p&gt;Here we just present SPL code of the 6 tasks in the previous section, giving you a glance of the language’s elegance and conciseness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 1&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdm0qe5dp5nco3a1zfmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdm0qe5dp5nco3a1zfmi.png" alt="Image description" width="800" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 2&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9acuo88b4iryclmd0l6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9acuo88b4iryclmd0l6.png" alt="Image description" width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is easy for SPL to code an intuitive and direct algorithm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 3&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh2biwswtcpsffpruu6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh2biwswtcpsffpruu6r.png" alt="Image description" width="800" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL keeps result set of the grouping operation to further process it as it handles a regular set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 4&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9ctju9wtgpj6j0k0ml9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9ctju9wtgpj6j0k0ml9.png" alt="Image description" width="800" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL writes the code smoothly as the intuitive algorithm unfolds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 5&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yr02wm0nw38puz12nhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1yr02wm0nw38puz12nhk.png" alt="Image description" width="800" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the support of object reference, it is convenient for SPL to access a field of the record pointed by the foreign key as it gets one of its original fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task 6&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55qsgb9ozvddmd9qmq84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55qsgb9ozvddmd9qmq84.png" alt="Image description" width="800" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL allows treating a set of records of the sub table as a field of the primary table and accesses it in the same way of getting its other fields, avoiding repeated computations on the sub table.&lt;/p&gt;

&lt;p&gt;SPL has an intuitive IDE that offers convenient debug functionalities to track each step for processing a query, making coding even easier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1rtvswa7enygw2sd9eq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1rtvswa7enygw2sd9eq.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a computation within an application, SPL offers the standard JDBC driver to be integrated with the application, such as JAVA, as SQL does:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;… Class.forName("com.esproc.jdbc.InternalDriver"); Connection conn =DriverManager.getConnection("jdbc:esproc:local://"); Statement st = connection.(); CallableStatement st = conn.prepareCall("{call xxxx(?,?)}"); st.setObject(1,3000); st.setObject(2,5000); ResultSet result=st.execute(); ...&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SPL: a database language featuring easy writing and fast running</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Mon, 13 Feb 2023 10:28:05 +0000</pubDate>
      <link>https://dev.to/sushrutkm/spl-a-database-language-featuring-easy-writing-and-fast-running-59ke</link>
      <guid>https://dev.to/sushrutkm/spl-a-database-language-featuring-easy-writing-and-fast-running-59ke</guid>
      <description>&lt;h2&gt;
  
  
  Objective of database language
&lt;/h2&gt;

&lt;p&gt;To clarify this objective, we need to first understand what the database does.&lt;/p&gt;

&lt;p&gt;When it comes to database, it always makes people think that it is primarily for storage since its name has a part “base”. But in fact, it is not the case, database can achieve two important functions: &lt;strong&gt;calculation and transaction&lt;/strong&gt;, which are what we often call OLAP and OLTP. The storage of database is intended for these two functions, and just serving as a storing role is not the objective of database.&lt;/p&gt;

&lt;p&gt;As we know, SQL is currently the mainstream database language. So, is it convenient to do such two things in SQL?&lt;/p&gt;

&lt;p&gt;The transaction function is mainly to solve the consistency of data during writing and reading. Although it is hard to achieve, its interface is very simple for applications, and the code for manipulating the reading and writing of database is also very simple. If it is assumed that the current logical storage scheme of relational database was reasonable (that is, using the data tables and records to store data. Whether it is reasonable or not is another complicated issue, which will not be discussed in detail here), then it would not be a big problem for SQL to describe the transaction function, because there is no need to describe complex action, and the complexity is already solved in the database.&lt;/p&gt;

&lt;p&gt;As for the calculation function, however, the situation will be different.&lt;/p&gt;

&lt;p&gt;The calculation we are talking about here is a broader concept. It is not just simple addition and subtraction, the search and association can all be regarded as some calculation.&lt;/p&gt;

&lt;p&gt;So here comes a question, what kind of computing system is good?&lt;/p&gt;

&lt;p&gt;Two characteristics needed: &lt;strong&gt;easy in writing, fast in running&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Easy in writing is easy to understand, which is to allow programmers to write code quickly so that more work can be done per unit of time; while for fast in running, it is easier to understand since we definitely hope to get the calculation results in a shorter time.&lt;/p&gt;

&lt;p&gt;Actually, the Q in SQL represents query. The original purpose of inventing SQL is to query (i.e., calculation), which is the main goal of SQL. However, it is hard to say that SQL is very competent when describing computing tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SQL is not competent
&lt;/h2&gt;

&lt;p&gt;Let’s start with easy in writing.&lt;/p&gt;

&lt;p&gt;The code written in SQL is very much like English, and some queries can be read and written in English (there are so many examples on the Internet, so we won’t give examples here). This should be regarded as satisfying the requirement of easy in writing.&lt;/p&gt;

&lt;p&gt;Wait a minute! The code written in SQL we see in textbooks often has only two or three lines, it is indeed simple, but what if we try to solve some slightly more complicated problems?&lt;/p&gt;

&lt;p&gt;Here is an example that is actually not very complicated: calculate the maximum consecutive days that a stock keeps rising. Write it in SQL is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;max&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consecutive_day&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consecutive_day&lt;/span&gt;
      &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rise_mark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;trade_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;days_no_gain&lt;/span&gt;
            &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;trade_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;closing_price&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;closing_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;trade_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                              &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;rise_mark&lt;/span&gt;
                  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;stock_price&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;days_no_gain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The working principle of this statement won’t be explained here, it's a little confusing anyway. You can try it yourself.&lt;/p&gt;

&lt;p&gt;This is a recruitment test of Raqsoft company, with a pass rate of less than 20%; Because it is too difficult, it is later changed to another testing way: ask the candidate to explain what the written SQL statement is, but unfortunately, the pass rate is still not high.&lt;/p&gt;

&lt;p&gt;What does it reveal? It reveals that the situation is slightly complicated, and SQL becomes difficult to both understand and write!&lt;/p&gt;

&lt;p&gt;Let's look at the issue of fast in running, and take the simple task that is often used as an example: take the top 10 out of 100 million pieces of data. This task is not complicated to write in SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TOP&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;However, the execution logic corresponding to this statement is to perform the big sorting for all the data first, and then take the top 10, and discard the remaining data. As we all know that sorting is a very slow action, and will traverse the data many times. If the amount of data is too large to be loaded into memory, it also needs to buffer the data in external storage, resulting in a further sharp decrease in performance. If the logic embodied in this statement is strictly followed, the operation will not run fast anyway. Fortunately, many programmers know that this operation does not need the big sorting, nor the external storage to buffer since it can be done by traversing only once and only occupying a little memory space, it means a higher performance algorithm exists. Regrettably, such algorithm can't be implemented in SQL. We can only hope the database optimizer is smart enough to convert this SQL statement to a high-performance algorithm to execute, but the database optimizer may not be reliable when the situation is complicated.&lt;/p&gt;

&lt;p&gt;It seems that SQL is not doing well in both aspects. Although these two examples are not very complicated, SQL does not perform well in either example. In reality, the difficult-to-write and slow running situation abounds in SQL codes with thousands of lines.&lt;/p&gt;

&lt;p&gt;Then, why these two aspects cannot be well achieved in SQL?&lt;/p&gt;

&lt;p&gt;To answer this question, we need to analyze what exactly the implementation of calculation with program code does.&lt;/p&gt;

&lt;p&gt;Essentially, &lt;strong&gt;the process of programming is the process of translating problem-solving idea into a precise formal language executable by the computer&lt;/strong&gt;. For example, just like solving an applied problem by a primary school student, the student also needs to list an expression relating to four basic arithmetic operations after analyzing the problem and coming up with a solution. Likewise, for the calculation with the program, not only does the solution need to be come up with, but it also needs to translate the solution into actions that can be understood and executed by the computer.&lt;/p&gt;

&lt;p&gt;For the formal language used to describe calculation method, its core lies in the algebraic system adopted. To put it simply, the so-called algebraic system includes two key elements: data types and corresponding operation rules. For instance, the key elements of arithmetic we learned in primary school is the integer and the operations including the addition, subtraction, multiplication and division. Once we get both key elements, we can write the operation we want with the symbols stipulated in the algebraic system to something, i.e., the code, and then the computer can execute.&lt;/p&gt;

&lt;p&gt;If an algebraic system is not well designed, causing the provided data types and operations to be inconvenient, it will make it very difficult to describe the algorithm. In this case, a strange phenomenon will occur: &lt;strong&gt;the difficulty of translating the solution into the code is far more than solving the problem itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, we learned to use Arabic numerals for daily calculation in our childhood, and using such numerals is very convenient to do addition, subtraction, multiplication and division, and hence everyone naturally believes that numerical operation should be like this. Are all numerical operations so convenient? Not necessarily! It is estimated that many people know there is another numeral called Roman numeral. Do you know how to add, subtract, multiply and divide with Roman numerals? And how did the ancient Romans go to the streets for shopping?&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The reason why coding is difficult is largely due to algebra.&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's look at the reason for not running fast.&lt;/p&gt;

&lt;p&gt;Software cannot change the performance of hardware; the speed of CPU and hard disk depends on their own configuration. However, we can design an algorithm of low complexity, that is, an algorithm with a smaller amount of calculation, so that the computer executes less actions, and thus the running speed will be faster naturally. Yet, just working out the algorithm is not enough, we also need to program the algorithm in some formal language, otherwise the computer won't execute. Moreover, it needs to be relatively simple to code. If the code in a certain formal language is very long, it will be very troublesome and no one will use such formal language. Therefore, for the program, &lt;strong&gt;easy in writing and fast in running are actually the same problem&lt;/strong&gt;, behind which is the algebra adopted by the formal language. If the algebra is not good, it will make it difficult or even impossible to implement high-performance algorithm, as a result, there is no way to run fast. As mentioned above, our desired algorithm of occupying a little memory space and traversing only once cannot be implemented in SQL. Consequently, if you want it to run fast, you can only place hope on the optimizer.&lt;/p&gt;

&lt;p&gt;Let's make another analogy:&lt;/p&gt;

&lt;p&gt;Students who have gone to primary school probably know the story of Gauss calculating 1+2+3+…+100. Ordinary students adopted the most primitive method, which was to add 100 times step by step, while little Gauss was very smart, he found that 1+100=101, 2+99=101,…,50+51=101, from which he multiplied 50 by 101, and hence quickly figured out the result and then headed home for lunch.&lt;/p&gt;

&lt;p&gt;After hearing this story, we all felt that Gauss was so clever that he thought of such an ingenious solution, which is simple and fast. Yes, that’s right, but it is easy to overlook one point: in the days of Gauss, multiplication already existed in the human arithmetic system (also an algebra)! As mentioned earlier, since we learned four arithmetic operations in our childhood, and hence we would take it for granted that multiplication should be used. But it is not, actually! Multiplication was invented after addition. If multiplication had not yet been invented in the days of Gauss, he wouldn’t have found a way to solve this problem quickly no matter how clever Gauss was.&lt;/p&gt;

&lt;p&gt;At present, the mainstream database is the relational database, and the reason why it is called this way is because its mathematical basis is called relational algebra. SQL is exactly a formal language developed from the theory of relational algebra.&lt;/p&gt;

&lt;p&gt;Now we can answer why SQL is not competent in both aspects we expect. &lt;strong&gt;The problem lies in relational algebra&lt;/strong&gt;, and the relational algebra is just like an arithmetic system with only addition and no multiplication. Therefore, it is inevitable that many things cannot be done well.&lt;/p&gt;

&lt;p&gt;Relational algebra has been invented for fifty years. The difference between the application requirements and hardware environments of fifty years ago and today is very huge. Continuing to apply the theory of fifty years ago to solve today's problems, does it sound too outdated? However, this is the reality. Due to the large number of existing users and the lack of mature new technologies, SQL, based on relational algebra, is still the most important database language today. Although some improvements have been made in recent decades, the foundation has not changed. In the face of contemporary complex requirements and hardware environments, it is reasonable that SQL is incompetent.&lt;/p&gt;

&lt;p&gt;And, unfortunately, this problem is at the theoretical level, and it won't help no matter how optimized it is in practice, it can only be improved in a limited way, not eradicated. Regrettably, most database developers do not think of this level, or, in order to take care of the compatibility of existing users, they do not intend to think about this level. As a result, the mainstream database industry has been going around in circles in this limited space.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why SPL is competent
&lt;/h2&gt;

&lt;p&gt;Now then, how to make the calculation Easier in Writing and Faster in Running?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invent new algebra&lt;/strong&gt;! An algebra with “multiplication”, and then design a new language based on the new algebra.&lt;/p&gt;

&lt;p&gt;This is where SPL comes from. Its theoretical basis is no longer the relational algebra, but something called discrete dataset. The formal language designed based on this new algebra is named SPL (structured process language).&lt;/p&gt;

&lt;p&gt;Innovations against the shortcomings of SQL have been made to SPL (more precisely, innovations against various deficiencies of relational algebra have been made to the discrete dataset). SPL redefines and extends many operations of structured data, specifically, it adds the discreteness, enhances ordered computation, implements a thorough set orientation, supports object references, and advocates stepwise operation.&lt;/p&gt;

&lt;p&gt;Recoding the previous problems in SPL will give you a direct feeling.&lt;/p&gt;

&lt;p&gt;Calculate the maximum consecutive days that a stock keeps rising:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;stock_price&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trade_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;group&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;closing_price&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;closing_price&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="k"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Although the calculation idea is the same as the previous SQL, it is much easier to express and no longer confusing, because of the introduction of ordering characteristic.&lt;/p&gt;

&lt;p&gt;Take the top 10 out of 100 million pieces of data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;(;&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SPL has richer set data types, it is easy to describe the efficient algorithm that implements simple aggregation on a single traversal, without involving big sorting action.&lt;/p&gt;

&lt;p&gt;Due to space limitations, we will not introduce SPL (discrete dataset) in an all-round way here, but will list some differential improvements of SPL (discrete dataset) against SQL (relational algebra):&lt;/p&gt;

&lt;h3&gt;
  
  
  Discrete records
&lt;/h3&gt;

&lt;p&gt;The records in the discrete dataset are a basic data type that can exist independently of the data table. The data table is a set constituted by records, and the records that make up a certain data table can also be used to make up other data tables. For example, the filtering operation is to use the records that meet the conditions in original data table to make up a new data table, in this way, it has more advantages in both space occupation and operation performance.&lt;/p&gt;

&lt;p&gt;The relational algebra has no computable data type to represent the record. A single record is actually a data table with only one row, and records in different data tables must not be same. For example, during the filtering operation, new records will be duplicated to form a new data table, it will result in an increase in the costs of space and time.&lt;/p&gt;

&lt;p&gt;In particular, because there are discrete records, the discrete dataset allows record’s field value to be a certain record, which makes it easier to implement foreign key join.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ordering characteristic
&lt;/h3&gt;

&lt;p&gt;Relational algebra is designed based on unordered sets, and the set members do not have the concept of sequence number. Moreover, it doesn’t provide the mechanism of positioning calculation and adjacent reference. In practice, SQL has made some partial improvements, allowing the modern SQL to easily do some ordered operations.&lt;/p&gt;

&lt;p&gt;On the contrary, the sets in discrete dataset are ordered, and all set members have the concept of sequence number and can be accessed with sequence number. Moreover, the discrete dataset defines the positioning operation so as to return the sequence number of members in the set. Also, the discrete dataset provides symbols to implement adjacent reference in set operation, and supports the calculation according to the position of a certain sequence number in the set.&lt;/p&gt;

&lt;p&gt;Ordered operation is very common, but it has always been a difficult for SQL. The implementation of ordered operation in SQL is still very cumbersome even with window functions available. SPL has greatly improved this situation, which can be illustrated by the previous example of stock rising.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discreteness and set orientation
&lt;/h3&gt;

&lt;p&gt;The relational algebra defines rich set operations, that is, it can take the set as a whole to participate in operations such as aggregation and grouping. This is where SQL is more convenient than high-level programming languages like Java.&lt;/p&gt;

&lt;p&gt;However, the relational algebra has very poor discreteness and no discrete records, while high-level programming languages such as Java have no problem in this regard.&lt;/p&gt;

&lt;p&gt;As for the discrete dataset, it is equivalent to combining discreteness with set orientation, which means that it has not only the set data type and related operations, but also the set members that separate out of the set to do independent operation or form other sets. Therefore, it can be said that SPL integrates the advantages of both SQL and Java.&lt;/p&gt;

&lt;p&gt;Ordered operation is a typical scenario that combines discreteness with set orientation. The concept of order is meaningful only for a set and meaningless for a single member, which reflects the set orientation; the ordered operation needs to calculate a certain member and its adjacent members, which requires discreteness.&lt;/p&gt;

&lt;p&gt;Only with the support of discreteness can we obtain more thorough set orientation, and solve problems like ordered operation.&lt;/p&gt;

&lt;p&gt;In short, the discrete dataset is an algebraic system with both discreteness and set orientation, while relational algebra has only set orientation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding of grouping
&lt;/h3&gt;

&lt;p&gt;The original intention of the grouping operation is to split a large set into several subsets according to some rules. In relational algebra, since there is no data type that can represent the set of sets, it has to do the aggregation operation after grouping.&lt;/p&gt;

&lt;p&gt;Conversely, the discrete dataset allows the set of sets, it can represent reasonable grouping operation result. The grouping operation and the aggregation operation after grouping are split into two-step independent operations. In this way, more complex operation can be performed on the grouped subsets.&lt;/p&gt;

&lt;p&gt;In relational algebra, there is only one kind of equivalence grouping, that is, the sets are divided according to the grouping key value. The equivalence grouping is a complete division.&lt;/p&gt;

&lt;p&gt;For the discrete dataset, however, it thinks that any method of splitting a large set is a grouping operation. In addition to the conventional equivalence grouping, it also provides the ordered grouping combined with ordering characteristic, as well as the aligned grouping that may get incomplete division result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding of aggregation
&lt;/h3&gt;

&lt;p&gt;There is no explicit set data type in relational algebra. The results of aggregation calculation are all a single value, so does the aggregation operation after grouping, only including SUM, COUNT, MAX, MIN etc. Particularly, the relational algebra cannot regard TOPN operation as an aggregation. The TOPN operation performed on the whole set can only take the first N items following the sorting when outputting the result set. However, for the grouped subsets, it is difficult to implement TOPN, in this case, it needs to change idea and work out the sequence number to achieve.&lt;/p&gt;

&lt;p&gt;The discrete dataset advocates the universal set, and the aggregation operation result is not necessarily a single value, but may still be a set. In discrete dataset, the TOPN operation has the same status as SUM and COUNT, etc., that is, it can be performed on the whole set or on the grouped subsets.&lt;/p&gt;

&lt;p&gt;After SPL regards TOPN as the aggregation operation, it can also avoid the sorting of all data in practice, hereby obtaining high performance. However, the TOPN in SQL is always accompanied by ORDER BY action. In theory, it can only be implemented by big sorting, in this case, you need to place hope on the optimization of database in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  High performance supported by ordering characteristic
&lt;/h3&gt;

&lt;p&gt;The discrete dataset places special emphasis on ordered set, and can implement many high-performance algorithms using ordered characteristic. This cannot be implemented by relational algebra based on unordered sets, and you can only hope for optimization in practice.&lt;/p&gt;

&lt;p&gt;The following are some low-complexity operations that can be implemented using ordering characteristic:&lt;/p&gt;

&lt;p&gt;1) The data table is ordered by the primary key, which is equivalent to having an index naturally. Filtering of key fields can often be quickly located to reduce the traversal amount in external storage. When fetching the data randomly by key value, the binary search can also be used for positioning; the index information can be reused in case of data-fetching by multiple key values at the same time.&lt;/p&gt;

&lt;p&gt;2) Usually, the grouping operation is implemented with the HASH algorithm. If we are sure that the data are ordered by the grouping key value, we only need to do the adjacent comparison, hereby avoiding the calculation of HASH value, in this way, there will be no HASH conflict problem, and it is very easy to perform parallel computing.&lt;/p&gt;

&lt;p&gt;3) The data table is ordered by the key, the merge algorithm with higher performance can be used for the alignment join between two large tables. In this way, we only need to traverse the data once, without the need to buffer the data, and thus it makes the memory occupation less. Yet, not only is the conventional HASH value partitioning method relatively complicated, requiring more memory and data buffering in external storage, but it also may cause secondary HASH and re-buffering due to improper hash function.&lt;/p&gt;

&lt;p&gt;4) The join of large table as foreign key table. When the fact table is small, the foreign key table can be used to order, from which the data corresponding to the associated key value are quickly taken out to achieve join, and there is no need to do HASH partitioning. When the fact table is also large, we can divide the foreign key table into multiple logical segments by quantile, and then partition the fact table by logical segment. In this way, only one table needs to be partitioned, and the secondary partitioning, which may occur during HASH partitioning, will not occur in the process of partitioning, and thus the computational complexity greatly decreases.&lt;/p&gt;

&lt;p&gt;Items 3)and 4) above exploit the modification of the join operation in discrete dataset. If we continue to use the definition in relational algebra (which may produce many-to-many), it is difficult to implement such low-complexity algorithms.&lt;/p&gt;

&lt;p&gt;In addition to theoretical differences, SPL has many engineering-level advantages such as: easier to write parallel computing code, large memory pre-association to improve foreign key join performance, unique column storage mechanism to support arbitrary segmentation and parallel computing, etc.&lt;/p&gt;

&lt;p&gt;In the era of big data, we are often interested in high performance computation. Here are some big data algorithms implemented in SPL:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1571218947381" rel="noopener noreferrer"&gt;Performance optimization skill: Multi-purpose traversa&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1571217482491" rel="noopener noreferrer"&gt;Performance optimization skill: TopN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1578990230409" rel="noopener noreferrer"&gt;Performance optimization skill: Pre-Joining&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1577758685313" rel="noopener noreferrer"&gt;Performance optimization skill: Numberizing Foreign Key&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1584935117965" rel="noopener noreferrer"&gt;Performance optimization skill: Attached Table&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1585881236616" rel="noopener noreferrer"&gt;Performance optimization skill: One-side Partition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;......&lt;/p&gt;

&lt;p&gt;And some high performance cases:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1642763952755" rel="noopener noreferrer"&gt;Open-source SPL Speeds up Query on Detail Table of Group Insurance by 2000+ Times &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1643105108043" rel="noopener noreferrer"&gt;Open-source SPL improves bank’s self-service analysis from 5-concurrency to 100-concurrency&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1643333049458" rel="noopener noreferrer"&gt;Open-source SPL speeds up intersection calculation of customer groups in bank user profile by 200+ times&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1643533607375" rel="noopener noreferrer"&gt;Open-source SPL turns pre-association of query on bank mobile account into real-time association&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1644215913288" rel="noopener noreferrer"&gt;Open-source SPL speeds up batch operating of bank loan agreements by 10+ times&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://c.raqsoft.com/article/1644827119694" rel="noopener noreferrer"&gt;Open-source SPL optimizes batch operating of insurance company from 2 hours to 17 minutes&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;SPL Official Website 👉 &lt;a href="http://www.scudata.com" rel="noopener noreferrer"&gt;http://www.scudata.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL Feedback and Help 👉 &lt;a href="https://www.reddit.com/r/esProc" rel="noopener noreferrer"&gt;https://www.reddit.com/r/esProc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL Learning Material 👉 &lt;a href="http://c.raqsoft.com" rel="noopener noreferrer"&gt;http://c.raqsoft.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SPL Source Code and Package 👉 &lt;a href="https://github.com/SPLWare/esProc" rel="noopener noreferrer"&gt;https://github.com/SPLWare/esProc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Becoming a Community Manager: A Super Lucrative Career</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Fri, 03 Feb 2023 04:16:56 +0000</pubDate>
      <link>https://dev.to/sushrutkm/becoming-a-community-manager-a-super-lucrative-career-31lf</link>
      <guid>https://dev.to/sushrutkm/becoming-a-community-manager-a-super-lucrative-career-31lf</guid>
      <description>&lt;p&gt;Community management is a crucial aspect of modern business and an increasingly in-demand skill. Community managers are responsible for fostering online communities, promoting brand awareness, and managing customer relationships. They are the voice of the company and play a vital role in building and maintaining customer trust and loyalty. If you are interested in becoming a community manager, this guide will provide you with the essential steps to get started.&lt;/p&gt;

&lt;p&gt;I became a community manager by chance. After earning my degree in Computer Science, I started working for a big MNC as a Salesforce Developer. My interest quickly shifted to content creation and I started doing it part-time. I discovered that I had a passion for community building and decided to pursue a career in community management. Through a bit of hard work and continuous bugging founders, I was able to start a career and make a positive impact on the communities I serve.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Gain an Understanding of the Industry
&lt;/h2&gt;

&lt;h4&gt;
  
  
  The Importance of Familiarizing Yourself with the Industry
&lt;/h4&gt;

&lt;p&gt;The first step to becoming a community manager is to understand the industry. Learn about the different platforms, tools, and best practices used in community management. Familiarize yourself with social media platforms like Twitter, Facebook, Instagram, and LinkedIn, as well as customer relationship management (CRM) systems like Hootsuite and Sprout Social. Read articles, attend webinars, and follow influencers in the field to stay up-to-date on industry trends and developments.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build Your Skills
&lt;/h2&gt;

&lt;h4&gt;
  
  
  The Essential Skills for Community Management
&lt;/h4&gt;

&lt;p&gt;Community management requires a unique set of skills, including strong communication and interpersonal skills, creativity, and an understanding of customer behavior. To build your skills, start by volunteering to manage social media accounts for non-profit organizations or small businesses. This will give you hands-on experience and help you develop your skillset. Consider taking online courses or earning certifications in social media management, digital marketing, or customer service.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Create a Strong Online Presence
&lt;/h2&gt;

&lt;h4&gt;
  
  
  The Importance of Personal Branding for Community Managers
&lt;/h4&gt;

&lt;p&gt;Community managers are responsible for representing a brand online, so it's essential to have a strong online presence. Create professional profiles on social media platforms, and make sure your profiles reflect the brand you are trying to represent. Be active on social media and engage with others in your community. This will help you develop a personal brand and build your reputation as a community manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Network with Other Community Managers
&lt;/h2&gt;

&lt;h4&gt;
  
  
  The Benefits of Building a Professional Network
&lt;/h4&gt;

&lt;p&gt;Networking is an important part of any career, and community management is no exception. Attend industry events, join online communities, and connect with other community managers on social media. Share your experiences, ask for advice, and learn from others in the field. Building a network of colleagues and peers can help you stay up-to-date on industry trends and provide valuable support as you grow in your career.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Find a Job or Freelance Opportunities
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Options for Building Your Career as a Community Manager
&lt;/h4&gt;

&lt;p&gt;Once you have developed your skills and built a strong online presence, it's time to start looking for job opportunities. Check job boards, such as LinkedIn and Indeed, for open positions. Consider freelancing or starting your own business as a community manager. This will give you the flexibility to work with multiple clients and gain a broader range of experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, becoming a community manager requires a combination of skills, experience, and personal branding. By following the steps outlined in this guide, you can build a successful career in community management. Remember to stay up-to-date on industry trends, network with other community managers, and continue to develop your skills and online&lt;/p&gt;

</description>
      <category>playlist</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>How I Built a Side-Income Stream For Myself as a Developer</title>
      <dc:creator>Sushrut Mishra</dc:creator>
      <pubDate>Sat, 17 Sep 2022 16:34:31 +0000</pubDate>
      <link>https://dev.to/sushrutkm/how-i-built-a-side-income-stream-for-myself-as-a-developer-461d</link>
      <guid>https://dev.to/sushrutkm/how-i-built-a-side-income-stream-for-myself-as-a-developer-461d</guid>
      <description>&lt;p&gt;Being a developer in this century is not as shallow as just getting into development, working on projects, sitting for interviews, getting a job, and working in it for the rest of your life. It was the case a decade ago, but not today! No, not in a mile. &lt;/p&gt;

&lt;p&gt;I too started my college with the same motive and I kept believing in it throughout my college life. I studied all the subjects, got enough marks, learnt enough DSA, and sat for placements. I even got a job as a Salesforce Developer! But then, I began to understand that I was wrong. This is not what I want to do for the rest of my life. That 9-to-5 underpaying job could never make me happy, neither it could suffice my needs.&lt;/p&gt;

&lt;p&gt;I’m pretty sure it is/was the same for you. I get it and this blog post is about how I went on a rampage and built a side-hustle for myself with my developer skills and knowledge. &lt;/p&gt;

&lt;p&gt;If this sounds interesting to you. Let's hop in -&lt;/p&gt;

&lt;h2&gt;
  
  
  I Started After College
&lt;/h2&gt;

&lt;p&gt;When I passed out of college, it was COVID and everyone was trapped at home. People had more time than ever. More time to learn, earn, think, revamp, and whatnot. This is when I consciously wanted to devote my time to better places. I already had much stress over my underpaying job and I desperately wanted to change it. Hence, I got active in the developer's community. &lt;/p&gt;

&lt;p&gt;It was June 2021, I joined Twitter, started talking with other developers, and learnt about their stories. I came to realise that the world is not just about jobs anymore. I was amazed and fabled! One of my friends advised me to learn trending development skills and create content around that. With a hard knock of reality and a boost of motivation, I started my content creation journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Birth of my Side-Hustles as a Developer
&lt;/h2&gt;

&lt;p&gt;I had three things in my head and I focused only on those. The below-mentioned three factors helped me create side-income streams for myself: &lt;/p&gt;

&lt;h3&gt;
  
  
  Tweets and Threads
&lt;/h3&gt;

&lt;p&gt;I never thought I’d use Twitter unless my friend Swastika introduced me to it. She told me about the tech Twitter community and the opportunities I might get. Therefore, I started creating content on Twitter around June 2021. I was learning front-end development (HTML, CSS, and JavaScript to be precise) at that time. This was it. &lt;/p&gt;

&lt;p&gt;I started tweeting about the topics and concepts I learned, the projects I made, and the resources I used. It was like learning and teaching at the same time. A few months passed, and I kept revamping my content around different topics, frameworks, and technologies. &lt;/p&gt;

&lt;h4&gt;
  
  
  How did it help?
&lt;/h4&gt;

&lt;p&gt;Creating and consuming content on Twitter helped me gain confidence, polish my writing skills, and of course my frontend development skills. The urge to compete with other developers, improve my skills, and build a side income helped me stay consistent. One of my networks on Twitter, Muthu referred me to a freelance job that earned me thousands of dollars.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Articles
&lt;/h3&gt;

&lt;p&gt;I couldn’t help but notice that many developers were publishing articles online. My talks with a few of them established that writing and publishing technical articles online brings in a load of opportunities. Without any further delay, I started writing technical articles and published them on various platforms like Dev Community, Hashnode, and Showwcase.&lt;/p&gt;

&lt;p&gt;I wrote on a variety of topics, from web development and blockchain to Salesforce and development tools. Months passed and it was November 2021, knowingly or unknowingly, I had a portfolio of tens of articles and thousands of tweets published online. I was sitting on a decent Twitter following, developer networks on Twitter, and a portfolio of published technical articles.&lt;/p&gt;

&lt;h4&gt;
  
  
  How did it help?
&lt;/h4&gt;

&lt;p&gt;Having a portfolio of articles fetched me a lot of freelance technical writing gigs. I started taking up work and soon my bio stated “Technical Writer”. Those writing gigs allowed me to learn different technologies, write about them, code in them, and develop with them. I was only increasing my knowledge base and filling my bank account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upskilling at Job
&lt;/h3&gt;

&lt;p&gt;Besides all the networking, content creation, and writing, I was upskilling myself during the job. I was delivering tasks, learning new things, and collecting certificates. It was December 2021, and I became a 2 times-certified Salesforce Developer. I posted about Salesforce concepts and my learnings on LinkedIn. People started recognizing me as their potential Salesforce freelancer. &lt;/p&gt;

&lt;p&gt;I even got a high-paying offshore client because of my knowledge and portfolio in Salesforce. It involved development and content creation both.&lt;/p&gt;

&lt;h4&gt;
  
  
  How did it help?
&lt;/h4&gt;

&lt;p&gt;Alongside my full-time job, I got the opportunity to perform the same tasks as a freelancer with much better money and work-life balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  My framework for Side-Income as a Developer
&lt;/h2&gt;

&lt;p&gt;This is August 2022 and I’ve been in this side-hustle race for more than a year now. I followed some specific steps that fetched me my side income and I know for sure that this framework has helped thousands of developers. &lt;/p&gt;

&lt;p&gt;I’d followed this religiously and I’ve seen results. Many have seen growth manifolds and several made their fortune. This is a 3-step framework - Upskill, Create, Network.&lt;/p&gt;

&lt;p&gt;Recognize your skills and polish them to a certain extent. Side hustle never meant easy money, it means ‘more money with more skills’.&lt;/p&gt;

&lt;p&gt;This is the digital era and the world is online. If you’re not online and if you’re not creating content (text, pictorial, or video graphics), you’re missing out. Start creating content online. Pick platforms like Showwcase, Twitter, Hashnode, there are plenty.&lt;/p&gt;

&lt;p&gt;Network with like-minded people and people in the same industry as yours. You never know who’s a God-sent Angel. We are humans and humans are social beings. So network as much as you can.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Favorite Side-Income Streams
&lt;/h2&gt;

&lt;p&gt;I’ve done many jobs and worked in multiple sectors. But the following are my favorite:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Writing:&lt;/strong&gt; I’ve been a technical writer for about 6 months and these six months have made me more money than my one-year full-time job at an MNC. No matter what tech stack you have, technical writing will always find a way if you just start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freelance Projects:&lt;/strong&gt; If you are confident in your skills and can get the job done, picking up freelance or contractual jobs can fetch you more money than a regular job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DevRel and Community work:&lt;/strong&gt; This particular sector is on fire! Imagine getting paid for helping and connecting with fellow developers, creating content, writing code, and of course getting paid for it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To conclude, if you are a developer, and can come online, and make yourself visible to the world, the opportunities are endless for you. It worked for me, it worked for many, and it shall work for you as well. This was my story of side-income as a developer and I’d love to hear yours in the comment section. &lt;/p&gt;

&lt;p&gt;And oh! If you feel you’ve got any value from this blog, give it a like. I’ll know I’ve been of help.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
