<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Google - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Google - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 25 Aug 2026 16:17:06 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/google/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Make Your Antigravity Agent Skills Configurable (Without Forking Them) ]]>
                </title>
                <description>
                    <![CDATA[ Antigravity Agent Skills are a great way to teach your AI agent a workflow once and reuse it everywhere. You write a short SKILL.md file, drop it in a folder, and the agent picks it up whenever it's r ]]>
                </description>
                <link>https://www.freecodecamp.org/news/make-your-antigravity-agent-skills-configurable-without-forking-them/</link>
                <guid isPermaLink="false">6a69c58763daca7bbbf2320b</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Antigravity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Obum ]]>
                </dc:creator>
                <pubDate>Wed, 29 Jul 2026 09:19:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/7edaf407-ce56-4eff-8b1c-5e1c31e71067.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Antigravity Agent Skills are a great way to teach your AI agent a workflow once and reuse it everywhere. You write a short <code>SKILL.md</code> file, drop it in a folder, and the agent picks it up whenever it's relevant.</p>
<p>But these skills have a hidden limitation: they're static. If you download a skill someone else wrote and you want it to behave a little differently, you'll have to copy the whole thing and edit it by hand. And as you may have noticed lately, there are many "skills" forks floating around that are difficult to maintain.</p>
<p>In this tutorial, I'll show you I built a small convention that fixes this. It lets any Agent Skill read a per-project config file, so you can adopt any skill and customize how it behaves by editing a few lines of YAML (without ever touching the skill itself).</p>
<p>You'll build it step by step, test it, and see how to share it so other people can plug into it.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-you-will-build">What You Will Build</a></p>
</li>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-what-are-antigravity-agent-skills">What Are Antigravity Agent Skills</a>?</p>
</li>
<li><p><a href="#heading-why-static-skills-are-a-problem">Why Static Skills Are a Problem</a></p>
</li>
<li><p><a href="#heading-the-configurable-skills-solution">The Configurable Skills Solution</a></p>
</li>
<li><p><a href="#heading-how-to-build-the-config-loader">How to Build the Config Loader</a></p>
</li>
<li><p><a href="#heading-how-to-make-a-skill-configurable">How to Make a Skill Configurable</a></p>
</li>
<li><p><a href="#heading-how-to-add-project-overrides">How to Add Project Overrides</a></p>
</li>
<li><p><a href="#heading-how-to-test-your-configurable-skill">How to Test Your Configurable Skill</a></p>
</li>
<li><p><a href="#heading-two-more-example-skills">Two More Example Skills</a></p>
</li>
<li><p><a href="#heading-how-to-share-your-agent-skills-with-others">How to Share Your Agent Skills With Others</a></p>
</li>
<li><p><a href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-what-you-will-build">What You Will Build</h2>
<p>You will build a tiny, reusable layer called <strong>Configurable Agent Skills</strong>. It has three parts:</p>
<ol>
<li><p>A small Python script, <code>resolve_config.py</code>, that merges a skill's default settings with your project settings and prints the result.</p>
</li>
<li><p>A convention: each skill ships 2 files, a <code>config.default.yaml</code> file with its "knobs" and a <code>SKILL.md</code> file. They both guide the agent's behavior.</p>
</li>
<li><p>A per-project file, <code>.agent/skills.config.yaml</code>, where anyone using your skill sets their own values.</p>
</li>
</ol>
<p>By the end, you'll have a working <code>git-commit-formatter</code> skill that one team can run in Conventional Commits mode and another team can switch to gitmoji mode, all using the exact same skill files with no forking.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow along, you'll need:</p>
<ul>
<li><p>Google Antigravity installed (the IDE, CLI, or SDK. Any of them work, since skills are just files.).</p>
</li>
<li><p>Python 3 installed, with PyYAML. You can install PyYAML with <code>python -m pip install pyyaml</code>.</p>
</li>
<li><p>Basic comfort with the terminal and YAML. You don't need to be an expert in either.</p>
</li>
</ul>
<p>If you've never written an Agent Skill before, the next two sections will bring you up to speed.</p>
<h2 id="heading-what-are-antigravity-agent-skills">What Are Antigravity Agent Skills?</h2>
<p>A Skill in Antigravity is a folder that contains a <code>SKILL.md</code> file and, optionally, some scripts, templates, or examples. The <code>SKILL.md</code> file has a short block of YAML "frontmatter" at the top (a <code>name</code> and a <code>description</code>), followed by a set of instructions written in plain Markdown.</p>
<p>Here's the important part: skills are loaded on demand. The agent reads only the short <code>description</code> of each skill at first. When your request matches that description, the agent pulls in the full instructions and follows them. This keeps the agent's context small and focused.</p>
<p>A minimal skill that enforces Conventional Commits looks like this:</p>
<pre><code class="language-markdown">---
name: git-commit-formatter
description: Formats git commit messages using the Conventional Commits specification. Use this when the user asks to commit changes or write a commit message.
---

# Git Commit Formatter

When writing a commit message, follow the Conventional Commits format:
`type(scope): description`

Allowed types: feat, fix, docs, style, refactor, perf, test, chore.
</code></pre>
<p>Drop that in your skills folder, ask the agent to "commit these changes," and it will write a properly formatted message. Simple and useful, right?</p>
<h2 id="heading-why-static-skills-are-a-problem">Why Static Skills Are a Problem</h2>
<p>Now look closely at that skill. The allowed types (<code>feat</code>, <code>fix</code>, <code>docs</code>, and so on) are baked directly into the instructions.</p>
<p>That's fine until someone wants something slightly different. Maybe your team also uses a <code>ci</code> type. Maybe you prefer gitmoji, where each commit starts with an emoji. Maybe you want to require a scope on every commit.</p>
<p>With a static skill, there's only one way to get any of that: copy the whole skill and edit the Markdown. When you do this across a team, everyone ends up with their own private fork. When the original author ships an improvement, none of the forks get it. The skill stops being something you <em>share</em> and becomes something everyone <em>rewrites</em>.</p>
<p>The core issue is that there's no clean line between the skill's logic (which everyone should share) and its settings (which each project wants to control). How do we solve this?</p>
<h2 id="heading-the-configurable-skills-solution">The Configurable Skills Solution</h2>
<p>The idea is simple. Instead of hard-coding settings in the instructions, the skill will:</p>
<ol>
<li><p>Ship its settings and their defaults in a separate <code>config.default.yaml</code> file.</p>
</li>
<li><p>Read a merged config (defaults plus any project-level overrides) before it acts.</p>
</li>
</ol>
<p>The project-level overrides live in a file called <code>.agent/skills.config.yaml</code>, which sits at the root of the user's project:</p>
<pre><code class="language-yaml"># .agent/skills.config.yaml 
# (edit this file in your project instead of the skill globally)
git-commit-formatter:
  style: gitmoji
  extra_types: [ci, build]
  scope_required: true
</code></pre>
<p>That's the easy flow. Drop the skill in, set a few keys, and you're done. The skill's own files never change.</p>
<p>To make this work, you need a script that reads both files, merges them, and hands the result to the agent. Let's build it.</p>
<h2 id="heading-how-to-build-the-config-loader">How to Build the Config Loader</h2>
<p>Create a file called <code>resolve_config.py</code>. Its job is to take a skill's name, load that skill's <code>config.default.yaml</code>, find the user's <code>.agent/skills.config.yaml</code>, and merge the two so that user values win.</p>
<p>Start with a deep-merge helper. This is the heart of the loader:</p>
<pre><code class="language-python">def deep_merge(base, override):
    """Recursively merge override onto base.

    Dicts merge key by key. Anything else (scalars, lists) is replaced
    wholesale by the override value.
    """
    if isinstance(base, dict) and isinstance(override, dict):
        merged = dict(base)
        for key, value in override.items():
            merged[key] = deep_merge(merged[key], value) if key in merged else value
        return merged
    return override
</code></pre>
<p>Notice the deliberate choice here: dictionaries merge key by key, but lists are replaced, not appended. That keeps the behavior predictable. If you want to handle "defaults plus extras", use the explicit <code>extra_types</code> key in the skill as you'll see in the example below.</p>
<p>Next, you need to find your "per-project" config. The loader walks up from the current directory looking for an <code>.agent/skills.config.yaml</code> file:</p>
<pre><code class="language-python">from pathlib import Path

def find_project_config(start: Path):
    """Walk upward from start looking for .agent/skills.config.yaml."""
    start = start.resolve()
    for folder in [start, *start.parents]:
        candidate = folder / ".agent" / "skills.config.yaml"
        if candidate.is_file():
            return candidate
    return None
</code></pre>
<p>Now put it together. The loader locates the skill's defaults (which sit next to the script), loads your overrides for that skill's name, merges them, and prints the result:</p>
<pre><code class="language-python">import sys, yaml
from pathlib import Path

def resolve(skill_name, skill_dir, project_root):
    defaults = yaml.safe_load((Path(skill_dir) / "config.default.yaml").read_text()) or {}

    user_path = find_project_config(Path(project_root))
    user_all = yaml.safe_load(user_path.read_text()) if user_path else {}
    user_cfg = (user_all or {}).get(skill_name, {}) or {}

    return deep_merge(defaults, user_cfg)
</code></pre>
<p>That completes the whole idea. The full version in the sample repo adds a command-line interface, JSON output, and clear error messages, but the logic above is all you really need.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5f92a5e56aa1ed54804bb866/ca8d7095-21f6-4433-8c82-b6b0ca34b9ef.png" alt="Terminal output showing the resolved configuration for the git-commit-formatter skill." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-how-to-make-a-skill-configurable">How to Make a Skill Configurable</h2>
<p>Now you'll convert the static commit skill into a configurable one. This takes two files.</p>
<p>First, create <code>config.default.yaml</code> next to the skill. It lists every setting and a safe default, so the skill works even when the user has no config at all:</p>
<pre><code class="language-yaml"># Default configuration for the git-commit-formatter skill.
style: conventional          # conventional | gitmoji
types:                       # base set of allowed commit types
  - feat
  - fix
  - docs
  - style
  - refactor
  - perf
  - test
  - chore
extra_types: []              # additional types, merged on top of `types`
scope_required: false        # if true, require a scope: type(scope): ...
max_subject_length: 72       # hard cap on the subject line
</code></pre>
<p>Second, update <code>SKILL.md</code> so that its very first instruction is to resolve the config and apply it. This is the key move: you're telling the agent to read the settings before it does anything else:</p>
<pre><code class="language-markdown">---
name: git-commit-formatter
description: Formats git commit messages to a team's chosen convention (Conventional Commits or gitmoji). Use this when the user asks to commit changes or write a commit message. Reads per-project settings so teams customize commit style without editing this skill.
---

# Git Commit Formatter (Configurable)

## Step 1 - Resolve configuration (always do this first)

Run the loader and read its output:

`python scripts/resolve_config.py git-commit-formatter --project-root .`

Apply exactly those settings:

- `style`: `conventional` or `gitmoji`.
- `types` + `extra_types`: the full set of allowed commit types.
- `scope_required`: if true, a scope is mandatory.
- `max_subject_length`: hard cap on the subject line.

## Step 2 - Compose the message

Pick the primary type from `types` + `extra_types`, build the subject in the
chosen `style`, and enforce `scope_required` and `max_subject_length`.
</code></pre>
<p>This pattern ("make the agent run a script and obey its output") is the same one Antigravity's own validation skills use. It keeps the behavior deterministic instead of leaving it to the model's memory.</p>
<p>Notice how <code>extra_types</code> solves the additive-list question. The default list stays put, and the user's extras are simply added on top by the skill. No fork is required to add a <code>ci</code> type.</p>
<h2 id="heading-how-to-add-project-overrides">How to Add Project Overrides</h2>
<p>Let's say you want gitmoji commits with two extra types. Create a single file in your project:</p>
<pre><code class="language-yaml"># .agent/skills.config.yaml
git-commit-formatter:
  style: gitmoji
  extra_types: [ci, build]
  scope_required: true
</code></pre>
<p>You just changed three lines of config and didn't open the skill or fork any code. The next time the agent commits, it will use this project settings.</p>
<p>And a different project, with no config file at all, keeps getting the sensible Conventional Commits defaults. You have one skill with many behaviors.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5f92a5e56aa1ed54804bb866/c9cb7c61-4a6f-4963-94ed-321bb20bde30.png" alt="The agent proposing a commit message that starts with an emoji, driven by the project config.&quot;" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-how-to-test-your-configurable-skill">How to Test Your Configurable Skill</h2>
<p>You don't need the agent to check that the merge works. Run the loader directly and read the output.</p>
<p>With no overrides, you get the defaults:</p>
<pre><code class="language-bash">$ python scripts/resolve_config.py git-commit-formatter --project-root .
style: conventional
scope_required: false
...
</code></pre>
<p>Now add the <code>.agent/skills.config.yaml</code> override from the last section and run it again:</p>
<pre><code class="language-bash">$ python scripts/resolve_config.py git-commit-formatter --project-root . --print-sources
style: gitmoji
scope_required: true
extra_types:
- ci
- build
types:
- feat
- fix
- docs
...
</code></pre>
<p>The <code>style</code> flipped to <code>gitmoji</code>, <code>scope_required</code> became <code>true</code>, and your extra types appeared (while the base <code>types</code> list stayed intact). That confirms the merge does exactly what you want.</p>
<p>It's worth writing a small automated test too, so a future change to the loader can't silently break the merge. A test can create a fake skill and a fake project config in a temp folder, run the loader, and assert that user values override defaults while untouched defaults survive.</p>
<h2 id="heading-two-more-example-skills">Two More Example Skills</h2>
<p>The same pattern works for any skill. Here are two more to show the range.</p>
<h3 id="heading-a-changelog-generator">A Changelog Generator</h3>
<p>Its <code>config.default.yaml</code> exposes the output <code>format</code> (like Keep a Changelog), which commit <code>types</code> to include, and whether to link commit hashes to a repo URL. One project can generate a formal changelog grouped by type, while another can generate a simple bulleted list. It's the same skill with a different config.</p>
<pre><code class="language-yaml"># changelog-generator config.default.yaml (excerpt)
format: keepachangelog       # keepachangelog | conventional | simple
include_types: [feat, fix, perf]
include_authors: false
repo_url: ""                 # if set, hashes link to commits
</code></pre>
<h3 id="heading-a-license-header-adder">A License-Header Adder</h3>
<p>Its config exposes the <code>license</code> (Apache-2.0, MIT, or custom), the <code>holder</code>, and a map of file extensions to comment styles. A company sets the holder once in their project config, and every new file gets the right header in the right comment style, without editing the skill.</p>
<pre><code class="language-yaml"># license-header-adder config.default.yaml (excerpt)
license: apache-2.0          # apache-2.0 | mit | custom
holder: "Your Name or Org"
year: auto                   # auto = current year
</code></pre>
<p>The lesson is that almost any skill has a few decisions baked into it. When you pull those decisions into a <code>config.default.yaml</code>, you convert a one-off skill into a tool that anyone can reuse and tune.</p>
<h2 id="heading-how-to-share-your-agent-skills-with-others">How to Share Your Agent Skills With Others</h2>
<p>Once your agent skills follow the convention, they compose into something bigger. To make your agent skills easy for others to adopt, you have to:</p>
<ul>
<li><p><strong>Keep each skill self-contained:</strong> Vendor a copy of <code>resolve_config.py</code> inside each skill's <code>scripts/</code> folder, so someone can copy a single skill folder anywhere and it just works.</p>
</li>
<li><p><strong>Document every config key</strong> in the <code>SKILL.md</code>, so users know exactly what they can tune.</p>
</li>
<li><p><strong>Publish a small index:</strong> A simple <code>index.json</code> that lists each skill's name, path, and config keys makes it easy for others to discover what you've built and contribute their own.</p>
</li>
</ul>
<p>Because the convention is just "read a config file first," anyone can publish a compatible skill. Each new configurable skill makes the whole ecosystem more useful. In addition to shipping a skill, you're shipping a small standard that other people can build on.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You started with a static skill whose behavior was frozen in Markdown, and you turned it into a configurable one that anyone can tune from a single project file.</p>
<p>The entire setup is relatively small. It has the merge function, one convention, and a <code>config.default.yaml</code> per skill.</p>
<p>It also changes how skills are shared. Instead of forking a skill to change one setting, you can keep the shared logic and adjust your own config. Improvements to the skill flow to everyone, and everyone still gets the behavior they want.</p>
<p>If you want to try it, build the <code>git-commit-formatter</code> skill from this tutorial, drop it into your Antigravity skills folder, and add an <code>.agent/skills.config.yaml</code> to a project. Then flip <code>style</code> from <code>conventional</code> to <code>gitmoji</code> and watch the same skill behave differently.</p>
<p>From there, make one of your own skills configurable. Find the settings you baked into the instructions, move them into a <code>config.default.yaml</code>, and let your users take it from there.</p>
<p>The full sample code (the loader, its tests, and all three example skills) is on GitHub at <a href="https://github.com/keepdeploying/configurable-agent-skills">github.com/keepdeploying/configurable-agent-skills</a>.</p>
<p>Thanks for reading. If you build a configurable skill of your own, share it. Let's keep the ecosystem growing.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ From RPC to gRPC: Understanding Remote Procedure Calls, Protocol Buffers, and Modern Distributed Systems Communication  ]]>
                </title>
                <description>
                    <![CDATA[ Every application, at some point, needs to talk to another system. A mobile app talks to a backend. A backend service talks to a payment gateway. An authentication service talks to a user service. A d ]]>
                </description>
                <link>https://www.freecodecamp.org/news/remote-procedure-calls-protocol-buffers-and-modern-distributed-systems-communication/</link>
                <guid isPermaLink="false">6a6145d945466c5d8ca2a549</guid>
                
                    <category>
                        <![CDATA[ gRPC ]]>
                    </category>
                
                    <category>
                        <![CDATA[ RPC ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dart ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwaseyi Fatunmole ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jul 2026 22:36:09 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/1205581e-5729-44fa-837e-0f30981ea059.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every application, at some point, needs to talk to another system. A mobile app talks to a backend. A backend service talks to a payment gateway. An authentication service talks to a user service. A data pipeline talks to a storage layer.</p>
<p>The question is never whether systems need to communicate. The question is always how.</p>
<p>For years, REST over HTTP with JSON was the default answer. It works, it's simple, and the tooling is everywhere. But as systems grow in scale (in the number of services talking to each other, the volume of data being exchanged, and the need for real-time communication), REST starts to show its limits.</p>
<p>This is where Remote Procedure Calls, Protocol Buffers, and gRPC enter the picture.</p>
<p>In this handbook, you'll learn what RPC is and the problem it was designed to solve. You'll also understand Protocol Buffers: what they are, why they exist, and how they work.</p>
<p>You'll then see how Google combined these ideas into gRPC, one of the most powerful communication frameworks in modern distributed systems. You'll learn all four gRPC communication patterns, see code generated across multiple languages from a single contract file, and walk through a complete end-to-end Flutter implementation with production-grade concerns including authentication, error handling, and timeouts.</p>
<p>By the end, you won't just know what gRPC is. You'll understand when to use it, when not to, and how to think about service communication as a systems engineer.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-a-remote-procedure-call">What is a Remote Procedure Call</a>?</p>
</li>
<li><p><a href="#heading-the-problem-rpc-solves">The Problem RPC Solves</a></p>
</li>
<li><p><a href="#heading-why-grpc-over-rest-the-real-case">Why gRPC Over REST: The Real Case</a></p>
</li>
<li><p><a href="#heading-protocol-buffers-a-new-language-for-data">Protocol Buffers: A New Language for Data</a></p>
</li>
<li><p><a href="#heading-the-proto-file">The Proto File</a></p>
</li>
<li><p><a href="#heading-json-vs-protocol-buffers">JSON vs Protocol Buffers</a></p>
</li>
<li><p><a href="#heading-the-protoc-compiler-and-code-generation">The Protoc Compiler and Code Generation</a></p>
</li>
<li><p><a href="#heading-what-is-grpc">What is gRPC</a>?</p>
</li>
<li><p><a href="#heading-why-http2-matters-for-grpc">Why HTTP/2 Matters for gRPC</a></p>
</li>
<li><p><a href="#heading-the-four-grpc-communication-patterns">The Four gRPC Communication Patterns</a></p>
</li>
<li><p><a href="#heading-the-protobuf-repository-organizational-best-practice">The Protobuf Repository: Organizational Best Practice</a></p>
</li>
<li><p><a href="#heading-building-a-complete-grpc-system-with-dart-and-flutter">Building a Complete gRPC System with Dart and Flutter</a></p>
</li>
<li><p><a href="#heading-production-concerns">Production Concerns</a></p>
</li>
<li><p><a href="#heading-grpc-vs-rest-vs-websockets-when-to-use-what">gRPC vs REST vs WebSockets: When to Use What</a></p>
</li>
<li><p><a href="#heading-the-hybrid-architecture">The Hybrid Architecture</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-remote-procedure-call">What is a Remote Procedure Call?</h2>
<p>To understand RPCs, you first need to understand what a procedure call is.</p>
<p>A procedure call means invoking a procedure or function so that its code executes. For example, in Dart:</p>
<pre><code class="language-dart">double calculateTax(double amount) {
  return amount * 0.075;
}

final tax = calculateTax(50000); // local procedure call
</code></pre>
<p>You call <code>calculateTax</code>, pass an argument, and get a result back. The function lives on the same machine, in the same process, in the same memory space. This is a local procedure call.</p>
<p>A Remote Procedure Call takes this same idea and stretches it across a network. The function you're calling lives on a different machine, in a different process, and potentially in a different country. But from the caller's perspective, it feels exactly like calling a local function.</p>
<pre><code class="language-dart">// This looks like a local function call
final tax = await taxService.calculateTax(amount: 50000);

// But under the hood, this:
// 1. Serializes the argument into a binary format
// 2. Sends it over a network connection to a remote server
// 3. The server executes calculateTax with your argument
// 4. Serializes the result
// 5. Sends it back over the network
// 6. Deserializes it into a Dart object
// 7. Returns it to you as if it were local
</code></pre>
<p>The network complexity is completely hidden. You call a function. You get a result. Everything in between is handled by the RPC framework.</p>
<p>This is the fundamental idea behind RPC: make calling a remote function feel as natural as calling a local one.</p>
<h2 id="heading-the-problem-rpc-solves">The Problem RPC Solves</h2>
<p>To appreciate why RPC matters, you need to understand what the alternative looks like.</p>
<p>Without RPC, calling a remote service looks like this:</p>
<pre><code class="language-dart">Future&lt;double&gt; calculateTax(double amount) async {
  final response = await http.post(
    Uri.parse('https://tax-service.internal/api/v1/calculate'),
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token',
    },
    body: jsonEncode({'amount': amount}),
  );

  if (response.statusCode != 200) {
    throw Exception('Tax calculation failed: ${response.statusCode}');
  }

  final data = jsonDecode(response.body);
  return (data['tax'] as num).toDouble();
}
</code></pre>
<p>Every service call requires you to:</p>
<ul>
<li><p>Know and hardcode the endpoint URL</p>
</li>
<li><p>Know the correct HTTP method</p>
</li>
<li><p>Manually serialize your request to JSON</p>
</li>
<li><p>Handle HTTP status codes yourself</p>
</li>
<li><p>Manually deserialize the response from JSON</p>
</li>
<li><p>Cast dynamic types to the types you actually expect</p>
</li>
<li><p>Hope the field names in the response match what you think they are</p>
</li>
</ul>
<p>Now multiply this by every single service call in your application. An authentication service, a user service, a payment service, a notification service, a transaction service. Every one of them requires the same manual boilerplate. Every one of them introduces the possibility of a typo in a field name, a wrong status code assumption, or a JSON deserialization failure that only surfaces at runtime.</p>
<p>With RPC:</p>
<pre><code class="language-dart">// Feels like a local function call
final tax = await taxService.calculateTax(
  TaxRequest(amount: 50000),
);
// tax is already a strongly typed TaxResponse object
// No URLs. No HTTP methods. No JSON parsing. No casting.
</code></pre>
<p>The framework handles everything. The function signature is defined in a contract file that both the client and server use. The types are enforced at compile time. If the server changes the response shape, the client fails to compile before anything reaches production.</p>
<p>This is what RPC solves: it removes the accidental complexity of network communication and lets you focus on what you're actually trying to do.</p>
<h2 id="heading-why-grpc-over-rest-the-real-case">Why gRPC Over REST: The Real Case</h2>
<p>Before going into the technical details of Protocol Buffers and gRPC, it's important to make a solid case for why you'd choose gRPC over REST in specific scenarios. This isn't a claim that gRPC is always better. It's a clear look at where it genuinely wins.</p>
<h3 id="heading-large-payloads-called-by-many-internal-systems">Large Payloads Called by Many Internal Systems</h3>
<p>Consider an internal enterprise API in a large telecommunications company. A single request and response payload for a plan registration or activation flow can contain over a thousand fields. This endpoint is called by dozens of internal applications: billing systems, CRM platforms, customer-facing mobile apps, internal dashboards, and partner portals.</p>
<p>With REST and JSON, every one of those applications sends and receives that thousand-field payload as text. Field names like <code>subscription_activation_status</code>, <code>rate_plan_identifier</code>, and <code>network_provisioning_reference</code> travel over the wire as strings on every single request. A significant portion of every payload isn't data. It's labels for data.</p>
<p>With Protocol Buffers, field names never appear in the payload at all. Only field numbers and values travel over the wire. That thousand-field payload shrinks dramatically. For an endpoint called millions of times per day by dozens of systems, the bandwidth saving is enormous and translates directly to infrastructure cost reduction.</p>
<p>Beyond size, the generated client guarantee is equally important. With REST, each of those dozens of applications reads the API documentation and builds its own understanding of the contract. When the backend changes a field name or type, not every application finds out immediately. Some find out in production when they break.</p>
<p>With a shared <code>.proto</code> file, every application generates its own strongly typed client from the same source. A contract change means every application regenerates. The compiler immediately reports where the breaking change affects each codebase. Nothing reaches production in a broken state.</p>
<h3 id="heading-low-bandwidth-and-remote-network-conditions">Low Bandwidth and Remote Network Conditions</h3>
<p>This is one of the most under-appreciated advantages of gRPC in markets where network quality varies significantly.</p>
<p>In many regions, a substantial portion of mobile users are on 2G or 3G connections. On a 2G connection, bandwidth can be as low as 50 to 100 kilobits per second. A REST JSON response that is 80 kilobytes takes over 6 seconds to download on a 2G connection. The equivalent protobuf binary, which can be 3 to 10 times smaller, takes under 2 seconds.</p>
<p>That difference isn't a technical footnote. It's the line between an application that feels usable and one that feels broken to a significant portion of your users. For any product that operates in markets with variable network conditions, protobuf's binary efficiency is a direct competitive advantage.</p>
<p>Beyond size, gRPC runs over HTTP/2 which maintains a single persistent connection rather than opening a new connection for every request. On slow networks where connection establishment (the TCP handshake and TLS negotiation) can itself take hundreds of milliseconds, reusing a single connection across many calls saves significant time over a session.</p>
<h3 id="heading-microservice-to-microservice-communication">Microservice to Microservice Communication</h3>
<p>When two internal services need to communicate, you have options. A message bus like Kafka or RabbitMQ is excellent when you don't need an immediate response, when the operation can happen asynchronously, and when you're broadcasting something that happened to multiple consumers.</p>
<p>But many service-to-service calls are synchronous by nature. An authentication service needs to validate a token right now before the request proceeds. A fraud detection service needs to assess a transaction right now before the payment is authorized. A pricing service needs to calculate a rate right now before the quote is generated. These operations can't publish an event and wait.</p>
<p>For synchronous service-to-service calls at high frequency, gRPC over HTTP/2 with protobuf encoding is significantly more efficient than REST. The persistent multiplexed connection means no connection setup overhead per call. The binary encoding means no JSON serialization and deserialization overhead on every hop. The generated clients mean both services compile against the same contract.</p>
<p>At scale, when two services are calling each other thousands of times per second, these efficiency differences compound into real performance and cost differences.</p>
<h3 id="heading-managing-api-contracts-across-multiple-teams">Managing API Contracts Across Multiple Teams</h3>
<p>In a large engineering organization, multiple teams build services that others depend on. REST API contracts live in documentation. Documentation goes stale. The backend team changes a field name. The mobile team finds out when users report crashes. The data team finds out when their pipeline throws an error at 2am.</p>
<p>gRPC's protobuf repository approach transforms contract management from a documentation problem into a code problem. Contract changes go through pull requests. Every dependent team reviews the change. Breaking changes are caught at compile time. Nobody is surprised in production.</p>
<p>This governance benefit scales with team size. The larger the organization, the more valuable it becomes.</p>
<h3 id="heading-real-time-communication">Real-Time Communication</h3>
<p>REST is request-response. The client asks and the server answers. The conversation ends. For real-time features, you either poll (wasteful) or bolt on a separate WebSocket server alongside your REST API (two different systems to maintain).</p>
<p>gRPC's streaming patterns handle real-time communication natively within the same framework you use for regular calls. A live balance update, a real-time transaction notification, or a bidirectional chat session all use the same generated client, the same connection, and the same protobuf encoding as your regular unary calls.</p>
<p>One framework with all communication patterns. No separate infrastructure.</p>
<h2 id="heading-protocol-buffers-a-new-language-for-data">Protocol Buffers: A New Language for Data</h2>
<p>RPC is a concept. To implement it, you need two things: a way to define the contract between client and server, and a way to serialize data efficiently for transmission over the network.</p>
<p>This is where Protocol Buffers comes in.</p>
<p>Protocol Buffers, commonly called protobuf, is a language-neutral, platform-neutral, extensible mechanism for serializing structured data. It was developed at Google in 2001, used internally for years, and open-sourced in 2008.</p>
<h3 id="heading-the-json-problem-at-scale">The JSON Problem at Scale</h3>
<p>JSON is the dominant data format for web APIs. It's human-readable, flexible, and universally supported. For many use cases, it's the right choice.</p>
<p>But JSON has structural inefficiencies that become painful at scale.</p>
<p>Consider a user profile response:</p>
<pre><code class="language-json">{
  "id": "usr_001",
  "first_name": "John",
  "last_name": "Smith",
  "email": "john@example.com",
  "phone_number": "+2348012345678",
  "account_type": "savings",
  "balance": 500000.00,
  "currency": "NGN",
  "is_verified": true,
  "is_active": true,
  "kyc_level": 3,
  "created_at": "2024-01-15T10:30:00Z",
  "last_login": "2026-07-20T09:15:00Z"
}
</code></pre>
<p>Every field name travels over the network as a string on every single response. <code>"first_name"</code>, <code>"account_type"</code>, <code>"phone_number"</code> aren't data. They're labels for data. But they consume bytes on every request.</p>
<p>Now consider an internal enterprise API with over a thousand fields in its request and response payload, being called by dozens of internal applications thousands of times per day. A significant portion of every payload is field name strings, not actual data. The overhead accumulates into real bandwidth and processing costs.</p>
<p>Beyond size, JSON has another problem: it has no schema at the network level. Nothing prevents a backend engineer from renaming <code>"first_name"</code> to <code>"firstName"</code> in a new deployment. The client breaks at runtime in production with real users.</p>
<h3 id="heading-what-protocol-buffers-do-differently">What Protocol Buffers Do Differently</h3>
<p>Protocol Buffers solve both problems with a fundamentally different approach to data encoding.</p>
<p>Instead of encoding data as human-readable text with field names, protobuf encodes data as compact binary using only field numbers and values. Field names never travel over the network.</p>
<p>Here's the same user profile defined in protobuf:</p>
<pre><code class="language-protobuf">message UserProfile {
  string id = 1;
  string first_name = 2;
  string last_name = 3;
  string email = 4;
  string phone_number = 5;
  string account_type = 6;
  double balance = 7;
  string currency = 8;
  bool is_verified = 9;
  bool is_active = 10;
  int32 kyc_level = 11;
  string created_at = 12;
  string last_login = 13;
}
</code></pre>
<p>When protobuf encodes this data, the output is binary that no human can read. But to a machine, it's extremely compact and fast to parse. The field numbers (1, 2, 3...) identify each field. The names never appear in the encoded output at all.</p>
<p>The result: the same user profile that's approximately 280 bytes in JSON is approximately 95 bytes in protobuf. That's three times smaller. For a thousand-field enterprise payload, this difference is enormous.</p>
<p>And because the schema is defined in a <code>.proto</code> file that both client and server compile against, field name changes are caught at compile time, not at runtime.</p>
<h2 id="heading-the-proto-file">The Proto File</h2>
<p>The <code>.proto</code> file is the heart of everything in the protobuf and gRPC ecosystem. It's where you define your data models and your service contracts.</p>
<p>It's written in Protocol Buffer Language (proto3) – not Go, not Dart, not Python, not Java. You write it in any text editor. VS Code with the <code>vscode-proto3</code> extension gives you syntax highlighting, autocomplete, and inline validation.</p>
<p>Here's a complete <code>.proto</code> file for a fintech platform:</p>
<pre><code class="language-csharp">syntax = "proto3";

package banking;

option go_package = "./banking";
option java_package = "com.fintech.banking";



service BankingService {
  // Unary: one request, one response
  rpc Login (LoginRequest) returns (LoginResponse);

  // Unary: fetch user profile
  rpc GetProfile (ProfileRequest) returns (UserProfile);

  // Server streaming: real-time balance updates
  rpc WatchBalance (BalanceRequest) returns (stream BalanceResponse);

  // Server streaming: live transaction feed
  rpc StreamTransactions (TransactionRequest) returns (stream Transaction);

  // Client streaming: upload KYC documents in chunks
  rpc UploadDocument (stream DocumentChunk) returns (UploadResponse);

  // Bidirectional streaming: live chat support
  rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}



message LoginRequest {
  string email = 1;
  string password = 2;
}

message LoginResponse {
  string token = 1;
  string user_id = 2;
  int64 expires_at = 3;
}

message ProfileRequest {
  string user_id = 1;
}

message UserProfile {
  string id = 1;
  string first_name = 2;
  string last_name = 3;
  string email = 4;
  string phone_number = 5;
  string account_type = 6;
  double balance = 7;
  string currency = 8;
  bool is_verified = 9;
  int32 kyc_level = 10;
}

message BalanceRequest {
  string user_id = 1;
}

message BalanceResponse {
  double balance = 1;
  string currency = 2;
  int64 timestamp = 3;
}

message TransactionRequest {
  string user_id = 1;
  int32 limit = 2;
}

message Transaction {
  string id = 1;
  double amount = 2;
  string description = 3;
  string type = 4;
  int64 timestamp = 5;
}

message DocumentChunk {
  bytes data = 1;
  string document_type = 2;
  int32 chunk_index = 3;
  bool is_last = 4;
}

message UploadResponse {
  bool success = 1;
  string document_id = 2;
  string message = 3;
}

message ChatMessage {
  string sender_id = 1;
  string content = 2;
  int64 timestamp = 3;
}
</code></pre>
<p>Let's walk through every part of this file carefully.</p>
<h3 id="heading-the-syntax-declaration">The Syntax Declaration</h3>
<pre><code class="language-csharp">syntax = "proto3";
</code></pre>
<p>This tells the protobuf compiler which version of the Protocol Buffer language you're using. proto3 is the current standard. It must be the first non-comment line in every <code>.proto</code> file.</p>
<h3 id="heading-the-package-declaration">The Package Declaration</h3>
<pre><code class="language-csharp">package banking;
</code></pre>
<p>The package name prevents naming conflicts when you have multiple <code>.proto</code> files across different services. It functions like a namespace. If two services both define a <code>UserProfile</code> message, the package name distinguishes them: <code>banking.UserProfile</code> versus <code>auth.UserProfile</code>.</p>
<h3 id="heading-language-specific-options">Language-Specific Options</h3>
<pre><code class="language-protobuf">option go_package = "./banking";
option java_package = "com.fintech.banking";
</code></pre>
<p>These options tell the compiler how to organize the generated code for specific languages. They don't affect the proto file itself, only the generated output.</p>
<h3 id="heading-the-service-definition">The Service Definition</h3>
<pre><code class="language-csharp">service BankingService {
  rpc Login (LoginRequest) returns (LoginResponse);
  rpc WatchBalance (BalanceRequest) returns (stream BalanceResponse);
}
</code></pre>
<p>The <code>service</code> block defines the RPC contract. Think of it exactly like an abstract class in any object-oriented language. It declares what functions exist, what they accept, and what they return.</p>
<p>Each <code>rpc</code> line defines one remote procedure. The <code>stream</code> keyword before a type indicates that multiple messages will flow rather than just one.</p>
<h3 id="heading-message-definitions">Message Definitions</h3>
<pre><code class="language-csharp">message LoginRequest {
  string email = 1;
  string password = 2;
}
</code></pre>
<p>A <code>message</code> is a data structure. Think of it as a class with only fields: no methods, no logic. Each field has three parts.</p>
<p>The <strong>type</strong> can be <code>string</code>, <code>int32</code>, <code>int64</code>, <code>double</code>, <code>bool</code>, <code>bytes</code>, or another message type.</p>
<p>The <strong>name</strong> is the field name as it appears in generated code. This is for human readability only. It never appears in the binary encoding.</p>
<p>The <strong>field number</strong> (= 1, = 2, = 3) is the unique identifier that protobuf uses in the binary output instead of the field name. This is critical: once you assign a field number, you must never change it or reuse it. The binary encoding uses these numbers, not names. If you change a field number, old encoded data becomes unreadable.</p>
<p>You can safely add new fields with new numbers, remove fields (the number stays reserved, never reuse it), and rename fields (names don't appear in binary). You must never change a field number, reuse a removed field's number, or change a field's type.</p>
<h2 id="heading-json-vs-protocol-buffers">JSON vs Protocol Buffers</h2>
<p>Now that you understand both formats, let's make a direct comparison.</p>
<h3 id="heading-size-comparison">Size Comparison</h3>
<p>Let's look at the same login request in both formats:</p>
<p><strong>JSON (text):</strong></p>
<pre><code class="language-csharp">{
  "email": "john@example.com",
  "password": "securepassword123"
}
</code></pre>
<p>Approximately 55 bytes.</p>
<p><strong>Protobuf binary:</strong></p>
<p>Field 1 (email): tag + length + value bytes. Field 2 (password): tag + length + value bytes.</p>
<p>Approximately 38 bytes.</p>
<p>For a simple two-field message, the difference is modest. Now consider a thousand-field enterprise payload. Field names alone in JSON can account for 40-60% of the total payload size. In protobuf, field names contribute zero bytes to the payload.</p>
<p>On a 2G connection where bandwidth can be as low as 50 kilobits per second, the difference between an 80 kilobyte JSON response and a 15 kilobyte protobuf response is the difference between a 13-second load and a 2-second load. For users in areas with limited network infrastructure, this isn't a performance metric. It's a usability threshold.</p>
<h3 id="heading-speed-comparison">Speed Comparison</h3>
<p>Protobuf serialization and deserialization is significantly faster than JSON parsing because binary parsing requires no string tokenizing, quote handling, whitespace skipping, or type inference. The parser reads a field number, reads the value type, reads the value, and moves to the next field. It's a direct binary read.</p>
<p>JSON parsing must tokenize a string character by character, identify keys and values by their surrounding quotes and delimiters, infer types from the value format, and construct objects from dynamic maps.</p>
<p>On a mobile device handling hundreds of responses per session, this parsing difference translates to measurable CPU and battery savings.</p>
<h3 id="heading-schema-and-type-safety">Schema and Type Safety</h3>
<p>JSON has no schema enforcement at the network level. A backend can change <code>"balance"</code> to <code>"current_balance"</code> and the client only discovers this when the app crashes in production.</p>
<p>Protobuf schemas are enforced at compile time. If the <code>.proto</code> file changes in a way that breaks the client, the client fails to compile. The problem is caught before it reaches any user.</p>
<h3 id="heading-the-honest-comparison">The Honest Comparison</h3>
<table>
<thead>
<tr>
<th></th>
<th>JSON</th>
<th>Protocol Buffers</th>
</tr>
</thead>
<tbody><tr>
<td>Encoding</td>
<td>Text (UTF-8)</td>
<td>Binary</td>
</tr>
<tr>
<td>Human readable</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Payload size</td>
<td>Larger (field names included)</td>
<td>3 to 10 times smaller</td>
</tr>
<tr>
<td>Parse speed</td>
<td>Slower (text tokenizing)</td>
<td>Faster (direct binary read)</td>
</tr>
<tr>
<td>Schema enforcement</td>
<td>None at network level</td>
<td>Compile-time enforcement</td>
</tr>
<tr>
<td>Code generation</td>
<td>Optional</td>
<td>Required and automatic</td>
</tr>
<tr>
<td>Best for</td>
<td>Public APIs, human inspection</td>
<td>Internal services, high performance</td>
</tr>
</tbody></table>
<h2 id="heading-the-protoc-compiler-and-code-generation">The Protoc Compiler and Code Generation</h2>
<p>The <code>protoc</code> compiler reads your <code>.proto</code> file and generates code in any language you specify. This is where the universal contract becomes reality.</p>
<p><strong>Generating Go code (for the backend server):</strong></p>
<pre><code class="language-csharp">protoc \
  --go_out=. \
  --go-grpc_out=. \
  proto/banking.proto
</code></pre>
<p>Generates:</p>
<pre><code class="language-plaintext">banking.pb.go        &lt;- the message structs
banking_grpc.pb.go   &lt;- the server interface
</code></pre>
<p><strong>Generating Dart code (for the Flutter client):</strong></p>
<pre><code class="language-csharp">protoc \
  --dart_out=grpc:lib/generated \
  proto/banking.proto
</code></pre>
<p>Generates:</p>
<pre><code class="language-plaintext">lib/generated/
  banking.pb.dart        &lt;- the message classes
  banking.pbgrpc.dart    &lt;- the client stub
</code></pre>
<p><strong>Generating Python code (for a data service):</strong></p>
<pre><code class="language-csharp">protoc \
  --python_out=. \
  --grpc_python_out=. \
  proto/banking.proto
</code></pre>
<p>Generates:</p>
<pre><code class="language-plaintext">banking_pb2.py         &lt;- the message classes
banking_pb2_grpc.py    &lt;- the client and server classes
</code></pre>
<p><strong>Generating TypeScript code (for a web frontend):</strong></p>
<pre><code class="language-csharp">protoc \
  --ts_out=. \
  proto/banking.proto
</code></pre>
<p>Generates:</p>
<pre><code class="language-plaintext">banking.ts             &lt;- typed message classes and client
</code></pre>
<p>All of this from the same single <code>banking.proto</code> file.</p>
<p>The Go backend engineer never writes serialization code. The Flutter engineer never writes deserialization code. The Python data engineer never parses binary manually. The TypeScript web engineer never constructs HTTP requests. All of that is generated automatically from the contract that every team agreed on.</p>
<p>Here's what the generated code looks like in each language to make this concrete:</p>
<p><strong>Generated Go server interface (the backend implements this):</strong></p>
<pre><code class="language-go">// Generated — do not edit
type BankingServiceServer interface {
    Login(context.Context, *LoginRequest) (*LoginResponse, error)
    WatchBalance(*BalanceRequest, BankingService_WatchBalanceServer) error
    mustEmbedUnimplementedBankingServiceServer()
}

// The Go backend engineer writes this implementation
type bankingServer struct {
    pb.UnimplementedBankingServiceServer
}

func (s *bankingServer) Login(
    ctx context.Context,
    req *pb.LoginRequest,
) (*pb.LoginResponse, error) {
    token, err := authService.Login(req.Email, req.Password)
    if err != nil {
        return nil, status.Errorf(codes.Unauthenticated, "invalid credentials")
    }
    return &amp;pb.LoginResponse{
        Token:  token,
        UserId: user.Id,
    }, nil
}
</code></pre>
<p><strong>Generated Python client (the data team uses this):</strong></p>
<pre><code class="language-python">import grpc
import banking_pb2
import banking_pb2_grpc

channel = grpc.secure_channel(
    'api.fintech-platform.com:50051',
    grpc.ssl_channel_credentials()
)
stub = banking_pb2_grpc.BankingServiceStub(channel)

response = stub.Login(banking_pb2.LoginRequest(
    email='john@example.com',
    password='password123'
))

print(f"Token: {response.token}")
print(f"User ID: {response.user_id}")
</code></pre>
<p><strong>Generated Dart client (you use this in Flutter):</strong></p>
<pre><code class="language-dart">import 'package:grpc/grpc.dart';
import 'generated/banking.pbgrpc.dart';
import 'generated/banking.pb.dart';

final channel = ClientChannel('api.fintech-platform.com', port: 50051);
final client = BankingServiceClient(channel);

final response = await client.login(
  LoginRequest(email: 'john@example.com', password: 'password123'),
);

print('Token: ${response.token}');
print('User ID: ${response.userId}');
</code></pre>
<p>Three different languages. Three different teams. One <code>.proto</code> file. All of them are generated, strongly typed, and guaranteed to be in sync with the server.</p>
<h2 id="heading-what-is-grpc">What is gRPC?</h2>
<p>gRPC is Google's open-source Remote Procedure Call framework. It was open-sourced in 2016 and is now a Cloud Native Computing Foundation (CNCF) graduated project. This means it's been production-proven at the highest level of the cloud-native ecosystem.</p>
<p>gRPC combines three things:</p>
<ol>
<li><p><strong>Remote Procedure Calls</strong> as the programming model: calling remote functions like local ones.</p>
</li>
<li><p><strong>Protocol Buffers</strong> as the interface definition language and data serialization format: strongly typed contracts and compact binary encoding.</p>
</li>
<li><p><strong>HTTP/2</strong> as the transport protocol: multiplexed, persistent connections with binary framing.</p>
</li>
</ol>
<p>The combination of these three produces a framework that's faster than REST, more structured than WebSockets, and more powerful than any of its predecessors.</p>
<p>gRPC is used internally at Google for virtually all service-to-service communication. Netflix, Uber, Square, Dropbox, Lyft, and hundreds of other organizations use it for their internal microservice communication. Official support exists for Go, Java, Python, C++, C#, Ruby, Node.js, PHP, Dart, Kotlin, and more.</p>
<h2 id="heading-why-http2-matters-for-grpc">Why HTTP/2 Matters for gRPC</h2>
<p>gRPC is built exclusively on HTTP/2. Understanding what HTTP/2 provides is essential to understanding why gRPC performs the way it does.</p>
<p>HTTP/1.1, which powers most REST APIs, has fundamental performance constraints. Each request must complete before the next one begins on the same connection. Headers are sent as verbose text on every request. The server can't send data unless the client asks first.</p>
<p>HTTP/2 was designed to fix these constraints at the protocol level.</p>
<h3 id="heading-multiplexing">Multiplexing</h3>
<p>HTTP/2 introduces streams within a single connection. Multiple independent requests can travel over the same TCP connection simultaneously.</p>
<pre><code class="language-csharp">Single TCP connection to api.fintech-platform.com

Stream 1: Login request ---------&gt; Login response
Stream 2: Profile request -------&gt; Profile response
Stream 3: Balance request -------&gt; Balance stream (ongoing)
Stream 4: Transactions request --&gt; Transaction stream (ongoing)

All four streams active simultaneously over ONE connection
</code></pre>
<p>In HTTP/1.1, you would need four separate connections or wait for each to complete before starting the next. HTTP/2 handles all four over a single persistent connection with no waiting.</p>
<p>This is the foundation of gRPC's streaming capabilities. A persistent multiplexed connection is what allows the server to keep pushing balance updates and transaction notifications while the client continues making other calls.</p>
<h3 id="heading-binary-framing">Binary Framing</h3>
<p>HTTP/1.1 sends everything as text. HTTP/2 sends everything as binary frames. Binary is more compact and significantly faster for machines to parse.</p>
<p>Every gRPC message is broken into binary frames and sent over the HTTP/2 connection. Combined with protobuf's binary encoding, gRPC data travels in the most compact form possible at every layer.</p>
<h3 id="heading-header-compression-hpack">Header Compression (HPACK)</h3>
<p>HTTP/1.1 sends full headers on every request. An Authorization header carrying a JWT token can be 500 bytes or more, repeated on every request.</p>
<p>HTTP/2 uses HPACK compression. Headers sent on previous requests are cached. Subsequent requests only send headers that changed. The Authorization header, once sent, is referenced by a short index rather than retransmitted in full.</p>
<p>On a mobile application making dozens of authenticated requests per session, this compression is a meaningful bandwidth saving, especially on slow networks where every byte matters.</p>
<h3 id="heading-server-push">Server Push</h3>
<p>HTTP/2 allows the server to proactively send data to the client without waiting for a request. The client opens a stream and the server keeps pushing messages through it as events occur.</p>
<p>This is the mechanism behind gRPC server streaming. The client sends one <code>WatchBalance</code> request and the server pushes a new <code>BalanceResponse</code> every time the balance changes. No polling or repeated requests. The connection stays open and the server speaks whenever it has something new to say.</p>
<h2 id="heading-the-four-grpc-communication-patterns">The Four gRPC Communication Patterns</h2>
<p>This is the most important section of this article. gRPC doesn't have one communication model. It has four. Each one is defined precisely in the <code>.proto</code> file and serves different use cases.</p>
<h3 id="heading-pattern-1-unary-rpc">Pattern 1: Unary RPC</h3>
<p>One request from the client and one response from the server. This is identical to a REST API call in terms of the request-response flow.</p>
<pre><code class="language-csharp">rpc Login (LoginRequest) returns (LoginResponse);
</code></pre>
<pre><code class="language-plaintext">Client ----LoginRequest----&gt; Server
Client &lt;---LoginResponse---- Server
Done.
</code></pre>
<p><strong>When to use Unary RPC:</strong> Login, profile fetch, payment initiation, data creation, configuration retrieval: any operation that follows a simple ask-and-answer pattern.</p>
<p><strong>Dart implementation:</strong></p>
<pre><code class="language-dart">Future&lt;LoginResponse&gt; login(String email, String password) async {
  try {
    return await _client.login(
      LoginRequest(email: email, password: password),
    );
  } on GrpcError catch (e) {
    throw _mapGrpcError(e);
  }
}
</code></pre>
<p><strong>Go server implementation:</strong></p>
<pre><code class="language-go">func (s *bankingServer) Login(
    ctx context.Context,
    req *pb.LoginRequest,
) (*pb.LoginResponse, error) {
    user, err := s.authService.Login(req.Email, req.Password)
    if err != nil {
        return nil, status.Errorf(codes.Unauthenticated, "invalid credentials: %v", err)
    }
    token, _ := s.tokenService.Generate(user.Id)
    return &amp;pb.LoginResponse{
        Token:  token,
        UserId: user.Id,
    }, nil
}
</code></pre>
<h3 id="heading-pattern-2-server-streaming-rpc">Pattern 2: Server Streaming RPC</h3>
<p>One request from the client and a continuous stream of responses from the server. The connection stays open and the server pushes messages as they become available.</p>
<pre><code class="language-csharp">rpc WatchBalance (BalanceRequest) returns (stream BalanceResponse);
rpc StreamTransactions (TransactionRequest) returns (stream Transaction);
</code></pre>
<pre><code class="language-plaintext">Client ----BalanceRequest----&gt; Server
Client &lt;---BalanceResponse---- Server (balance: 500000)
Client &lt;---BalanceResponse---- Server (balance: 495000, after a debit)
Client &lt;---BalanceResponse---- Server (balance: 995000, after a credit)
[stream stays open, server pushes on every change]
</code></pre>
<p><strong>When to use Server Streaming:</strong> Live account balance, real-time transaction notifications, live stock prices, sports scores, news feeds, system monitoring dashboards: anything where the server has an ongoing series of updates to deliver.</p>
<p><strong>Dart implementation:</strong></p>
<pre><code class="language-csharp">Stream&lt;BalanceResponse&gt; watchBalance(String userId) {
  return _client.watchBalance(
    BalanceRequest(userId: userId),
  );
}
</code></pre>
<p>In Flutter, consume this with a <code>StreamBuilder</code>:</p>
<pre><code class="language-csharp">StreamBuilder&lt;BalanceResponse&gt;(
  stream: _dataSource.watchBalance(currentUserId),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator();
    }

    if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    }

    if (!snapshot.hasData) {
      return const Text('Waiting for balance...');
    }

    final balance = snapshot.data!;
    return Column(
      children: [
        Text(
          '${balance.currency} ${balance.balance.toStringAsFixed(2)}',
          style: const TextStyle(
            fontSize: 36,
            fontWeight: FontWeight.bold,
          ),
        ),
        Text(
          'Updated: ${DateTime.fromMillisecondsSinceEpoch(balance.timestamp.toInt())}',
        ),
      ],
    );
  },
)
</code></pre>
<p>Every time the server pushes a new balance, the <code>StreamBuilder</code> calls <code>builder</code> again and the widget shows the updated value. There's zero polling logic or manual refresh. The server speaks and the widget listens.</p>
<p><strong>Go server implementation:</strong></p>
<pre><code class="language-csharp">func (s *bankingServer) WatchBalance(
    req *pb.BalanceRequest,
    stream pb.BankingService_WatchBalanceServer,
) error {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case &lt;-stream.Context().Done():
            return nil
        case &lt;-ticker.C:
            balance, err := s.accountService.GetBalance(req.UserId)
            if err != nil {
                return status.Errorf(codes.Internal, "failed to fetch balance: %v", err)
            }

            if err := stream.Send(&amp;pb.BalanceResponse{
                Balance:   balance.Amount,
                Currency:  balance.Currency,
                Timestamp: time.Now().UnixMilli(),
            }); err != nil {
                return err
            }
        }
    }
}
</code></pre>
<h3 id="heading-pattern-3-client-streaming-rpc">Pattern 3: Client Streaming RPC</h3>
<p>The client sends a stream of messages to the server. The server processes them all and responds once at the end.</p>
<pre><code class="language-csharp">rpc UploadDocument (stream DocumentChunk) returns (UploadResponse);
</code></pre>
<pre><code class="language-plaintext">Client ----Chunk 1 (bytes 0-1024)-----&gt; Server
Client ----Chunk 2 (bytes 1024-2048)--&gt; Server
Client ----Chunk 3 (bytes 2048-3072)--&gt; Server
Client ----Chunk 4 (last chunk)-------&gt; Server
Client &lt;---UploadResponse-------------- Server (document_id: "doc_001")
</code></pre>
<p><strong>When to use Client Streaming:</strong> Uploading large files (KYC documents, profile photos) in chunks, sending a batch of sensor readings, submitting bulk records to a server.</p>
<p><strong>Dart implementation:</strong></p>
<pre><code class="language-dart">Future&lt;UploadResponse&gt; uploadDocument(
  List&lt;Uint8List&gt; chunks,
  String documentType,
) async {
  try {
    Stream&lt;DocumentChunk&gt; chunkStream() async* {
      for (int i = 0; i &lt; chunks.length; i++) {
        yield DocumentChunk(
          data: chunks[i],
          documentType: documentType,
          chunkIndex: i,
          isLast: i == chunks.length - 1,
        );
      }
    }

    return await _client.uploadDocument(chunkStream());
  } on GrpcError catch (e) {
    throw _mapGrpcError(e);
  }
}
</code></pre>
<p><code>chunkStream()</code> is an async generator function. The <code>async*</code> keyword means it yields values over time rather than returning a single value. Each <code>yield</code> produces one <code>DocumentChunk</code> message that gRPC sends to the server. The server receives these one by one and processes them all before sending a single <code>UploadResponse</code> at the end.</p>
<p><strong>Go server implementation:</strong></p>
<pre><code class="language-go">func (s *bankingServer) UploadDocument(
    stream pb.BankingService_UploadDocumentServer,
) error {
    var allData []byte
    var documentType string

    for {
        chunk, err := stream.Recv()
        if err == io.EOF {
            break
        }
        if err != nil {
            return status.Errorf(codes.Internal, "failed to receive chunk: %v", err)
        }

        allData = append(allData, chunk.Data...)
        documentType = chunk.DocumentType
    }

    docId, err := s.documentService.Store(allData, documentType)
    if err != nil {
        return status.Errorf(codes.Internal, "failed to store document: %v", err)
    }

    return stream.SendAndClose(&amp;pb.UploadResponse{
        Success:    true,
        DocumentId: docId,
        Message:    "Document uploaded successfully",
    })
}
</code></pre>
<h3 id="heading-pattern-4-bidirectional-streaming-rpc">Pattern 4: Bidirectional Streaming RPC</h3>
<p>Both the client and server stream messages simultaneously. Both sides can send at any time. Neither waits for the other.</p>
<pre><code class="language-csharp">rpc Chat (stream ChatMessage) returns (stream ChatMessage);
</code></pre>
<pre><code class="language-plaintext">Client ----"Hello"---------------------------&gt; Server
Server &lt;---"Hi, how can I help?"-------------- Client
Client ----"What is my account balance?"-----&gt; Server
Server &lt;---"Your balance is NGN 500,000"------ Client
Server &lt;---"New transaction alert: -5,000"---- Client (server-initiated)
Client ----"Thanks"--------------------------&gt; Server
[both sides communicate freely and simultaneously]
</code></pre>
<p><strong>When to use Bidirectional Streaming:</strong> Real-time chat, live collaborative document editing, multiplayer game state synchronization, interactive trading terminals, real-time customer support sessions.</p>
<p><strong>Dart implementation:</strong></p>
<pre><code class="language-csharp">void startChat(String userId) {
  final outgoing = StreamController&lt;ChatMessage&gt;();

  final incoming = _client.chat(outgoing.stream);

  incoming.listen(
    (message) {
      print('${message.senderId}: ${message.content}');
    },
    onError: (error) {
      print('Chat error: $error');
    },
    onDone: () {
      print('Chat session ended');
    },
  );

  outgoing.add(ChatMessage(
    senderId: userId,
    content: 'Hello, I need help with my account',
    timestamp: DateTime.now().millisecondsSinceEpoch,
  ));
}
</code></pre>
<p><code>StreamController</code> manages the outgoing message stream. You add messages to <code>outgoing</code> whenever the user sends something. The incoming stream delivers messages from the server. Both run simultaneously over the same HTTP/2 connection.</p>
<p><strong>Go server implementation:</strong></p>
<pre><code class="language-go">func (s *bankingServer) Chat(stream pb.BankingService_ChatServer) error {
    for {
        msg, err := stream.Recv()
        if err == io.EOF {
            return nil
        }
        if err != nil {
            return err
        }

        response := s.chatService.Process(msg)
        if err := stream.Send(&amp;pb.ChatMessage{
            SenderId:  "support_agent",
            Content:   response,
            Timestamp: time.Now().UnixMilli(),
        }); err != nil {
            return err
        }
    }
}
</code></pre>
<h2 id="heading-the-protobuf-repository-organizational-best-practice">The Protobuf Repository: Organizational Best Practice</h2>
<p>In a small project, the <code>.proto</code> file can live inside the backend repository. The mobile engineer clones the backend repo to get it. This works at small scale.</p>
<p>In any organization of meaningful size, this approach breaks down. The backend repo becomes the source of truth, giving the backend team unilateral control over the contract. Other teams find out about changes when their builds break.</p>
<p>The industry best practice is a dedicated protobuf repository: a standalone repository that belongs to everyone and is owned exclusively by no one.</p>
<pre><code class="language-plaintext">fintech-api-contracts/
  proto/
    auth/
      auth.proto
    banking/
      banking.proto
    payments/
      payments.proto
    notifications/
      notifications.proto
    kyc/
      kyc.proto
  scripts/
    generate_dart.sh
    generate_go.sh
    generate_python.sh
  README.md
</code></pre>
<h3 id="heading-how-contract-changes-work">How Contract Changes Work</h3>
<p>Every API change follows the same process:</p>
<pre><code class="language-plaintext">Engineer proposes a change to banking.proto
          |
          raises a Pull Request in fintech-api-contracts
          |
Flutter team lead reviews:
  "Does this break our client? Do we need to update?"

Go backend lead reviews:
  "Is this implementable? Does it follow our conventions?"

React web lead reviews:
  "Does the web client need changes?"

Python data lead reviews:
  "Does this affect our data pipelines?"
          |
All teams approve
          |
PR merges — the change is now the law
          |
Every team runs their code generation script
          |
Builds fail where breaking changes exist
Changes are caught at compile time
Before any code reaches production
</code></pre>
<p>This process gives you something REST with documentation can never provide: guaranteed contract synchronization across every team, enforced by the compiler, before anything reaches users.</p>
<h2 id="heading-building-a-complete-grpc-system-with-dart-and-flutter">Building a Complete gRPC System with Dart and Flutter</h2>
<p>Now let's put everything together in a complete, production-structured example.</p>
<h3 id="heading-project-setup">Project Setup</h3>
<p>Add the gRPC dependency to your Flutter project:</p>
<pre><code class="language-yaml"># pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  grpc: ^3.2.4
  protobuf: ^3.1.0

dev_dependencies:
  protoc_plugin: ^21.1.2
</code></pre>
<p>Install the protoc compiler and the Dart plugin:</p>
<pre><code class="language-yaml"># macOS
brew install protobuf

# Install the Dart protoc plugin
dart pub global activate protoc_plugin
</code></pre>
<p>Generate the Dart code from the proto file:</p>
<pre><code class="language-bash">protoc \
  --dart_out=grpc:lib/generated \
  -I proto \
  proto/banking/banking.proto
</code></pre>
<h3 id="heading-the-data-source-layer">The Data Source Layer</h3>
<pre><code class="language-dart">// lib/features/banking/data/datasources/banking_remote_datasource.dart

import 'package:grpc/grpc.dart';
import '../../../../generated/banking.pb.dart';
import '../../../../generated/banking.pbgrpc.dart';
import '../../../../core/error/app_exception.dart';

class BankingRemoteDataSource {
  late final BankingServiceClient _client;
  late final ClientChannel _channel;

  BankingRemoteDataSource({
    required String host,
    required int port,
    required String authToken,
  }) {
   
    _channel = ClientChannel(
      host,
      port: port,
      options: const ChannelOptions(
        credentials: ChannelCredentials.secure(),
        connectionTimeout: Duration(seconds: 10),
      ),
    );

   
    _client = BankingServiceClient(
      _channel,
      options: CallOptions(
        metadata: {'authorization': 'Bearer $authToken'},
        timeout: const Duration(seconds: 30),
      ),
    );
  }

  Future&lt;LoginResponse&gt; login(String email, String password) async {
    try {
      return await _client.login(
        LoginRequest(email: email, password: password),
      );
    } on GrpcError catch (e) {
      throw _mapGrpcError(e);
    }
  }

  Future&lt;UserProfile&gt; getProfile(String userId) async {
    try {
      return await _client.getProfile(
        ProfileRequest(userId: userId),
      );
    } on GrpcError catch (e) {
      throw _mapGrpcError(e);
    }
  }

  Stream&lt;BalanceResponse&gt; watchBalance(String userId) {
    return _client
        .watchBalance(BalanceRequest(userId: userId))
        .handleError((error) {
      if (error is GrpcError) throw _mapGrpcError(error);
      throw error;
    });
  }

  Stream&lt;Transaction&gt; streamTransactions(String userId, {int limit = 20}) {
    return _client
        .streamTransactions(
          TransactionRequest(userId: userId, limit: limit),
        )
        .handleError((error) {
      if (error is GrpcError) throw _mapGrpcError(error);
      throw error;
    });
  }

  Future&lt;UploadResponse&gt; uploadDocument(
    List&lt;Uint8List&gt; chunks,
    String documentType,
  ) async {
    try {
      Stream&lt;DocumentChunk&gt; chunkStream() async* {
        for (int i = 0; i &lt; chunks.length; i++) {
          yield DocumentChunk(
            data: chunks[i],
            documentType: documentType,
            chunkIndex: i,
            isLast: i == chunks.length - 1,
          );
        }
      }
      return await _client.uploadDocument(chunkStream());
    } on GrpcError catch (e) {
      throw _mapGrpcError(e);
    }
  }

  ResponseStream&lt;ChatMessage&gt; startChat(Stream&lt;ChatMessage&gt; outgoing) {
    return _client.chat(outgoing);
  }

  Future&lt;void&gt; dispose() async {
    await _channel.shutdown();
  }

  AppException _mapGrpcError(GrpcError error) {
    switch (error.code) {
      case StatusCode.unauthenticated:
        return AppException.unauthorized(
          message: error.message ?? 'Unauthorized',
        );
      case StatusCode.notFound:
        return AppException.notFound(
          message: error.message ?? 'Not found',
        );
      case StatusCode.deadlineExceeded:
        return AppException.timeout(message: 'Request timed out');
      case StatusCode.unavailable:
        return AppException.serverUnavailable(
          message: 'Service unavailable',
        );
      default:
        return AppException.unknown(
          message: error.message ?? 'Unknown error',
        );
    }
  }
}
</code></pre>
<p>Let's walk through the important decisions in this data source.</p>
<h4 id="heading-the-channel">The Channel:</h4>
<pre><code class="language-csharp">_channel = ClientChannel(
  host,
  port: port,
  options: const ChannelOptions(
    credentials: ChannelCredentials.secure(),
    connectionTimeout: Duration(seconds: 10),
  ),
);
</code></pre>
<p>The channel is the physical HTTP/2 connection to the server. You create it once and reuse it for every call. <code>ChannelCredentials.secure()</code> enables TLS encryption. <code>connectionTimeout</code> prevents the app from waiting indefinitely if the server is unreachable.</p>
<p>The channel is the core of gRPC's performance advantage. A single persistent channel multiplexes all requests through one HTTP/2 connection. Creating a new channel per request would eliminate this advantage entirely and perform worse than REST.</p>
<h4 id="heading-authentication-via-metadata">Authentication via Metadata:</h4>
<pre><code class="language-dart">_client = BankingServiceClient(
  _channel,
  options: CallOptions(
    metadata: {'authorization': 'Bearer $authToken'},
    timeout: const Duration(seconds: 30),
  ),
);
</code></pre>
<p>gRPC uses metadata (key-value pairs) for what HTTP uses headers. Passing the auth token as metadata on the <code>CallOptions</code> means every single call made through this client automatically includes the Authorization metadata. You write it once. It applies everywhere.</p>
<h4 id="heading-error-mapping">Error Mapping:</h4>
<pre><code class="language-csharp">AppException _mapGrpcError(GrpcError error) {
  switch (error.code) {
    case StatusCode.unauthenticated:
      return AppException.unauthorized(...);
    case StatusCode.deadlineExceeded:
      return AppException.timeout(...);
    ...
  }
}
</code></pre>
<p>gRPC has its own set of status codes similar to HTTP status codes but not identical. Mapping them to your application's exception types at the data source layer means the rest of your code (use cases, notifiers, widgets) never deals with gRPC-specific errors directly. Your domain layer stays clean and framework-independent.</p>
<h3 id="heading-the-repository-layer">The Repository Layer</h3>
<pre><code class="language-dart">
abstract class BankingRepository {
  Future&lt;Result&lt;UserProfile, AppException&gt;&gt; getProfile(String userId);
  Stream&lt;BalanceResponse&gt; watchBalance(String userId);
  Stream&lt;Transaction&gt; streamTransactions(String userId);
  Future&lt;Result&lt;UploadResponse, AppException&gt;&gt; uploadDocument(
    List&lt;Uint8List&gt; chunks,
    String documentType,
  );
}


class BankingRepositoryImpl implements BankingRepository {
  final BankingRemoteDataSource _dataSource;

  BankingRepositoryImpl(this._dataSource);

  @override
  Future&lt;Result&lt;UserProfile, AppException&gt;&gt; getProfile(String userId) async {
    try {
      final profile = await _dataSource.getProfile(userId);
      return Result.success(profile);
    } on AppException catch (e) {
      return Result.failure(e);
    }
  }

  @override
  Stream&lt;BalanceResponse&gt; watchBalance(String userId) {
    return _dataSource.watchBalance(userId);
  }

  @override
  Stream&lt;Transaction&gt; streamTransactions(String userId) {
    return _dataSource.streamTransactions(userId);
  }

  @override
  Future&lt;Result&lt;UploadResponse, AppException&gt;&gt; uploadDocument(
    List&lt;Uint8List&gt; chunks,
    String documentType,
  ) async {
    try {
      final response = await _dataSource.uploadDocument(chunks, documentType);
      return Result.success(response);
    } on AppException catch (e) {
      return Result.failure(e);
    }
  }
}
</code></pre>
<h3 id="heading-the-riverpod-providers">The Riverpod Providers</h3>
<pre><code class="language-dart">
part 'banking_providers.g.dart';

@riverpod
Stream&lt;BalanceResponse&gt; balanceStream(BalanceStreamRef ref, String userId) {
  final repository = ref.watch(bankingRepositoryProvider);
  return repository.watchBalance(userId);
}

@riverpod
Stream&lt;Transaction&gt; transactionStream(
  TransactionStreamRef ref,
  String userId,
) {
  final repository = ref.watch(bankingRepositoryProvider);
  return repository.streamTransactions(userId);
}
</code></pre>
<p>With Riverpod, a provider that returns a <code>Stream</code> automatically becomes an <code>AsyncValue</code> that widgets can watch. Every new value pushed from the gRPC server stream triggers a widget rebuild automatically.</p>
<h3 id="heading-the-ui">The UI</h3>
<pre><code class="language-dart">// lib/features/banking/presentation/pages/dashboard_page.dart
class DashboardPage extends ConsumerWidget {
  final String userId;

  const DashboardPage({required this.userId, super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final balanceAsync = ref.watch(balanceStreamProvider(userId));
    final transactionsAsync = ref.watch(transactionStreamProvider(userId));

    return Scaffold(
      appBar: AppBar(title: const Text('Dashboard')),
      body: Column(
        children: [
          balanceAsync.when(
            data: (balance) =&gt; BalanceCard(
              amount: balance.balance,
              currency: balance.currency,
            ),
            loading: () =&gt; const BalanceShimmer(),
            error: (e, _) =&gt; ErrorCard(message: e.toString()),
          ),

          const SizedBox(height: 24),

          Expanded(
            child: transactionsAsync.when(
              data: (transaction) =&gt; TransactionTile(
                transaction: transaction,
              ),
              loading: () =&gt; const TransactionShimmer(),
              error: (e, _) =&gt; ErrorCard(message: e.toString()),
            ),
          ),
        ],
      ),
    );
  }
}
</code></pre>
<p>Both the balance and transactions arrive through gRPC server streams. Both update in real-time as the server pushes new data. Both are handled identically through Riverpod's <code>AsyncValue</code> pattern. One framework with all patterns covered.</p>
<h2 id="heading-production-concerns">Production Concerns</h2>
<h3 id="heading-authentication-with-interceptors">Authentication with Interceptors</h3>
<p>For more granular authentication control, such as refreshing an expired token and retrying automatically, you implement a client interceptor:</p>
<pre><code class="language-dart">class AuthInterceptor extends ClientInterceptor {
  final TokenService _tokenService;

  AuthInterceptor(this._tokenService);

  @override
  ResponseFuture&lt;R&gt; interceptUnary&lt;Q, R&gt;(
    ClientMethod&lt;Q, R&gt; method,
    Q request,
    CallOptions options,
    ClientUnaryInvoker&lt;Q, R&gt; invoker,
  ) {
    final token = _tokenService.currentToken;
    final authenticatedOptions = options.mergedWith(
      CallOptions(metadata: {'authorization': 'Bearer $token'}),
    );
    return invoker(method, request, authenticatedOptions);
  }

  @override
  ResponseStream&lt;R&gt; interceptServerStreaming&lt;Q, R&gt;(
    ClientMethod&lt;Q, R&gt; method,
    Q request,
    CallOptions options,
    ClientServerStreamingInvoker&lt;Q, R&gt; invoker,
  ) {
    final token = _tokenService.currentToken;
    final authenticatedOptions = options.mergedWith(
      CallOptions(metadata: {'authorization': 'Bearer $token'}),
    );
    return invoker(method, request, authenticatedOptions);
  }
}
</code></pre>
<p>Pass the interceptor when creating the client:</p>
<pre><code class="language-dart">_client = BankingServiceClient(
  _channel,
  interceptors: [AuthInterceptor(tokenService)],
);
</code></pre>
<p>The interceptor fires on every call automatically. The data source code never touches auth logic directly.</p>
<h3 id="heading-error-handling-grpc-status-codes">Error Handling: gRPC Status Codes</h3>
<p>gRPC defines a standard set of status codes that every implementation follows:</p>
<table>
<thead>
<tr>
<th>Status Code</th>
<th>Meaning</th>
<th>Recommended Action</th>
</tr>
</thead>
<tbody><tr>
<td>OK (0)</td>
<td>Success</td>
<td>Use the response</td>
</tr>
<tr>
<td>CANCELLED (1)</td>
<td>Client cancelled the call</td>
<td>Ignore or log</td>
</tr>
<tr>
<td>UNKNOWN (2)</td>
<td>Unknown server error</td>
<td>Show generic error</td>
</tr>
<tr>
<td>INVALID_ARGUMENT (3)</td>
<td>Bad request data</td>
<td>Show validation error</td>
</tr>
<tr>
<td>DEADLINE_EXCEEDED (4)</td>
<td>Call timed out</td>
<td>Retry or show timeout message</td>
</tr>
<tr>
<td>NOT_FOUND (5)</td>
<td>Resource does not exist</td>
<td>Show not found UI</td>
</tr>
<tr>
<td>ALREADY_EXISTS (6)</td>
<td>Duplicate resource</td>
<td>Show conflict message</td>
</tr>
<tr>
<td>PERMISSION_DENIED (7)</td>
<td>Insufficient permissions</td>
<td>Show access denied</td>
</tr>
<tr>
<td>UNAUTHENTICATED (16)</td>
<td>Invalid or expired credentials</td>
<td>Navigate to login</td>
</tr>
<tr>
<td>RESOURCE_EXHAUSTED (8)</td>
<td>Rate limited</td>
<td>Back off and retry</td>
</tr>
<tr>
<td>UNAVAILABLE (14)</td>
<td>Server temporarily down</td>
<td>Show offline message</td>
</tr>
</tbody></table>
<pre><code class="language-dart">AppException _mapGrpcError(GrpcError error) {
  switch (error.code) {
    case StatusCode.unauthenticated:
      return AppException.unauthorized(message: 'Session expired');
    case StatusCode.permissionDenied:
      return AppException.forbidden(message: 'Access denied');
    case StatusCode.notFound:
      return AppException.notFound(message: error.message ?? 'Not found');
    case StatusCode.deadlineExceeded:
      return AppException.timeout(message: 'Request timed out');
    case StatusCode.unavailable:
      return AppException.serverUnavailable(message: 'Service unavailable');
    case StatusCode.resourceExhausted:
      return AppException.rateLimited(message: 'Too many requests');
    case StatusCode.invalidArgument:
      return AppException.validation(
        message: error.message ?? 'Invalid input',
      );
    default:
      return AppException.unknown(
        message: error.message ?? 'An error occurred',
      );
  }
}
</code></pre>
<h3 id="heading-deadlines-and-timeouts">Deadlines and Timeouts</h3>
<p>Every gRPC call should have a deadline. Without deadlines, a slow server can make your app hang indefinitely.</p>
<p>Per-call deadline:</p>
<pre><code class="language-dart">Future&lt;UserProfile&gt; getProfile(String userId) async {
  return await _client.getProfile(
    ProfileRequest(userId: userId),
    options: CallOptions(timeout: const Duration(seconds: 10)),
  );
}
</code></pre>
<p>Default deadline for all calls:</p>
<pre><code class="language-dart">_client = BankingServiceClient(
  _channel,
  options: CallOptions(
    timeout: const Duration(seconds: 30),
    metadata: {'authorization': 'Bearer $authToken'},
  ),
);
</code></pre>
<p>When the deadline is exceeded, the call throws a <code>GrpcError</code> with <code>StatusCode.deadlineExceeded</code>, which your error mapper handles appropriately.</p>
<h3 id="heading-logging-interceptor">Logging Interceptor</h3>
<pre><code class="language-dart">class LoggingInterceptor extends ClientInterceptor {
  @override
  ResponseFuture&lt;R&gt; interceptUnary&lt;Q, R&gt;(
    ClientMethod&lt;Q, R&gt; method,
    Q request,
    CallOptions options,
    ClientUnaryInvoker&lt;Q, R&gt; invoker,
  ) {
    final stopwatch = Stopwatch()..start();
    debugPrint('[gRPC] --&gt; ${method.path}');

    final response = invoker(method, request, options);

    response.then((_) {
      stopwatch.stop();
      debugPrint(
        '[gRPC] &lt;-- ${method.path} (${stopwatch.elapsedMilliseconds}ms)',
      );
    }).catchError((error) {
      stopwatch.stop();
      debugPrint(
        '[gRPC] ERROR ${method.path}: $error (${stopwatch.elapsedMilliseconds}ms)',
      );
    });

    return response;
  }
}
</code></pre>
<h2 id="heading-grpc-vs-rest-vs-websockets-when-to-use-what">gRPC vs REST vs WebSockets: When to Use What</h2>
<h3 id="heading-when-to-use-rest">When to Use REST</h3>
<p>The API is consumed by third-party developers or external partners. JSON over HTTP is the universal language that every developer in every language can access immediately without learning new tooling.</p>
<p>The operation is simple request-response with no streaming requirements and only one client platform. REST is simpler to implement, simpler to debug, and simpler to test for straightforward CRUD operations.</p>
<p>Public documentation and human readability matter. REST with OpenAPI/Swagger gives you browsable, testable documentation that developers can explore in a browser.</p>
<p>Caching is important. REST GET responses can be cached at every layer: CDN, reverse proxy, browser cache. gRPC requests can't leverage standard HTTP caching.</p>
<h3 id="heading-use-websockets-when">Use WebSockets When</h3>
<p>You need true bidirectional real-time communication and gRPC isn't already in your stack. Chat applications, multiplayer games, and collaborative tools where both sides need to speak freely are natural WebSocket use cases.</p>
<p>Browser support without a proxy layer is required. WebSockets work natively in every modern browser. gRPC in the browser requires gRPC-Web and a proxy layer.</p>
<h3 id="heading-when-to-use-grpc">When to Use gRPC</h3>
<p>Multiple platform teams share the same service contract. When Flutter, React, Go, and Python services all call the same backend, a <code>.proto</code> file enforced by the compiler prevents contract drift across every team.</p>
<p>Large payloads are called by many internal applications. The more fields in the payload and the more applications consuming it, the stronger the case for protobuf's binary encoding and generated clients.</p>
<p>Network conditions are variable and payload size matters. Users on 2G or 3G connections benefit directly from protobuf's compact binary format. The same data in protobuf can be 3 to 10 times smaller than JSON, translating to faster load times and lower data consumption for users on limited data plans.</p>
<p>Real-time streaming is required and you want one unified framework for all communication patterns. gRPC's four patterns cover every scenario without requiring a separate WebSocket server alongside your API.</p>
<p>Service-to-service communication at high frequency is involved. Two internal services calling each other thousands of times per second over a persistent multiplexed HTTP/2 connection with binary protobuf encoding will significantly outperform REST with JSON over HTTP/1.1.</p>
<h2 id="heading-the-hybrid-architecture">The Hybrid Architecture</h2>
<p>The mature engineering decision is not choosing gRPC over REST or REST over gRPC. It's knowing where each belongs and using both deliberately.</p>
<p>Most organizations of meaningful scale end up with a hybrid:</p>
<p>The public REST API serves external consumers who need simplicity and JSON. The internal gRPC network handles high-frequency, high-performance service-to-service calls. The mobile gRPC endpoints give Flutter clients real-time capabilities over efficient binary connections.</p>
<p>Each layer uses the right tool for its specific requirements. No ideological commitment to one protocol. Pure engineering pragmatism.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Remote Procedure Calls began with a simple observation: network communication shouldn't require developers to think about network communication. Calling a function on another machine should feel like calling a function on your own.</p>
<p>Protocol Buffers took this further by solving the data problem. JSON is readable but verbose. Binary encoding with a compiler-enforced schema produces payloads that are smaller, faster to parse, and guaranteed to match the contract every team agreed on. For users on slow networks and internal systems processing millions of requests daily, this efficiency is a business advantage.</p>
<p>gRPC combined RPC semantics, Protocol Buffer encoding, and HTTP/2 transport into a framework that supports four distinct communication patterns: unary request-response, server streaming, client streaming, and bidirectional streaming. All from the same generated client, using the same persistent connection, and enforced by the same <code>.proto</code> contract.</p>
<p>The organizational practice of a shared protobuf repository transforms gRPC from a technical tool into an engineering discipline. Contract changes go through review. Breaking changes are caught by the compiler. Every team generates their own strongly typed client from the same source of truth and stays in sync automatically, regardless of programming language.</p>
<p>In Flutter specifically, gRPC server streams integrate naturally with Dart's <code>Stream</code> type and Riverpod's stream providers. Real-time balance updates and live transaction feeds that would require polling with REST or a separate WebSocket implementation become simple stream subscriptions. The server pushes, the widget listens, and nothing else is required.</p>
<p>The decision of when to use gRPC versus REST versus WebSockets isn't about preference. It's about matching the tool to the requirement. Public APIs belong behind REST. High-frequency internal service communication belongs on gRPC. Large payloads consumed by many internal systems belong in protobuf. Real-time bidirectional features belong on gRPC streaming. Users on variable networks deserve the smallest payloads you can give them.</p>
<p>Understanding all of these tools, understanding why they exist, and knowing when to reach for each one is what separates engineers who use tools from engineers who think in systems.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Overcome a Negative Performance Review and Become a Better Developer ]]>
                </title>
                <description>
                    <![CDATA[ I was a year into my new job at Google. After repeated warnings about underperformance, my manager sat me down. I was being placed on a Performance Improvement Plan (PIP). For those unfamiliar, a PIP at Google is a two-month plan to show improvement ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/clawing-out-of-underperformance/</link>
                <guid isPermaLink="false">69038e8be43cf9a3614ff2fd</guid>
                
                    <category>
                        <![CDATA[ pip ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Self Improvement  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Moshe Siegel ]]>
                </dc:creator>
                <pubDate>Thu, 30 Oct 2025 16:12:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761774919543/5eb6447b-d709-41cb-9383-73dacde102a7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I was a year into my new job at Google. After repeated warnings about underperformance, my manager sat me down. I was being placed on a Performance Improvement Plan (PIP).</p>
<p>For those unfamiliar, a PIP at Google is a two-month plan to show improvement – a final chance to prove yourself. You’re given a project and a strict deadline. Deliver successfully, or you’re fired. There are no extensions, no middle ground. </p>
<p>Scary thoughts about providing for my family’s finances raced through my mind. But my deeper fear was this: what story would I carry about myself if I tried to persevere and failed?</p>
<p>If I got fired, I would need to face job interviews. And I knew the question would come: <em>“Tell me about a project you worked on at Google that you’re most proud of.”</em> The honest answer was that I didn’t have one. I hadn’t yet excelled at a project, hadn’t gone deep enough into any system to truly own it. I imagined myself sitting in an interview, with a blank face, with nothing to say. </p>
<p>That dreadful image became my motivation. I wanted a project I could truly own, something I could explain inside and out, regardless of how the PIP ended. I’m also not the type of person who simply backs down when things get tough. I needed to prove to myself that I could rise up. I was gonna give the project everything I had, week after week after week. That singular commitment became the start of my transformation into a more focused, disciplined engineer.</p>
<p>In this guide, you’ll learn how to turn professional setbacks into catalysts for growth. While examining my journey on Google’s Performance Improvement Plan, I’ll show you how to face underperformance head-on, rebuild your confidence, and come out stronger than before. You’ll see how focus, discipline, and gratitude can turn the lowest points of your career into launch ramps for acceleration.</p>
<h3 id="heading-heres-what-ill-cover">Here’s what I’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-the-backstory">The Backstory</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-pip-begins">The PIP Begins</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-project">The Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-fatherhood">Fatherhood</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-letting-go">Letting Go</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-whats-next">What’s Next</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-closing">Closing</a></p>
</li>
</ol>
<h2 id="heading-the-backstory">The Backstory</h2>
<p>To understand how I landed in that chair across from my manager, you need to know where I came from. Before Google, I’d worked at Meta. I was hired there as an IC3 (entry-level engineer) and promoted after a year to IC4 (mid-level). But that promotion didn't come from technical excellence. It came from my connecting our engineering projects to the business’ needs.</p>
<p>I had worked on a payments system used by large enterprises. By sitting with the operations staff and customer service reps, I spotted inefficiencies and built small features that saved time, reduced errors, and allowed the team to scale. Those changes had a big impact, and they earned me a promotion. But, in hindsight, my success had come from soft skills such as teamwork and business awareness. I hadn’t actually developed the technical knowledge expected of an IC4.</p>
<p>On my team at Google, technical mastery was the main thing we were measured on, while business awareness was a side point. On top of that, I had recently immigrated from the United States to Israel and needed to learn the local language of Hebrew and the local culture. It was a lot all at once: new country, new language, new company, and strong engineering expectations.</p>
<p>The gap between my technical skills and those of my peers eventually led to my being placed on a Performance Improvement Plan.</p>
<h2 id="heading-the-pip-begins">The PIP Begins</h2>
<p>When the PIP started, I increased my working hours to 60 hours per week. I cut out almost everything else in my life – news, side projects, YouTube – and focused only on my work. When you’re falling behind, cutting distractions isn’t punishment. Rather, it’s how you create the quiet needed to actually improve.</p>
<p>It was brutal. Despite all the intense hours, I was slower than my coworkers. They shipped code confidently while I second-guessed myself. They reviewed my work and pointed out ways to improve it.</p>
<p>Some nights I walked away from my desk ready to cry. I was exhausted, and even after pouring in all those hours, I still wasn’t keeping pace. I felt defeated.</p>
<p>But I kept grinding away, day after day, week after week. Ignoring every side project and distraction forced me to confront the real issue: my lack of depth in the systems I was working on.</p>
<h2 id="heading-the-project">The Project</h2>
<p>For confidentiality reasons, I won’t describe the actual project I was assigned. But here’s a similar example.</p>
<p>Imagine Google had a small music game built into Google Search. My task was to add a line of text above the game’s start button telling players how many people had reached the next level. The goal was to encourage more people to keep playing.</p>
<p>The text addition would run as an experiment. We’d launch it to a small percentage of users, measure the impact, and then either shut it down or roll it out to everyone.</p>
<p>The problem? At that time, Google Search didn’t even store how many players completed each level. So before I could add the text, I had to design and run a new data pipeline to track how many players completed each level of the game.</p>
<p>At first, I got lost. Just before my PIP began, our broader organization had been through a reorg, and my small team of five engineers was newly assigned to focus on games within Search. None of us had touched the gaming code before, and the particular game I was assigned hadn't had any meaningful updates in several years.</p>
<p>I spent days combing through design docs from 3-7 years earlier, only to find that the original authors had long since moved on. Each time I reached out, I’d get referred to someone else. Eventually, I found the current owner of the data storage systems for gaming. She had recently inherited them and hadn’t built the systems herself, but she helped me understand their current state. </p>
<p>With that clarity, I was finally making headway. But I realized I needed to rethink my priorities. Data pipeline code could be reviewed and deployed relatively quickly, while code changes to Google Search required slower, more comprehensive quality assurance checks. If I wanted to have any chance of meeting the PIP deadline, I had to shift focus to the Search-side work first.</p>
<p>As I dug deeper, another issue surfaced: the people who were listed as the engineering owners of the game hadn’t touched it in years and didn’t want to be involved anymore. I learned that our team would be running many more experiments on that code. Therefore, after consulting with my manager, I became the game’s code owner, the person ultimately responsible for all engineering decisions. </p>
<p>Taking ownership didn’t mean I suddenly moved fast or flawlessly. Some of my choices slowed me down. I aimed for near-perfect data accuracy when “mostly accurate” would have been enough for an experiment. I also wasted days digging through outdated documentation instead of simply reaching out to the people behind it.</p>
<p>After several days reading a four-year-old doc, I finally messaged the author. They immediately redirected me to someone else, who then forwarded me again. The third person turned out to be the current owner, and within minutes, they shared with me their private notes which clarified a ton.</p>
<p>But those mistakes were part of the learning curve. Each week, I dove deeper into the engineering tasks, internalized more of the systems, and made more progress than the week before.</p>
<p>By the time the final two weeks of the PIP arrived, I was operating at a whole new level. While the first month had felt like drowning, the last two weeks had felt like flying. I was excitedly diving into the code, unblocking myself, and helping teammates navigate the codebase.</p>
<p>That turnaround, from tears of frustration to the thrill of ownership, was exhilarating. For the first time at Google, I was independently driving my project forward. And I loved it.</p>
<p>When the PIP deadline arrived, though, I hadn’t yet delivered the full project. I was just a few hours of engineering work away from getting a working end-to-end flow with hardcoded data, but the actual data collection and experiment launch would have required about nine more days of engineering work.</p>
<p>On a PIP, “almost there” isn’t good enough. I was called in for a hearing with my director and HR, where I was given an opportunity to explain my case. </p>
<p>I didn’t walk into that final meeting empty-handed. I brought a detailed handoff plan listing the current state of the project, the remaining steps, and every contact and document another engineer would need to continue. I also brought a plan for improving collaboration amongst our various gaming engineers by creating a doc that would function as a centralized directory of all gaming systems, their owners, and their design docs. I offered to maintain this directory as a side effort, building it up naturally through my ongoing engineering work and conversations with past owners of the systems.</p>
<p>The hearing was an hour. I walked my director and HR through what I had shipped, my handoff plan, and my roadmap for unblocking future projects. I left the meeting proud of all that I’d learned over the previous two months. “<em>Whatever will be will be,</em>” I told myself. </p>
<p>A few days later, HR and my director called me back with their decision. Their feedback was straightforward: I had shown steady improvement, but I hadn’t delivered the final project on time, and therefore I hadn’t met expectations for my level.</p>
<p>Their feedback didn’t mention my handoff plan, my roadmap, nor my becoming the game’s code owner. That’s because a PIP isn’t a coaching program, it’s an evaluation. It doesn’t measure acceleration, it measures completion. It’s binary: You either deliver within the two months, or you don’t. And I hadn’t. </p>
<p>Upon hearing their decision, I thanked my director and the HR representative for having given me a final chance. I told them that the PIP had succeeded: it had built within me an internal engine of ownership over my engineering career. The fact that I would no longer be at Google was irrelevant. There would be no break in my internal transformation. </p>
<h2 id="heading-fatherhood">Fatherhood</h2>
<p>The official decision closed one chapter. But the habits I’d built during the PIP of focus, ownership, and accountability began reshaping more than just my work. They changed how I saw myself as a father and husband.</p>
<p>Before the PIP, I’d take my toddler to the playground after work. During it, I was often too drained for that. I’d sit him in front of the TV while I caught up on writing code or reading documentation. Date nights with my wife slipped away too. For a while, I wondered: What kind of father and husband does that make me?</p>
<p>One night, I was listening to financial coach Dave Ramsey, a religious Christian who often brings faith into his talk show. He spoke about a father’s responsibility to provide for his family. It reframed how I saw my long hours. Had I made more disciplined decisions and strengthened my engineering skills months earlier, I never would have been placed on the PIP. The newer, more focused, harder-working version of me wasn’t the problem, it was the solution. </p>
<p>So as my son sat in front of the TV, I reminded myself: An earlier version of me had made decisions which resulted in my now being less available for my family. The new me, the disciplined me, hadn’t made that choice. My current unavailability was a course correction that needed to happen for me to become the type of father and husband I wanted to become. </p>
<h2 id="heading-letting-go">Letting Go</h2>
<p>When I was let go, I felt a little lost. One of my biggest worries was financial. Not only did I lose a high-paying job, but I was also frustrated that I wouldn’t receive the yearly bonus Google gives its employees. I had plans for how I would use it, and letting go of that expectation was difficult.</p>
<p>I spoke with my Rabbi about being let go. He told me: In Judaism, we believe that everything happens for a reason. If I lost the job, then God wanted me to lose it. He encouraged me to view my overall experience at Google in positive terms, and to focus on appreciation to God for having a plan for me. It made logical sense, but I was still frustrated about the loss of the bonus income.</p>
<p>The inner peace came later, when I realized something simple: I hadn’t earned that yearly bonus. My performance before the PIP hadn’t justified it. It made sense, in fact it felt right, that I didn’t receive it. </p>
<p>With that acceptance came space for gratitude, especially toward my former coworkers and managers. During those final two months, they reviewed my work, pointed out ways to improve it, answered my questions, and patiently explained how Google’s internal engineering systems worked. I will always be grateful for how much they taught me. </p>
<p>That gratitude extended to my manager as well. Several weeks after being let go, I visited the office one last time to say goodbye to my team. My manager explained that the decision to let me go had been a difficult one. He told me he liked me as a person and recognized how much I had improved during the PIP. But keeping me on would have required certainty that I was already operating at the expected engineering level, and that was something he wasn’t sure of. I understood his position. If I had been in his shoes, I would have made the same decision.</p>
<p>Because of the Performance Improvement Plan I had gained growth, humility, and clarity. Letting go was about moving forward with gratitude for what had gone right.</p>
<h2 id="heading-whats-next">What’s Next</h2>
<p>The PIP had given me something invaluable: structure and accountability. During those eight weeks, I lived by a project plan timeline, and when my time at Google ended, I didn’t let that habit go. The very first thing I did afterward was set up a new timeline, this time for my job hunt. Tasks were ordered by priority, with time estimates and due dates, so that my search itself became a disciplined project. My wife, or anyone else, could hold me accountable just as my manager once had.</p>
<p>As an example, the below table is a snippet from my job hunt timeline:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Task</strong></td><td><strong>Time Remaining</strong></td><td><strong>Due Date</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Highly skilled at easy algorithms</td><td>2 days</td><td>Oct 20th, 2025</td></tr>
<tr>
<td>Medium skill at system design</td><td>4-6 days</td><td>Oct 24th, 2025</td></tr>
<tr>
<td>Talk to 3 local engineers and learn from them</td><td>12 hours weekly</td><td>-</td></tr>
</tbody>
</table>
</div><p>The key to creating my job hunting timeline was being clear on my priorities regarding what type of engineering position and what type of company I’d prefer to work for.</p>
<p>At Google, a company with tens of thousands of engineers, I used coding frameworks and technologies that were custom-built for Google engineers and used by no one outside of Google. I felt isolated from the greater world and to engineers outside of the company. So I want my next engineering role to be at a smaller company, where I’ll use popular open-source technologies and software used by engineers throughout the world.</p>
<p>To prepare myself for my next engineering role, I'm now laser-focused on upskilling my technical knowledge. I’ve been interviewing engineers at local startups about the technologies they use and then sharing the lessons publicly on LinkedIn. Each 1:1 interview and write-up helps close the skills gap that led to my firing at Google.</p>
<p>By following my written timeline and by knowing my end goal, I’ve been able to sustain long-term momentum in my job hunt.</p>
<h2 id="heading-closing">Closing</h2>
<p>Whatever will be will be. I’m grateful for the PIP experience, because it caused me to claw my way out of underperformance. It stripped away distractions, forced me to confront my engineering weaknesses head-on, and gave me the discipline to close the gap. </p>
<p>The momentum I built during those eight weeks never stopped. There was no break between week eight and week nine, just continuous acceleration. Week eight was about my PIP project, and week nine was about my job hunt. The external goals changed, but the internal engine kept running. </p>
<p>While my momentum softened the blow of getting fired, it didn’t erase the emotions that came with it. Sharing my story of being fired for underperformance has felt awkward and vulnerable, but also has given me a feeling of pride. Pride at who I’ve become. And pride in my giving back to the greater community, by enabling others facing similar struggles to learn from my story. </p>
<p>The eight weeks of the PIP were my launch ramp, and my acceleration continued long after the official PIP was over. To quote someone I know, “Like the mythical Phoenix, I believe in rising from the ashes, no matter how daunting the obstacle.”  The PIP was my ashes, but it was also my fire.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Configure Google Workspace Addon For Tier 2 CASA Security Assessment – Step by Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ As part of the Google CASA process, developers can run static analysis on their application’s source code using an inline integration with OpenText’s Fortify Source Code Analyzer (SCA) via the CASA portal. Naturally, I had to prepare my source code a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tier-casa-security-assessment/</link>
                <guid isPermaLink="false">66ba5b0dcccc49d721b6ea3a</guid>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google cloud ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nibesh Khadka ]]>
                </dc:creator>
                <pubDate>Fri, 23 Feb 2024 16:43:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/Addon-Assesment-Poster--4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As part of the <a target="_blank" href="https://appdefensealliance.dev/casa">Google CASA process</a>, developers can run static analysis on their application’s source code using an inline integration with OpenText’s Fortify Source Code Analyzer (SCA) via the CASA portal.</p>
<p>Naturally, I had to prepare my source code as per instruction. In this article, I will share how I packaged and submitted my Add-on's source code in Ubuntu OS. </p>
<p>But before that, let's talk a little about Tier 2 CASA assessment.</p>
<h2 id="heading-what-is-tier-2-casa-security-assessment">What is Tier 2 CASA Security Assessment?</h2>
<p>The <a target="_blank" href="https://appdefensealliance.dev/casa">Tier 2 CASA</a> (Cloud Application Security Assessment) is a self-service security assessment process for applicants seeking access to Google Workspace data or to comply with specific Google Workspace policies. </p>
<p>It allows developers to scan their applications and submit the results for verification without an external assessor accessing the code or infrastructure.</p>
<h3 id="heading-importance-tier-2-casa-security-assessment">Importance Tier 2 CASA security assessment</h3>
<p>Tier 2 CASA is important for several reasons:</p>
<ul>
<li><strong>Security Assurance:</strong> It provides independent verification of your application's security posture, reducing the risk of data breaches and protecting user privacy.</li>
<li><strong>Compliance:</strong> It helps meet security requirements for accessing Google Workspace data or adhering to Google policies, like the Workspace Marketplace Terms of Service.</li>
<li><strong>Efficiency:</strong> It's a faster and more cost-effective alternative to Tier 1 assessments, which involves external assessors directly examining your application.</li>
<li><strong>Trust</strong>: If your addon is published without verification it'll display an "unverified" message to the clients while installing the addon, which creates distrust and can lead to the installation process of your addon to be abandoned.</li>
</ul>
<p>In the context of my Google Workspace Addon <a target="_blank" href="https://appdefensealliance.dev/casa">Scan Me</a>, the use of <a target="_blank" href="https://developers.google.com/apps-script/add-ons/concepts/editor-scopes#restricted_scopes">restrictive</a> OAuth scope  <a target="_blank" href="https://developers.google.com/identity/protocols/oauth2/scopes#drive"><code>auth/drive</code></a> of Google Drive API likely triggered the need for a Tier 2 assessment. This scope grants your addon access to see, edit, create, and delete all of your Google Drive files, which falls under Google's security and privacy requirements.</p>
<h3 id="heading-additional-resources">Additional Resources</h3>
<ul>
<li><strong><a target="_blank" href="https://appdefensealliance.dev/casa/tier-2/getting-started">CASA Tier 2 Overview</a></strong></li>
<li><strong><a target="_blank" href="https://tacsecurity.com/google-casa-cloud-application-security-assessment/">CASA Documentation</a></strong></li>
<li><strong><a target="_blank" href="https://workspace.google.com/terms/marketplace/tos/">Google Workspace Marketplace Terms of Service</a></strong></li>
</ul>
<p><strong>Disclaimer</strong>: While I'll explain the Tier 2 CASA process<a target="_blank" href="https://workspace.google.com/marketplace/app/scan_me/613697866593">,</a> it's crucial to consult the official documentation and Google's security guidelines for specific requirements and guidance.</p>
<p>The assessment certification is free, by the way. To prepare your addon for the CASA assessment process follow the following steps.</p>
<h2 id="heading-step-1-sign-up-for-the-new-assessment-procedure"><strong>Step 1</strong> – <strong>Sign up for the new Assessment Procedure</strong></h2>
<p>If you're using restrictive scopes, you'll receive an email from Google's Verification team at some point requesting to verify the scopes after you've submitted your add-on for verification. </p>
<p>This email is the notification document. So, you need to download this email as a PDF, which must be submitted in the application form later on.</p>
<p>In that email, you'll find the following instructions for Tier 2 evaluation. You'll find a link to <a target="_blank" href="https://rc.products.pwc.com/login/casa/register">register</a> or <a target="_blank" href="https://rc.products.pwc.com/login/casa/">log-in</a> to the CASA portal. Click the link and register to the site. Then click on <strong>Start New Assessment&gt; Create New Assessment.</strong></p>
<p>Fill in the information asked carefully. Upload the previously downloaded email where you're asked for a Tier 2 notification pdf.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708599483954/704e9bf1-ac25-414d-b3f7-dcda721a82fd.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt="Image" width="1748" height="1240" loading="lazy">
<em>Starting New CASA Assesment of the Addon</em></p>
<p><strong>Note</strong>: For Google Workspace Addon, the type of application is <strong>Local App</strong>.</p>
<p><strong>Caution</strong>: As shown in the image above, even though "<strong>Project ID</strong>" is asked in the input field, they are asking for the <strong>Project Number</strong> included in the email, not the <strong>Project ID</strong> of your Google Cloud Console project.</p>
<p>After you carefully fill in the details and submit the form, you'll arrive at a new screen – <strong>Application Screening</strong> – where there are two things that you should download:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708599799176/52631f9a-8719-472e-997e-2169d1063127.png?auto=compress,format&amp;format=webp&amp;auto=compress,format&amp;format=webp" alt="Image" width="915" height="163" loading="lazy">
<em>Download Scan Cenral Package and Setup Insruction</em></p>
<ol>
<li>Fortify Scan Central Package.</li>
<li>Instruction on compressing your application's source code for initial assessment.</li>
</ol>
<h2 id="heading-step-2-download-and-setup-java-jdk"><strong>Step 2</strong> – <strong>Download and Setup Java JDK</strong></h2>
<p>To use the Scan Central package as mentioned in the instructions, a minimum of JDK 11 is required. </p>
<p>For setting up the path for the Java environment in Linux, I followed <a target="_blank" href="https://stackoverflow.com/a/73414921/6163929">this</a> instruction on StackOverflow.</p>
<h2 id="heading-step-3-setup-path-for-scan-central"><strong>Step 3</strong> – <strong>Setup Path for Scan Central</strong></h2>
<p>Now let's add the path to the Scan Central in our system.</p>
<p>In your CLI, open <code>.bashrc</code> file with <code>sudo nano ~/.bashrc</code>. Append the following path at the end of the file:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># SCAN Central </span>
<span class="hljs-comment"># Path looks like following</span>
<span class="hljs-comment">#/home/&lt;username&gt;/Fortify_ScanCentral_Client_22.2.1_x64/bin</span>

 <span class="hljs-built_in">export</span> PATH=<span class="hljs-variable">$PATH</span>:&lt;Path To bin folder <span class="hljs-keyword">in</span> Scan Central&gt;
</code></pre>
<p>Save (CTRL+S) and exit (CTRL + X) the file.</p>
<p>Open <code>.profile</code> with <code>sudo nano ~/.profile</code> and add the same path as above. You can check the version of Scan Central in your CLI with the command <code>scancentral -version</code>, to make sure the setup was successful.</p>
<h2 id="heading-step-4-packaging-source-code-for-assessment"><strong>Step 4</strong> – <strong>Packaging Source Code for</strong> A<strong>ssessment</strong></h2>
<p>To package the source code for your Google Workspace Addon, go to the root directory of your project. If you're following the instruction manual, go to the section for JavaScript code packaging.</p>
<p>In the root directory run any of the following commands:</p>
<pre><code class="lang-bash"><span class="hljs-comment">#cmd 1 </span>
scancentral package -bt none -o myPackage.zip
<span class="hljs-comment"># or cmd 2</span>
scancentral package -bt none --scan-node-modules -o myPackage.zip
</code></pre>
<p><strong>Note</strong>: The command <code>scancentral.bat</code> is for Windows users.</p>
<p>As mentioned in the instruction, command 2 increases the size of the package and is not necessary for Node.js or Angular. I created Workspace Addon so I don't have node-modules in my source code.</p>
<p>After that, you'll see a compressed package named <strong>myPackage</strong> in the directory where you ran the packaging operation.</p>
<h2 id="heading-step-5-initiate-the-scan-process"><strong>Step 5</strong> – <strong>Initiate the Scan Process</strong></h2>
<p>After packaging, go back to the CASA portal and click on your assessment ID link in the list, and open up the <strong>Application Screening</strong> window. Here:</p>
<ol>
<li>Click the <strong>Begin Scan Process</strong> button.</li>
<li>Upload the package you just compressed.</li>
<li>Click the <strong>Upload File &amp; Initiate Scan</strong> button.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/casa-form-filling--2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upload Source Code To Fortify Scan</em></p>
<p>This will initiate auto scanning of your application which is the beginning of assessment for your Addon.</p>
<p><strong>Reminder</strong>: As I've personally experienced, if your source code uses the <code>Math.random()</code> method, then the auto-scanner will not pass your code.</p>
<p>If you pass this phase, the manual verification process will begin where you'll have to fill in forms for the survey. Go to this <a target="_blank" href="https://lookerstudio.google.com/u/0/reporting/757d8fab-9682-4b74-9acc-58efb5e3081c/page/p_ana6axxq4c?s=tug3GYx0bmg">link</a> for the questions that'll be asked in the CASA survey. Here, choose the <strong>Local App</strong> option for App Type for a Google Workspace Add-on. I want to remind you that they will change based on the answer provided.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Alright, I'm hoping this blog helped you reduce the time and confusion that I had to encounter when I was trying to assess my <a target="_blank" href="https://workspace.google.com/marketplace/app/scan_me/613697866593">addon</a>. And please don't give up midway during the evaluation otherwise your months of hard work will be in vain.</p>
<p>My addon <a target="_blank" href="https://workspace.google.com/marketplace/app/scan_me/613697866593">Scan Me</a>, scans the Google Drive and prepares an audit report in a spreadsheet file of your choosing in your Google Drive. It makes it extremely easy for you to analyze your Google Drive from one place, and it also offers a free quota. If you're looking for a similar addon I hope you'll try this addon. </p>
<p>This is Nibesh khadka, have a good day.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ ChatGPT vs BARD AI – What's the Difference? ]]>
                </title>
                <description>
                    <![CDATA[ In November of 2022, Artificial Intelligence took center stage in the tech world. AI was not a new concept, but OpenAI had just released its ChatGPT Large Language Model, and devs started diving into using it.  Large Language Models, or LLMs, let use... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/chatgpt-vs-bard/</link>
                <guid isPermaLink="false">66c71fd3e39cd88fc3e1cce4</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ chatgpt ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ LLM&#39;s  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mabel Obadoni ]]>
                </dc:creator>
                <pubDate>Thu, 16 Nov 2023 17:19:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/gpt.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In November of 2022, Artificial Intelligence took center stage in the tech world. AI was not a new concept, but OpenAI had just released its ChatGPT Large Language Model, and devs started diving into using it. </p>
<p>Large Language Models, or LLMs, let users enter a prompt (some question or set of instructions) and then the LLM generates a response. People in tech are using them for everything from creating code examples to generating graphs and charts and beyond.</p>
<p>Sounds useful, right? Well, I'm sure you've heard talk about AI taking over a whole bunch of jobs. And as developers and content creators, we want to carry out our roles without worrying about some AI stepping in.</p>
<p>After all, robots are now being used in some parts of the world as waiters, and executive assistants are also being replaced by digital virtual assistants. And of course creatives such as technical writers are not left out.</p>
<p>So we need to learn how to use and take advantage of these new tools. In this way, they can help us, not push us out.</p>
<p>Even though technology is racing down the fast lane, there are many ways for you to stay relevant. In this article, I'll talk about two of the major players in the AI/LLM space – ChatGPT and Bard AI – and explain how you can use them to your benefit.</p>
<p>Here's what we'll cover:</p>
<ul>
<li>How AI works</li>
<li>AI tools and their applications</li>
<li>The major AI tools used in writing</li>
<li>Google Bard vs ChatGPT</li>
</ul>
<h2 id="heading-how-ai-works-an-overview">How AI Works – An Overview</h2>
<p>Before we dive into the tools themselves, we should understand briefly how Artificial intelligence works at a high level.</p>
<p>Artificial Intelligence is the technology that allows computers (or machines generally) to "think" and behave independently of human input. </p>
<p>Although there are some fundamental concepts and frameworks behind it such as data science and machine learning, artificial intelligence is now being used throughout various fields, both technical and not traditionally technical.  </p>
<p>The AI works by being fed data so that it can train ("learn") and produce some output based on its training. So the output depends on the data it learns on, to a large extent. </p>
<p>This is true for LLMs as well as other types of AI models – if you don't ask the LLM the right question or feed it the right prompt, you won't get the output you desire.</p>
<p>For example, if I want to generate a professional summary for a Web Developer Role and I accidentally request one for a Graphic Designer instead, it will generate the professional summary based on the role of a Graphics Designer. So you'll need to <a target="_blank" href="https://www.freecodecamp.org/news/learn-prompt-engineering-full-course/">learn how to ask the LLM the right questions</a>.</p>
<p>As long as you feed the AI the right data, it can do all sorts of things – from photo generation to content idea generation to helping you create useful code examples for your technical tutorials. So in fact, AI can help Creatives, Software Developers, and many others be more productive and save time so they can focus on the truly important problems.</p>
<p>Here's something to remember, though: as a writer, irrespective of your genre, you should not rely solely on AI to do the writing for you. While AI is helpful in generating outlines and ideas, it doesn't have your background knowledge, it might not understand the context or your audience, and sometimes its writing just won't be as good as yours. </p>
<p>So embrace your skills and your authenticity, and use AI as an enhancer to help you write better.</p>
<p>A you read this guide, note that my intention is to show you how you can use the AI tools listed here to do your work more effectively. You should not use these tools or technologies for any nefarious or dishonest purposes.</p>
<h2 id="heading-ai-tools-and-their-applications">AI Tools and Their Applications</h2>
<p>Almost everyone uses AI in some form these days, even without realizing it. Irrespective of your career field, there’s likely some AI software to help ease your workload. </p>
<p>Although there are different classes of AIs based on their learning methods, this article won't bore you with too many technical terms. So I'll just briefly go over the different types of AI software that can help make your tasks easier and faster. </p>
<p>Below is a table showing some popular AI applications and their use cases:</p>
<table><colgroup><col><col><col></colgroup><tbody><tr><td><p><span>S/n</span></p></td><td><p><span>AI Software</span></p></td><td><p><span>Function</span></p></td></tr><tr><td><p><span>1.</span></p></td><td><p><span>Remini</span></p></td><td><p><span>Used to generate photo-studio like images</span></p></td></tr><tr><td><p><span>2.</span></p></td><td><p><span>ChatGPT, Bard</span></p></td><td><p><span>These applications are the most commonly used in writing and for creating content like CVs, articles, profile summaries, code snippets, and more</span></p></td></tr><tr><td><p><span>3</span></p></td><td><p><span>Google Assistant, Alexa, Siri</span></p></td><td><p><span>These are voice assistants that share information and help you perform tasks by voice input. They're more like your virtual assistant</span></p></td></tr></tbody></table>

<p>These applications are grouped based on the functions they perform, even though they're built by different companies.</p>
<h2 id="heading-ai-tools-for-writing">AI Tools for Writing</h2>
<p>With the advent of writing assistants such as OpenAI’s ChatGPT and Google’s Bard, some people have begun to wonder – will writers start losing their jobs? But as one of my connections said on LinkedIn recently, tech is an enabler, and so is AI. </p>
<p>Some writers have started using these AI tools to generate topic ideas and help them improve their skills, as we briefly discussed above. But other writers are using AI tools to entirely write content for them. </p>
<p>This is not a good idea for many reasons – not least of which being that the AI could be plain wrong. It also won't have your finesse, your awareness of context and other subtleties, and it may sound stiff and overly formal. Plus, it'll take away a lot of the benefit you get as a writer and developer from researching and writing your own articles.</p>
<p>Just always remember that moderation is key and human intelligence will always still stand out. So learn and use these tools, but don't overly rely on them to do your job for you...or they might end up doing just that in the long run.</p>
<p>Let’s take a look at two of the major generative AIs used by writers and developers: ChatGPT and Google’s Bard.</p>
<h3 id="heading-what-is-chatgpt">What is ChatGPT?</h3>
<p><img src="https://lh7-us.googleusercontent.com/pi9BEsLN7vnHcxh3OwDIE-ZtoNb8PJmgwz3wra5cG-95ijSU6r2IPEZvAveBZqB65EqA7a2Y4DdSe8LUAjL3p51b06f_bEVH6JrwQQL_eMuigAX7Igpwsg8AAeDK9d97TeisdAATySCezeDWJqC4HSA" alt="Image" width="800" height="533" loading="lazy"></p>
<p>In November 2022, OpenAI alongside Microsoft launched a Large Language Model (LLM) that could generate responses based on the user’s input (questions), whether that input was text or code. </p>
<p>This model that is based on a text generative pre-trained model known as ChatGPT. Prior to this model of chatbot, there had been several chatbots such as the instant responder you find on websites and also different virtual help desks used by Fintechs. </p>
<p>From generating a résumé to generating software code in different programming languages, ChatGPT became the “darling” everyone sought to know.</p>
<h3 id="heading-how-does-chatgpt-work">How does ChatGPT work?</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-54.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The ChatGPT takes in your instructions, also referred to as prompts. These instructions are then used to generate a result relative to your prompt. </p>
<p>The more prompts the LLM receives, the better it gets at learning. This implies that the model is trained based on the user's input. </p>
<p>Example of a prompt:</p>
<p>In 5 sentences, explain how AI works</p>
<p>Output from ChatGPT</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screen-Shot-2023-11-16-at-1.12.20-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You should also bear in mind that your prompt should be well constructed and clear, otherwise the generated result might what you want (or might not be that helpful). </p>
<blockquote>
<p>Note that I used the free version of ChatGPT for this article. More features are available on the premium version.</p>
</blockquote>
<p>You can use ChatGPT in many different ways depending on your needs. Here are some examples of ways you can use it.</p>
<ul>
<li>ChatGPT can help you debug your code. You can enter a prompt requesting a code snippet or example for a certain task, and the LLM will generate it for you. This is not to say that you can depend solely on ChatGPT to build or debug your projects. Just like enzymes that speed up reactions, ChatGPT helps you debug codes faster by pointing you in the direction you should go.</li>
<li>Also, the Assistant API from ChatGPT can be consumed to build an instant messaging AI in your project. Although still in the beta stage, the Assistant API can help Software Developers build mini-ChatGPTs in their individual projects. That way, your users can ask questions and get responses based on the underlying LLM's abilities and knowledge.</li>
<li>Writers often complain about idea generation and writers' block. One way ChatGPT can work for you as a Technical Writer is to help you generate content ideas. It just depends, as always, on the prompt you enter.</li>
<li>It can also help you start writing about your ideas. Some writers have issues getting down that first sentence or making an outline for a draft. With ChatGPT, you can perform these tasks more quickly and use the LLMs ideas as jumping off points. </li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screen-Shot-2023-11-16-at-1.27.49-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Again, this is not to encourage you to depend solely on AI for content generation, as the human touch still stands out. But it can certainly help you get started.</p>
<p>While ChatGPT can help you in many ways, the earlier models (like GPT-3) also had their downsides. But now, the latest model of GPT-4 has many improvements, including being able to use plugins to get more current information. But you may need to pay for premium usage in some cases.</p>
<p>There are other ways you can use ChatGPT, and you can read more <a target="_blank" href="https://platform.openai.com/docs/introduction">here</a> to find out.</p>
<h3 id="heading-googles-bard-ai"><strong>Google's BARD AI</strong></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-52.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Google's BARD is the newest LLM kid on the block.</p>
<p>As expected, in the first quarter of 2023, Google released its own language based-model chatbot called Bard AI. Although still in the Beta stage (as at the time of this article), Google Bard AI is gradually catching the attention of the tech community.</p>
<h3 id="heading-how-does-bard-work">How does Bard work?</h3>
<p>Like other LLMs, Bard accepts prompts and generates results in response to the prompt. Bard is built on Google's <a target="_blank" href="https://blog.google/technology/ai/lamda/">LaMDA</a> (Language Model for Dialogue Applications), which generates finely-tuned responses and improves specificity. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screen-Shot-2023-11-16-at-2.22.11-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot showing Bard responding to a prompt</em></p>
<p>Bard can perform various operations such as:</p>
<ul>
<li>Review software development code errors and suggest solutions. Just remember that AI shouldn't be used as the ultimate error finder or solver for your code reviews. The LLM may not understand the entire architecture of your program based on the piece of code you feed it via the prompt.</li>
<li>Bard prides itself on its specific and fine-tuned responses, which of course are quite helpful in Technical Writing. Bard tries as much possible to keep prompt responses concise and authentic. In cases where it sources from any external web-page, the URL is referenced.</li>
</ul>
<h2 id="heading-chatgpt-vs-bard-ai"><strong>ChatGPT vs BARD AI</strong></h2>
<p>Both of these tools can be helpful to you as a dev or technical writer – it just depends on how you use them and what your needs are.</p>
<p>If you'd like to see them compared directly, here's a live demo of both ChatGPT and Google Bard:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/t3LglzQwSHo" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Note: The information provided here is based on what was available at the time, and may not reflect the most up-to-date details about ChatGPT and BARD AI.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Technologies can help enhance our capabilities as human beings. And Artificial Intelligence tools should be no different. You can use them to help you perform basic tasks or build creative solutions. This is why you should get acquainted with how they work and try them out in your projects.</p>
<p>Whether it is ChatGPT or Google’s Bard AI, the goal remains achieving efficiency and genuine results in the simplest way possible.  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Intro to Generative AI – 10 Free Courses by Google ]]>
                </title>
                <description>
                    <![CDATA[ Are you tired of all the AI talk yet? I am too, but I'm also intrigued by the technology behind it. If you'd like to dive into some of the details behind how AI actually works and take a break from the many creepy AI examples on the internet, check ]]>
                </description>
                <link>https://www.freecodecamp.org/news/intro-to-generative-ai-10-free-courses-by-google/</link>
                <guid isPermaLink="false">66b8de0cf805ffd579552e99</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ online courses ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Thu, 22 Jun 2023 22:22:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/gen-AI.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you tired of all the AI talk yet?</p>
<p>I am too, but I'm also intrigued by the technology behind it.</p>
<p>If you'd like to dive into some of the details behind how AI actually works and take a break from the many creepy AI examples on the internet, check this out:</p>
<p>Google has released a free set of training courses for generative AI. <a target="_blank" href="https://cloud.google.com/blog/topics/training-certifications/new-google-cloud-generative-ai-training-resources">Here's their announcement post</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/cloudify-your-skills.png" alt="Image" width="600" height="400" loading="lazy">
<em>Picture for generative AI courses</em></p>
<h3 id="heading-video-walkthrough">Video Walkthrough</h3>
<p>I've made a short video of the coursework if you'd prefer a visual walkthrough of my first impressions:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/OgE0DSSWk2M" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-overview">Overview</h2>
<p>There are 10 courses in this free learning path. Many are aimed at beginners with no prerequisite knowledge. Some suggest a background in Python, SQL, and/or machine learning. All of them deliver content through a combination of videos, articles, labs and quizzes.</p>
<p>There are badges to show that you've completed them, and I'm happy to see a freely available set of courses around the technology behind AI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/badge.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google course badge</em></p>
<p>The amount of content produced by and highlighting AI is overwhelming right now, but it's a safe bet that this is going to stick around. As such, it's best to arm yourselves with as much information about it as you can so that you can responsibly create tools and content for the future.</p>
<h2 id="heading-courses-material">Courses Material</h2>
<p>I've created a Google Sheet with all the course info pulled from each of these courses. <a target="_blank" href="https://docs.google.com/spreadsheets/d/1lHvmTj7SEZU_6vMg7E8yDpBctYdlEYNxc5fJtZzlwCc/edit#gid=0">Check it out here</a>. Google has done a fine job of creating a brief FAQ for each of the courses, and I've pulled them all into one sheet for easy comparison.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/google-sheet-summary.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google Sheet summary of all courses</em></p>
<p>Inside each course, you'll be presented with a straightforward navigation for the content. It's broken into video instruction, a curated collection of readings to peruse, and quizzes. Some courses also have online labs to complete in a certain amount of time.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/create-image-capturing-models.png" alt="Image" width="600" height="400" loading="lazy">
<em>Video content for the Create Image Captioning Models course</em></p>
<p>The curated list of readings is quite comprehensive, and you could easily exceed the estimated 45 minutes of time to complete the modules if you read through every one. But it is nice to have such a large list of resources compiled in one place.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/llms.png" alt="Image" width="600" height="400" loading="lazy">
<em>The list of readings for the Intro to Large Language Models course</em></p>
<p>There are also Labs hosted in some of the courses. If you've taken any of Google's Coursera courses, you'll be familiar with this delivery method. You're given a handful of tasks and a countdown timer, in this case 1hr, will begin when you start the lab.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/lab-work.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of lab work</em></p>
<p>Here is the full list of courses:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/intro-screenshot.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/536">Introduction to Generative AI</a> – designed to be an overview of what generative AI is and how it differs from machine learning methods. </li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3634938/video/379143">Introduction to Large Language Models</a> – explores what large language models are, where they are used, and how to use prompt tuning. (If you haven't noticed, prompt writing is being touted as a skill of the future right now.)</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/554">Introduction to Responsible AI</a> – an ethical course on what responsible AI is, how it's implemented in Google products, and why it's important. This course introduces Google's 7 AI Principles. I didn't know this was a thing, but there's a <a target="_blank" href="https://ai.google/responsibility/principles/">whole page</a> devoted to it. Covering topics from social responsibility, to safety, accountability and privacy design principles, I was happy to see that there is large effort being paid to build in solid principles.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3652912/quizzes/381263">Generative AI Fundamentals</a> – A quiz covering topics from the first three courses.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/541">Introduction to Image Generation</a> – An introduction to diffusion models which are a family of models used in image generation. Some pre-existing knowledge of machine learning, deep learning, convolutional neural nets and/or Python programming is suggested.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/543">Encoder-Decoder Architecture</a> – overview of a machine learning architecture for tasks like machine translation, text summarization, and question answering. Python and Tensorflow knowledge is suggested as a prerequisite.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/537">Attention Mechanism</a> – a technique that allows neural networks to focus on specific parts of an input sequence. Some pre-existing knowledge of machine learning, deep learning, natural language processing, and/or Python programming is suggested.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3635001/video/377866">Transformer Models and BERT Model</a> – Bidirectional Encoder Representations from Transformers...this is what BERT stands for in case you didn't know. You'll learn the main components of the Transformer architecture and intermediate machine learning experience as well, and knowledge of Python and TensorFlow are recommended.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_sessions/3652936/video/379207">Create Image Captioning Models</a> – how to create an image captioning model using deep learning. Deep learning, machine learning, natural language processing, computer vision and Python are recommended prerequisites.</li>
<li><a target="_blank" href="https://www.cloudskillsboost.google/course_templates/552">Introduction to Generative AI Studio</a> – you'll walk through demos of the Generative AI Studio which helps prototype and customize generative AI models. There is a hands-on lab at the end.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/generative-ai-studios-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-my-thoughts">My Thoughts</h2>
<p>After spending some time browsing through all of these courses, it's a nice mix of truly beginner-friendly content and some intermediate level stuff that requires previous knowledge of machine learning, Python, deep learning, and/or natural language processing.</p>
<p>I appreciate how there are answers to many common questions in the drop down menus for each course (and I've compiled all of those in one place in this <a target="_blank" href="https://docs.google.com/spreadsheets/d/1lHvmTj7SEZU_6vMg7E8yDpBctYdlEYNxc5fJtZzlwCc/edit#gid=0">Google Sheet</a>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/google-cloud-screenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Google Cloud certifications</em></p>
<p>This is a great starting point if you are truly interested in the inner-workings of AI. It also looks to be a potential on-ramp to some of <a target="_blank" href="https://cloud.google.com/learn/certification#why-get-google-cloud-certified">Google Cloud's larger certifications</a> as there are links to further training sprinkled in the courses.</p>
<p>What do you think?</p>
<p>👋My name is <a target="_blank" href="https://www.linkedin.com/post/edit/7077633795897622528/?author=urn%3Ali%3Afs_miniProfile%3AACoAAAirLdUBMHodHKOoTMZvUxoRedTeclnkxfw#">Eamonn Cottrell</a>, and I'm building content around Google Sheets &amp; Workspace. </p>
<p>Get my 📨 <a target="_blank" href="https://got-sheet.beehiiv.com/subscribe">newsletter here</a>. Find me on 📺 <a target="_blank" href="https://www.youtube.com/@eamonncottrell">YouTube here</a>.</p>
<p>Please ask questions in the comments, or send me a message; I love making new spreadsheet connections!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google's New Cybersecurity Professional Certificate Explained ]]>
                </title>
                <description>
                    <![CDATA[ Google has released a new professional certificate in Cybersecurity. The announcement came on May 4th, 2023 and marks the 6th topical branch in their continually expanding certificate program. It follows five other successful entry-level certificate ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cybersecurity-professional-certificate-by-google/</link>
                <guid isPermaLink="false">66b8ddd4f805ffd579552e97</guid>
                
                    <category>
                        <![CDATA[ Certification ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Mon, 08 May 2023 21:38:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/Cybersecurity-CertificateFCC.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google has released a new professional certificate in Cybersecurity. The <a target="_blank" href="https://blog.google/outreach-initiatives/grow-with-google/google-cybersecurity-career-certificate/">announcement</a> came on May 4th, 2023 and marks the 6th topical branch in their continually expanding certificate program.</p>
<p>It follows five other successful entry-level certificate programs in IT Support, Data Analytics, Digital Marketing &amp; E-commerce, Project Management and UX Design.</p>
<p>I made a first impressions video to accompany this article that you can find here:(more links in the summary at the bottom of the article, too)</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Q2w6fEFfWyQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-grow-with-google">What is "Grow with Google"?</h2>
<p>The Grow with Google program is for people interested in "training, tools and resources to grow skills, careers, or businesses". You can find all the certificate programs and resources <a target="_blank" href="https://grow.google/">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/grow-with-google-site.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Grow with Google website</em></p>
<p>Grow with Google's mission is to enable anyone to have access to quality technology training. They've been training digital skills since 2017, and currently partner with Coursera for course delivery.</p>
<p>Coursera's been in the MOOC (Massive Open Online Course) space since 2012, and has grown to be a leader in the online education world.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/faqs.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of FAQ from Grow With Google</em></p>
<p>Though Google has released a few Advanced level courses recently (<a target="_blank" href="https://www.freecodecamp.org/news/starting-and-excelling-in-data-analytics/">I wrote about this here</a>) in the Data Analytics, Business Intelligence and IT Automation tracts, the new Cybersecurity certificate has been designed with beginners in mind.</p>
<p>There is no experience necessary to begin. The structure of the certificate program starts in a foundational introductory module, works through some technical topics like SQL, Linux, and Python, and then culminates with a module on preparing for Cybersecurity Jobs.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/no-experience-required.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-get-job-ready">Get Job Ready</h2>
<p>This is also part of Google's Grow With Me pathways: they are partnering with businesses and universities to pair together jobs and program graduates.</p>
<p>The initial job platform was deprecated as of February 7th, 2023, but the new one for this year is maintained on <a target="_blank" href="https://www.careercircle.com/">CareerCircle</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/career-circle-screenshot.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of CareerCircle</em></p>
<p>This is a strong draw to participants, especially as the entry-level salaries for many of the fields approach and exceed six figures. Cybersecurity has a $100K+ amount listed in the marketing material.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/cybersecurity-median-entry-salaries.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Cybersecurity marketing material for median entry salaries</em></p>
<p>Naturally, these amounts are easily skewed and may not be realistic depending on the applicant's background. But it's no secret that on the whole, these technical jobs do lead to higher paying salaries.</p>
<h2 id="heading-whats-the-coursework-like">What's the Coursework Like?</h2>
<p>I took a look through the 8 courses that make up the Cybersecurity certificate, and found it to be a similar makeup to the first Data Analytics certificate that I completed a couple years ago.</p>
<p>It begins with some basic overviewing of the field, and then moves into an assortment of high level concepts and technical skill building. Here is the full list:</p>
<ul>
<li>Foundations of Cybersecurity</li>
<li>Play it Safe: Manage Security Risks</li>
<li>Connect and Protect: Networks and Network Security</li>
<li>Tools of the Trade: Linux and SQL</li>
<li>Assets, Threats, and Vulnerabilities</li>
<li>Sound the Alarm: Detection and Response</li>
<li>Automate Cybersecurity Tasks with Python</li>
<li>Put it to Work: Prepare for Cybersecurity Jobs</li>
</ul>
<p>As you can see from some of the titles, Google does get a little general in their topics, which is to be expected in an introductory course.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/cybersecurity-professional-coursework.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Cybersecurity Professional Certificate coursework</em></p>
<p>They have also been long-winded in the video courses in my experience, and I recommend increasing the video playback speed to 1.5x or 2.0x normal speed. I found I had little difficulty in keeping up with the presenters when I did this in other courses.</p>
<h2 id="heading-more-course-details-and">More Course Details and $$$</h2>
<p>Coursera would like you to pay $49 a month for this certificate program, and that's perfectly reasonable. Especially since Google estimates you can complete it in 6 months by working only 7 hours a week</p>
<p>...and I estimate you can complete it in a max of 3 months working 7-10 hours a week. 😀</p>
<p>But, if you're strapped for cash, you can click into any one of the individual courses and <strong>audit the whole thing for FREE</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/corsera-course-audit.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of Coursera course audit</em></p>
<p>You won't get the certificate, or access to the CareerCircle network, but if you're just leveling up your knowledge, you can do that for free.</p>
<p>You can also see each module's details within each of the courses. This detailed view breaks down each lesson to exactly what topics will be covered and how much time will be spent on each video, reading, or quiz.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/module-details.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is a great place to look in case you're not starting from zero and wonder if it will be repeating information you already know. I found that many of the items were very beginner-based (as they stated), especially in the Python course.</p>
<h2 id="heading-summary-links-and-video">Summary, Links, and Video</h2>
<p>This looks to be another solid offering from Google into a field that promises to be intriguing to many people.</p>
<p>If you're interested in Cybersecurity and have been wondering where to start, I believe this is as good an entry point as any.</p>
<ul>
<li>Check out my first impressions video <a target="_blank" href="https://youtu.be/Q2w6fEFfWyQ">here</a>.    </li>
<li>Check out the Coursera page <a target="_blank" href="https://www.coursera.org/professional-certificates/google-cybersecurity">here</a>.</li>
<li>Check out Google's Cybersecurity program overview page <a target="_blank" href="https://grow.google/certificates/cybersecurity/#?modal_active=none">here</a>.</li>
</ul>
<p>Have a great one!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Data Analytics with New Advanced Certifications from Google ]]>
                </title>
                <description>
                    <![CDATA[ Google has been growing a list of certifications for the past few years. And they've just added some advanced coursework to the repertoire.  In this article, I'll introduce you to the Google Certifications and detail what's new. I'll focus on the Dat... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/starting-and-excelling-in-data-analytics/</link>
                <guid isPermaLink="false">66b8de24abe19f6180038a35</guid>
                
                    <category>
                        <![CDATA[ data analysis ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analytics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Fri, 07 Apr 2023 20:47:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/Data-Analytics-Advanced-Certifications.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Google has been growing a list of certifications for the past few years. And they've just added some advanced coursework to the repertoire. </p>
<p>In this article, I'll introduce you to the Google Certifications and detail what's new. I'll focus on the Data Analytics pathway, but will include resources to their other programs.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/learn.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-video-walkthrough">Video Walkthrough</h2>
<p>Here's a video walkthrough of what we'll discuss below.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/dogpnO3IU_8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-grow-with-google-overview">Grow With Google Overview</h2>
<p>Career Certifications from Google are a part of their "Grow with Google" initiative. A portion of their <a target="_blank" href="https://grow.google/our-mission/">mission page</a> is in the picture below 👇. </p>
<p>Grow with Google is an assortment of training and learning resources for small business owners, job seekers, veterans, educators, developers and startups to learn vital digital skills.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-42.png" alt="Image" width="600" height="400" loading="lazy">
<em>From Grow with Google's mission: https://grow.google/our-mission/</em></p>
<p>Part of Grow with Google are the <a target="_blank" href="https://grow.google/certificates/#?modal_active=none">Career Certificates pathways</a> which offer flexible online training programs in <a target="_blank" href="https://grow.google/certificates/digital-marketing-ecommerce/#?modal_active=none">Digital Marketing &amp; E-commerce</a>, <a target="_blank" href="https://grow.google/certificates/it-support/#?modal_active=none">IT Support</a>, <a target="_blank" href="https://grow.google/certificates/data-analytics/#?modal_active=none">Data Analytics</a>, <a target="_blank" href="https://grow.google/certificates/project-management/#?modal_active=none">Project Management</a>, and <a target="_blank" href="https://grow.google/certificates/ux-design/#?modal_active=none">UX Design</a>.👇</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-47.png" alt="Image" width="600" height="400" loading="lazy">
<em>picture of Grow with Google's Career Certificates page</em></p>
<p>The proposition is attractive: no experience necessary to begin the programs, learn at your own pace, have a well-regarded certification from Google at the end of it and be qualified for a new entry-level job in careers with a median salary of $72,000 across the certificate fields. </p>
<p>The median salaries range from $57,000 for <a target="_blank" href="https://grow.google/certificates/it-support/#?modal_active=none">IT Support</a> to $112,000 for <a target="_blank" href="https://grow.google/certificates/ux-design/#?modal_active=none">UX Design</a>.</p>
<p>The entire certificate program is a partnership between Google, who has crafted the courses, and Coursera, which is one of the OG MOOCS that hosts the coursework. </p>
<p>This of course begs the question: how much does it cost? 🤔</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/howmuch.gif" alt="Image" width="600" height="400" loading="lazy">
<em>gif of man saying, how much money?</em></p>
<p>The good news is that you can nab the knowledge for free. And if you fork over a little bit, you can have the official certificate to display proudly on that portion of your LinkedIn page rarely ever scrolled to. 😀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-58.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of my LinkedIn licenses &amp; certifications</em></p>
<h3 id="heading-the-free-version">The Free Version:</h3>
<p>Yes, the knowledge is free. You can audit any of these courses at Coursera for free. So, while there's not an option to audit the whole certificate, you can click into the individual courses and audit them one by one.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/audit.png" alt="Image" width="600" height="400" loading="lazy">
<em>picture of audit option in coursera courser</em></p>
<p> I've clicked into the Foundations of Data Science course and selected audit. In the screenshot below, you can see that I now have access to all the coursework.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-62.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Foundations of Data Science coursework on coursera</em></p>
<p>What don't you get with the free version?</p>
<p>Well, you don't get that nice certificate "proving" you did the work. But if you've got the knowledge, you can muster together projects that will do a better job of proving that anyway. </p>
<p>And you also may not be able to turn in certain assignments for grades, depending on the course.</p>
<h3 id="heading-the-not-free-version">The Not Free Version:</h3>
<p>Coursera costs $39 a month for any of the individual Google certificates, including the new advanced ones. And since it's at your own pace, if you work fast, you can finish in one, two, or three months instead of the projected six...saving you some $$$. 💵💰</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-59.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of Coursera's individual course pricing</em></p>
<p>As is now common, Coursera also offers a more expensive Plus program for $59 a month or $399 a year. This gives unlimited access to courses and could be a better deal if you plan on plowing through many courses during a year.</p>
<p>But, you'd have to be flying through them for this to be valuable considering you could by 10 individual courses for $390.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-60.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of coursera plus costs</em></p>
<p>My opinion: if you're strapped for cash, start knocking out the free audit versions. But, it's pretty cheap to grab a certificate if that's important to you. Particularly if you work hard and fast 👉 it could cost as little as one month's $39 fee.</p>
<h2 id="heading-my-experience-with-the-data-analytics-cert">My Experience with the Data Analytics Cert</h2>
<p>I took the Data Analytics Certification a while back, and can attest that it was a fantastic overview of the field. I'd been using Excel heavily before taking the course, and was familiar with programming and database concepts, so I was able to move at a brisk pace.</p>
<p>I spent 2-3 months working through the "6 month" course, and certainly could have gone faster. Six months is conservative, even for a novice, in my opinion.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-57.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of my data analytics certificate</em></p>
<p>This certificate took some flak because it used R instead of Python for the programming portion. But I thought it was well laid out and offered a good introduction to data analytics.</p>
<p>Would it make someone hirable? </p>
<p>Well, it's just one piece in that puzzle. Relying on any of these certifications alone to land a job is perhaps unwise. It will take a combination of the skills learned, the networking you're willing to do, and your continued work through projects to prove your skills and land a job.</p>
<p>On the whole, I recommend it, especially if you're new to Excel, SQL, or programming.</p>
<p>And if you're wondering, yes, I ponied up the cash and enrolled in the program. It took me a little over two months and so I paid $117 +tax.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-63.png" alt="Image" width="600" height="400" loading="lazy">
<em>My payment history for Data Analytics coursework</em></p>
<h2 id="heading-advanced-certificates">Advanced Certificates</h2>
<p>My foray into the data analytics was one of curiosity more than anything. I was not actively seeking new employment – I simply wanted to sharpen and expand my skills. And that's exactly what piqued my interest in the new, advanced certificates that are now available.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/advanced.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of banner advertising new advanced Certificates</em></p>
<p>In addition to Industry Specializations (<a target="_blank" href="https://blog.google/outreach-initiatives/grow-with-google/industry-specializations/">added in October 2022</a>), there are now three advanced certificates (<a target="_blank" href="https://blog.google/outreach-initiatives/grow-with-google/advanced-google-data-analytics-career-certificates/">as of April 2023</a>) with more likely in the future: <a target="_blank" href="https://grow.google/certificates/data-analytics/?advanced#?modal_active=none">Advanced Data Analytics</a>, <a target="_blank" href="https://grow.google/certificates/data-analytics/?advanced#?modal_active=none">Business Intelligence</a>, and <a target="_blank" href="https://grow.google/certificates/it-support/?advanced#?modal_active=none">IT Automation with Python</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-64.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of advanced certificate listings from Grow with Google</em></p>
<p>According to Google's announcement post, the Data Analytics Certificate program was the most popular professional certificate on Coursera, so it's unsurprising that this field has received the first advanced follow-up courses. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/popular-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Excerpt from announcement post</em></p>
<p>And the field is well paid, making it an attractive aspiration for career transitioners and students alike.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-65.png" alt="Image" width="600" height="400" loading="lazy">
_pic of advanced data analytics certificate details from https://grow.google/certificates/data-analytics/?advanced#?modal<em>active=none</em></p>
<p>Of particular note, Google has wisely opted to go with Python and Jupyter Notebook (industry standard tools) as detailed in the above card for the Advanced Data Analytics Certificate.</p>
<p>Below, you can see similar details for the Business Intelligence Certificate which focuses more heavily on modeling, dashboards, and engaging with stakeholders via SQL, Tableau, and BigQuery.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-67.png" alt="Image" width="600" height="400" loading="lazy">
_pic of details from business intelligence certificate from https://grow.google/certificates/data-analytics/?advanced#?modal<em>active=none</em></p>
<p>I'm excited to try out both courses and see how deep they go after the introductory, pretty surface level course. And right now, it has that same fresh, new, adventurous feel as when a new WoW server launches 🧙‍♂️. Only 3 enrolled in the Data Analytics Advanced degree!😲😅</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/start.png" alt="Image" width="600" height="400" loading="lazy">
<em>pic of advanced data analytics certificate page on Coursera</em></p>
<p>And there are only 4 in the Business Intelligence program! This is sure to change quickly, and indeed, there are a few hundred in the individual courses already. Looks like many will indeed opt to audit the courses before jumping into the paid program.</p>
<h2 id="heading-coursework-overview">Coursework Overview</h2>
<p>Here are the respective courses in the two new advanced certificates. I encourage you to go check them out yourselves for further details, or watch my <a target="_blank" href="https://youtu.be/dogpnO3IU_8">video walkthrough</a>, but this will give you an idea of what to expect.</p>
<h3 id="heading-data-analytics-courses">Data Analytics Courses</h3>
<p><a target="_blank" href="https://www.coursera.org/google-certificates/advanced-data-analytics-certificate?utm_source=google&amp;utm_medium=institutions&amp;utm_campaign=gwgsite">Go here</a> to check out the overview of each data analytics course.</p>
<p>Click into each course below to explore in more detail and see all the modules within each course. This program is estimated by Google to take six months to complete.</p>
<ol>
<li><a target="_blank" href="https://www.coursera.org/learn/foundations-of-data-science?specialization=advanced-data-analytics-certificate">Foundations of Data Science</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/get-started-with-python?specialization=advanced-data-analytics-certificate">Get Started with Python</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/go-beyond-the-numbers-translate-data-into-insight?specialization=advanced-data-analytics-certificate">Go Beyond the Numbers: Translate Data into Insights</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/the-power-of-statistics?specialization=advanced-data-analytics-certificate">The Power of Statistics</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/regression-analysis-simplify-complex-data-relationships?specialization=advanced-data-analytics-certificate">Regression Analysis: Simplify Complex Data Relationships</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/the-nuts-and-bolts-of-machine-learning?specialization=advanced-data-analytics-certificate">The Nuts and Bolts of Machine Learning</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/google-advanced-data-analytics-capstone?specialization=advanced-data-analytics-certificate">Google Advanced Data Analytics Capstone</a></li>
</ol>
<p>You can see from the screenshot below the estimated hours to complete each module as well as the higher $118,000 median salary for entry-level roles:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-68.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of coursework for Advanced Data Analytics</em></p>
<h3 id="heading-business-intelligence-courses">Business Intelligence Courses</h3>
<p><a target="_blank" href="https://www.coursera.org/professional-certificates/google-business-intelligence">Go here</a> to check out the overview of each business intelligence course.</p>
<p>Click into each course below to explore in more detail and see all the modules within each course. This shorter program is estimated by Google to take two months to complete.</p>
<ol>
<li><a target="_blank" href="https://www.coursera.org/learn/foundations-of-business-intelligence?specialization=business-intelligence-certificate">Foundations of Business Intelligence</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/the-path-to-insights-data-models-and-pipelines?specialization=business-intelligence-certificate">The Path to Insights: Data Models and Pipelines</a></li>
<li><a target="_blank" href="https://www.coursera.org/learn/decisions-decisions-dashboards-and-reports?specialization=business-intelligence-certificate">Decisions, Decisions: Dashboards and Reports</a></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-69.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of Business Intelligence certificate coursework</em></p>
<h2 id="heading-after-the-certificate">After the Certificate</h2>
<p>Google has also developed an <a target="_blank" href="https://grow.google/employers/#?modal_active=none">employer consortium</a> of over 150 companies which will consider recent graduates of Google's programs for hiring. While this is certainly no guarantee of employment, if you're in the market it is a nice touch, and will be another helpful tool in your search.</p>
<h2 id="heading-summary">Summary</h2>
<p>I hope this has been a helpful overview for you! </p>
<p>I make weekly spreadsheet and coding videos on my <a target="_blank" href="https://www.youtube.com/@eamonncottrell?sub_confirmation=1">YouTube channel</a>. Come check it out if you find this helpful! Here's a link to my Google Sheets playlist where I walk through basic and advanced topics alike:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/undefined" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>You can also find me on <a target="_blank" href="https://www.linkedin.com/in/eamonncottrell/">LinkedIn</a>. Have a great one!👋</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Dorking for Penetration Testers — A Practical Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ Every day, Google processes over 8.5 billion searches. We know how much we use Google daily. With the crawling capabilities of Google, it can also be a powerful tool for pen testers. Google can help us find exposed files, scripts and other critical r... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-dorking-for-pentesters-a-practical-tutorial/</link>
                <guid isPermaLink="false">66d035c7ba54db009200dc85</guid>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ penetration testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 04 Apr 2023 21:10:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/dorks.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Every day, Google processes over 8.5 billion searches. We know how much we use Google daily.</p>
<p>With the crawling capabilities of Google, it can also be a powerful tool for pen testers. Google can help us find exposed files, scripts and other critical resources in web applications.</p>
<p>To find this type of sensitive information, hackers use specific search terms in Google. We call them Google Dorks.</p>
<p>Google Dorks are special search terms that help locate information which is not found through regular web searches.</p>
<p>In this article, we will look at what Google Dorks are and how they can help us in penetration testing.</p>
<h1 id="heading-what-are-google-dorks">What are Google Dorks?</h1>
<p>A Google Dork is a special search term. These terms, when used with regular search keywords, can help us discover hidden resources crawled by Google.</p>
<p>These resources include sensitive information such as usernames, passwords, credit card numbers, email addresses, shell scripts, user accounts, and so on.</p>
<p>These Dorks are not limited to Google. We can also use them with search engines like Bing and Yahoo. The results might vary, but they still serve the same purpose.</p>
<p>To harness the full potential of Google Dorking, we’ll need to master some specialized search operators. These operators will fine-tune our search results and help us find exactly what we are looking for.</p>
<p>Let’s try a few Google dorks.</p>
<h1 id="heading-common-google-dorks">Common Google Dorks</h1>
<p>Some of the common query operators in Google Dorking include search modifiers. These search modifiers allow us to find specific information that may not be accessible through traditional search methods.</p>
<p>Here are some of the most common operators used in Google Dorking.</p>
<h2 id="heading-intitle-operator">Intitle operator</h2>
<p>The “<strong>intitle</strong>” operator searches for web pages with specific words or phrases in the title tag. For instance, if you’re looking for pages that contain the phrase “password” and have “index of” in the title, you would use the search term:intitle:”index of” password.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*aGu8XsaRGj-LCmD9.png" alt="Image" width="1050" height="699" loading="lazy">
<em>In title. Image by the author.</em></p>
<h2 id="heading-inurl-operator">Inurl operator</h2>
<p>The “<strong>inurl</strong>” operator searches for web pages that contain specific words or phrases in the URL. For example, if you’re looking for pages that contain “admin.php” in the URL, you would use the search term:inurl:admin.php.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*eQJJKQ2WwakLmMWC.png" alt="Image" width="1050" height="638" loading="lazy">
<em>In url. Image by the author.</em></p>
<h2 id="heading-site-operator">Site operator</h2>
<p>The “<strong>site</strong>” operator allows you to search within a specific website or domain. For instance, if you’re looking for pages on the example.com domain that contain the word “Steganography”, you would use the search term:site:yeahhub.com “Steganography”</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*jvy2mkw49lQryy_r.png" alt="Image" width="1050" height="688" loading="lazy">
<em>In site. Image by the author.</em></p>
<h2 id="heading-filetype-operator">Filetype operator</h2>
<p>The “<strong>filetype</strong>” operator allows you to search for specific file types, such as PDFs or Word documents. For example, if you’re looking for PDF files that contain the phrase “confidential report”, you would use the search term:filetype:pdf "Advanced Network Security"</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*oXNyJ4L02zdEXCqP.png" alt="Image" width="1050" height="480" loading="lazy">
<em>Filetype. Image by the author.</em></p>
<h2 id="heading-intext-operator">Intext operator</h2>
<p>The “<strong>intext</strong>” operator searches for pages that contain specific words or phrases within the body of the page. For instance, if you’re looking for pages that contain both the words “login” and “password” within the body of the page, you would use the search term:intext:"about" contact.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*cLXuxHYh-XiwJSuC.png" alt="Image" width="1050" height="698" loading="lazy">
<em>In text. Image by the author.</em></p>
<h2 id="heading-link-operator">Link operator</h2>
<p>The “<strong>link</strong>” operator searches for web pages that link to a specific URL. For example, if you’re looking for web pages that link to the example.com domain, you would use the search term:link:”example.com”</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/0*DYGNbQTE2DYRbmAM.png" alt="Image" width="1050" height="499" loading="lazy">
<em>Link operator. Image by the author.</em></p>
<h2 id="heading-cache-operator">Cache operator</h2>
<p>The “<strong>cache</strong>” operator is used to retrieve the cached version of a web page. When you search for a website using Google, Google creates a cached version of that page in its system. This version can be useful if the original website is temporarily down or if you want to view an older version of the website.</p>
<p>Here is the syntax to find the cached version of yahoo.com.cache:https://www.yahoo.com</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/1*pJ888Ha57t-qrlF2ipSy4w.png" alt="Image" width="1050" height="693" loading="lazy">
<em>Cached version of yahoo.com. Image by author.</em></p>
<h2 id="heading-related-operator">Related operator</h2>
<p>The “<strong>related</strong>” operator is used to find web pages that are related to a specific URL. Here is the syntax to use the “related” operator to find sites similar to yahoo.com.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/1*A1S-BCae_XJXYWpfz50eUA.png" alt="Image" width="1050" height="665" loading="lazy">
<em>Related operator. Image by author.</em></p>
<p>By combining these operators in creative ways, you can find specific types of information on the web that can be useful for penetration testing and other purposes.</p>
<h1 id="heading-structure-of-query-operators">Structure of Query Operators</h1>
<p>Google Dorking query operators have a structure similar to regular Google search query operators. This technique involves using advanced operators and search queries to uncover information that is not typically available through regular searches.</p>
<p>The general structure of query operators in Google Dorking includes three elements:</p>
<ol>
<li><strong>Operator</strong>: A specific keyword or symbol that instructs Google what to search for. For instance, the “<strong>inurl</strong>” operator searches for pages that contain a particular keyword in their URL.</li>
<li><strong>Keyword:</strong> The search term or phrase that you want to find. If you are looking for a specific password file, then “password” is your keyword.</li>
<li><strong>Modifier:</strong> An additional search parameter that you can use to further refine your search. For example, the “<strong>filetype</strong>” modifier searches for a specific file type, such as a PDF.</li>
</ol>
<p>Here’s an example of a query operator structure in Google Dorking: intitle: “index of” site:example.com password filetype:pdf</p>
<p>This query uses the “<strong>intitle</strong>” operator to search for pages with “index of” in their title, the “site” operator to search within the example.com domain, the keyword “password,” and the “filetype” modifier to search for PDF files.</p>
<p>By utilizing query operators in Google Dorking, we can find useful and often vulnerable information that might not be accessible through regular searches.</p>
<h1 id="heading-google-hacking-database-ghdb">Google Hacking Database (GHDB)</h1>
<p><a target="_blank" href="https://www.exploit-db.com/google-hacking-database">The Google Hacking Database (GHDB)</a> is a compilation of search queries and query operators that help us in Google Dorking.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1050/1*ghTqBQgmfsmjgnl3T5QeKQ.png" alt="Image" width="1050" height="492" loading="lazy">
<em>Google hacking database. Image generated by author.</em></p>
<p>Johnny Long, a well-known security researcher and author, established the GHDB. It has since become a valuable resource for security engineers like you and me.</p>
<p>The GHDB has several search queries and operators that can uncover numerous sensitive files, vulnerable web servers, and applications. It can also discover default login pages and credentials, as well as network and security devices that may be prone to attack.</p>
<p>GHDB is arranged into categories such as “Files containing passwords” “Vulnerable servers” “Footholds” and “Error Messages”. Each category contains several search queries and operators crafted to reveal specific information about a target.</p>
<p>Please note that search queries and operators in the GHDB might produce false positives or outdated information. Always verify the information obtained through these search operators.</p>
<h1 id="heading-a-dorking-scenario">A Dorking Scenario</h1>
<p>Let’s assume you have to conduct a pentesting audit for a client. Here is a sample dorking scenario.</p>
<ol>
<li>Use the <strong>“site”</strong> operator to limit your search to the company’s website: site:example.com. This returns all pages on the example.com website.</li>
<li>Use the <strong>“intitle”</strong> operator to search for pages containing specific keywords in the title: intitle:”login” site:example.com. This helps identify potential login pages vulnerable to attack.</li>
<li>Use the <strong>“filetype”</strong> operator to search for specific file types: filetype:pdf site:example.com. This helps identify potential documents or reports containing sensitive information.</li>
<li>Use the <strong>“inurl”</strong> operator to search for specific URLs: inurl:”admin” site:example.com. This helps identify potential administrative pages vulnerable to attack.</li>
<li>Use the <strong>“cache”</strong> operator to view the cached version of a webpage Google has indexed: cache:example.com/login.php. This provides access to the page contents even if the original page is removed or no longer accessible.</li>
<li>Use the <strong>“related”</strong> operator to find similar websites: related:example.com. This helps identify potential partners or third-party vendors with access to the company’s network.</li>
</ol>
<h1 id="heading-summary">Summary</h1>
<p>Google Dorking is a powerful technique that allows us to perform advanced searches on Google. We can use Google Dorks to find specific information and publicly exposed vulnerabilities. It is an essential tool in a pentester’s toolkit.</p>
<p>Google Hacking Database (GHDB) provides a collection of pre-defined Google Dorks. Given the harm that someone can cause using dorking, it is important to use it ethically and with permission. Ensure that you have permission and follow ethical guidelines when using dorking for security audits.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Google Like a Pro ]]>
                </title>
                <description>
                    <![CDATA[ Are you tired of sifting through pages of irrelevant search results? Do you want to become more efficient at finding the information you need on the web? If so, this course is for you. We just published a video course on the freeCodeCamp.org YouTube ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-google-like-a-pro/</link>
                <guid isPermaLink="false">66b20320297cd6de0bd54646</guid>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Mon, 09 Jan 2023 15:30:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/googlepro.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you tired of sifting through pages of irrelevant search results? Do you want to become more efficient at finding the information you need on the web? If so, this course is for you.</p>
<p>We just published a video course on the freeCodeCamp.org YouTube channel that will teach you how to use Google like a pro.</p>
<p>Seth Goldin developed this course. Seth has been using Google to help him develop software for many years and he's currently a CS student a Yale University.</p>
<p>In this course, you'll learn how the search engine works and how to ask the right questions to get the best results. We'll also delve into the world of search operators, which are special commands that can help you narrow down and customize your search results.</p>
<p>Throughout the course, we'll cover a variety of search operators, including matching operators, date operators, source operators, boolean operators, and in-(URL/title/text/anchor) operators. We'll also explore utility operators and show you how to use and combine these operators to power up your search.</p>
<p>In addition to search operators, we'll also discuss other useful features of Google, such as Google Lens and image search. We'll also introduce you to some specialized search engines that can be helpful for specific types of information.</p>
<p>To wrap things up, we'll go over some handy keyboard shortcuts and give you some final tips and tricks for becoming a pro at Googling.</p>
<p>By the end of this course, you'll be a proficient searcher, able to find the information you need quickly and easily. So let's get started on our journey to becoming a Google pro!</p>
<p>Watch the full course on the freeCodeCamp.org YouTube channel (1-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/BRiNw490Eq0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Google like a Pro – 10 Tips for More Effective Googling ]]>
                </title>
                <description>
                    <![CDATA[ Pretty much everything is available on the internet, and Google is one of the main ways people search for information.  And while you might think it's obvious, many internet users don't know how to use Google search efficiently and effectively. In tr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-google-like-a-pro-10-tips-for-effective-googling/</link>
                <guid isPermaLink="false">66ba5d46e5ad5bacb410af20</guid>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ research ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Soham De Roy ]]>
                </dc:creator>
                <pubDate>Fri, 12 Aug 2022 18:19:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/Group-61.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Pretty much everything is available on the internet, and Google is one of the main ways people search for information. </p>
<p>And while you might think it's obvious, many internet users don't know how to use Google search <strong>efficiently</strong> and <strong>effectively</strong>.</p>
<p>In truth, Googling is an art. </p>
<p>To get the right answers, you need to ask the right questions. And to get the right answers quickly, you must know <strong>how</strong> to ask the right questions. </p>
<p>Everyone should learn the <strong>how</strong> part, and that's what this tutorial is all about. Below are some helpful tips and tricks you can use to find correct answers to your questions effectively and efficiently.</p>
<h2 id="heading-how-to-search-google-effectively">How to Search Google Effectively</h2>
<h3 id="heading-1-use-quotes-to-get-an-exact-match">1. Use quotes to get an "EXACT" match</h3>
<p>Generally, when we do a regular search on Google, it makes a <strong>shallow</strong> search. This may result in pages that may or may not contain all the words you mentioned in your search query. </p>
<p>But if you wrap your search query or question (either a term or a phrase) in quotes like this: <code>"your question goes here"</code> then Google will do a deep search. This means that all the results will include pages that <strong>contain all the terms</strong> in your question that you put within quotes. </p>
<p>This is helpful when you absolutely want a particular term or phrase to be there in your search results.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img1.PNG" alt="img1" width="600" height="400" loading="lazy"></p>
<h3 id="heading-2-search-within-a-specific-site-with-site">2. Search within a specific site with <code>site:</code></h3>
<p>If you want Google to return results from within a particular website, just add <code>site:</code> before the question you are searching. </p>
<p>This is also helpful when you want to search for something within a website that doesn't have an internal search option or perhaps doesn't have a very effective one. </p>
<p>For example, searching for <strong>site:freecodecamp.org react</strong> will populate search results only from the <a target="_blank" href="https://www.freecodecamp.org/">www.freecodecamp.org</a> website on the topic of React.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img2.PNG" alt="img2" width="600" height="400" loading="lazy"></p>
<h3 id="heading-3-exclude-a-term-from-search-results-with">3. Exclude a term from search results with <code>-</code></h3>
<p>If you don't want a term or phrase to appear in your search results, then just add <code>-</code> in front of that word. </p>
<p>For e.g. a search on =&gt; <strong>how to write components in React -class</strong> will return all the search results that don't have the term "class" in them. So, (if you know a bit of React) it'll give you only ways to write functional components in React.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img3.PNG" alt="img3" width="600" height="400" loading="lazy"></p>
<h3 id="heading-4-search-images-of-a-particular-size-with-imagesize">4. Search images of a particular size with <code>imagesize:</code></h3>
<p>If you want to search images of a particular size, then use the tag <code>imagesize:</code> in your search query along with the width and height in <strong>pixels</strong>. </p>
<p>Dimension should be in <strong>pixels</strong> only – for example, <code>imagesize:500x500</code> will populate image results which have a dimension of 500px x 500px. So a search on =&gt; "cute dog images imagesize:500x600" (coz why not) will result in pictures of cute dogs with an image size of <code>500px x 600px</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img4.PNG" alt="img4" width="600" height="400" loading="lazy"></p>
<h3 id="heading-5-search-for-a-particular-filetype-with-filetype">5. Search for a particular filetype with <code>filetype:</code></h3>
<p>If you want to get search results that contain a particular file type such as PDF or PPT, then add <code>filetype:&lt;extension&gt;</code> (without the angular brackets). For example, <strong>react tutorial filetype:pdf</strong> will generate results that contains PDF in them, as seen in the following image:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img5.PNG" alt="img5" width="600" height="400" loading="lazy"></p>
<h3 id="heading-6-use-wildcard-to-make-searches">6. Use wildcard <code>*</code> to make searches</h3>
<p>If you are unsure about or have forgotten any term in your search query/ question, then use the wildcard <code>*</code> charachter. Google will replace it for you with relevant terms. </p>
<p>For example, a search on =&gt; the <em> of money will populate the following results. It will be a bunch of pages that include the phrase such as "the </em>exchange<em> of money", "the </em>use<em> of money", "the </em>role<em> of money", "the </em>psychology* of money", and so on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img6.PNG" alt="img6" width="600" height="400" loading="lazy"></p>
<h3 id="heading-7-combine-searches-with-or-and-logic">7. Combine searches with <code>OR</code>, <code>AND</code> logic</h3>
<p>If you want your search results to contain two terms, then put the <code>AND</code> keyword in between them. For example, the search on =&gt; <strong>React AND Angular</strong> will fetch results that have both the terms react and angular in it. </p>
<p>Similarly, if you want either of the terms in your search results, then use the <code>OR</code> keyword in between them. For example, the search on =&gt; <strong>React OR Angular</strong> will fetch results that have either of the terms or even both.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img7.PNG" alt="img7" width="600" height="400" loading="lazy"></p>
<h3 id="heading-8-filter-out-searches-with-after-before-or-between-two-numbers">8. Filter out searches with <code>AFTER:</code>, <code>BEFORE:</code> or <code>..</code> between two numbers</h3>
<p>If you want Google to populate search results that were published after a particular year, then use the tag <code>AFTER:</code>. For example, the search on =&gt; <strong>React tutorials AFTER:2020</strong> will populate search results published after 2020. </p>
<p>Similarly adding the tag <code>BEFORE:</code> will return results published before a particular year. </p>
<p>You can also search for results published in a certain year range, or for that matter between any numbers. Just add <code>..</code> between the two numbers you want to search between along with the units, if any.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img8.PNG" alt="img8" width="600" height="400" loading="lazy"></p>
<h3 id="heading-9-check-out-related-websites-using-related">9. Check out related websites using <code>related:</code></h3>
<p>If you want to know what all other websites are available on the internet that are similar to a particular website, then use the <code>related:</code> tag. </p>
<p>For example, a search on <strong>related:google.com</strong> will fetch all the websites that are similar to Google like Bing, Yahoo, DuckDuckGo, and so on.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img9.PNG" alt="img9" width="600" height="400" loading="lazy"></p>
<h3 id="heading-10-use-cache-to-see-googles-cached-version-of-a-website">10. Use <code>cache:</code> to see Google's cached version of a website</h3>
<p>Google stores a cached version of websites to provide search results quickly. To see if Google has cached any site or not, just use the tag <code>cache:</code> in front of the website's URL. </p>
<p>This is especially helpful for <strong>web developers</strong> if they want to check if they are currently viewing a cached site or the latest version of a website after they have pushed some changes to the website. For example, a search for =&gt; <strong>cache:www.sohamderoy.dev</strong> on the day of writing this tutorial (that is, 4th Aug 2022) returns the following result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/img10a.png" alt="img10a" width="600" height="400" loading="lazy"></p>
<p>As you see, even though I am searching for the site on 4th August 2022, I still see a copy of the site from 3rd August 2022, as that is when Google has cached the website.</p>
<p>It is important to note that "Not all search operators return exhaustive results." as mentioned by <a target="_blank" href="https://support.google.com/websearch/answer/2466433?visit_id=637790664879774647-1036329470&amp;p=adv_pages_similar&amp;hl=en&amp;rd=1">Google</a> itself. </p>
<p>Still, I believe that these are some really handy tips that help you make an effective and efficient Google search. I hope I've explained them properly and have encouraged you to use them in your regular Google search.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Thanks for reading! I really hope you enjoyed reading this short article about how to google efficeiently and effectively and found this tutorial useful. </p>
<p>Do consider sharing it with your friends – I'd really appreciate that. Follow me on LinkedIn and Twitter and stay tuned for more amazing content! Peace out! 🖖</p>
<h3 id="heading-social-links">Social Links</h3>
<ul>
<li><a target="_blank" href="https://www.linkedin.com/feed/">LinkedIn</a></li>
<li><a target="_blank" href="https://www.sohamderoy.dev/">Website</a></li>
<li><a target="_blank" href="https://blogs.sohamderoy.dev">Other Blogs by me</a></li>
<li><a target="_blank" href="https://twitter.com/_sohamderoy">Twitter</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Apply to Google Summer of Code – GSoC Application Guide ]]>
                </title>
                <description>
                    <![CDATA[ By Jagruti Tiwari If you have heard of Google Summer of Code but aren't sure how to apply, then read on.  Whether you are a college student or a working professional, GSoC now is open to both. What is GSoC and How Does it Work? GSoC is a program ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-apply-to-google-summer-of-code/</link>
                <guid isPermaLink="false">66d45f3547a8245f78752a4c</guid>
                
                    <category>
                        <![CDATA[ community ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 31 May 2022 19:48:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/cristian-tarzi-6K8gY2g0Mfo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jagruti Tiwari</p>
<p>If you have heard of <a target="_blank" href="https://summerofcode.withgoogle.com">Google Summer of Code</a> but aren't sure how to apply, then read on. </p>
<p>Whether you are a college student or a working professional, GSoC now is open to both.</p>
<h2 id="heading-what-is-gsoc-and-how-does-it-work">What is GSoC and How Does it Work?</h2>
<p>GSoC is a program that encourages contribution to open source projects. It starts with the application process. Students apply once the organizations are announced. Then GSoC declares which projects are accepted into the program and the coding period begins.</p>
<p>If you are relying only on your college grades or work experience to get into the program, think again. It is not an interview that will help you get your foot in the door based on your qualifications or résumé. You have to submit a project idea. And it needs to be an idea that the organization is excited about and that the program wants to fund. </p>
<p>Don't forget that you will work on this project for 12 weeks or even more (if your project needs more time and the organization agrees). So make sure you propose something you want to build, fix, or revamp. It should be a project that fuels you to deliver your best.</p>
<h3 id="heading-what-happens-when-the-gsoc-results-are-out">What happens when the GSoC results are out?</h3>
<p>If you are in the Indian timezone it is around midnight when the GSoC project announcement emails start pouring in. Depending on the result, you might be having a pizza party or blinking away tears.</p>
<p>If the results went your way, congratulations for making it into the program. For the next 3 to 4 weeks you have a community bonding period. Here you get to know your mentors and team. </p>
<p>You might kickstart or brainstorm your project. If you are someone like me who changed your personal commitment if you were to get selected, you'll need a change of plans. Devise a new plan for the coming months and make new goals. Keep exploring different projects, and by the time the GSoC application period arrives again, you will know which organization you want to apply to.</p>
<p>Once the contributing period ends, the coding period starts. This period is divided into two phases. You have to propose two major deliverables for each phase.</p>
<p>You need a thorough plan for phase 1. Make sure you meet your weekly goals. In the next 4 to 5 weeks it will be time for your first evaluation. Before the evaluation, you should have delivered your first deliverable. Your mentor will submit your evaluation to the GSoC team. Once the evaluation is submitted 45% of your stipend will be released. This marks the end of phase 1.</p>
<p>In phase 2 you will start working on your second deliverable. This final phase is of 6 to 8 weeks. Along with completing your project, you also have to document, test, demo, and hand it over to the organization. Your mentor will evaluate your performance and submit it to the GSoC team. This marks the end of your contribution period.</p>
<p>Your organization then decides whether your project was a success, and depending on this your pending payment is released.</p>
<h2 id="heading-whats-new-in-gsoc-2022">What's new in GSoC 2022?</h2>
<p>For the past 17 years, GSoC was solely focused on university students. The aim was to give them some industry experience in the summer and prepare them for real-world software development. </p>
<p>In 2022 this has changed. GSoC has opened its doors to contributors from all walks of life. You may be a student, working professional, or retired veteran – if you can code you are welcome to the program.</p>
<p>Also starting this year two types of projects have been announced: medium-sized and large-sized projects. A medium-sized project would be ~175 hours and a large-sized project would be ~350 hours. Previously you had to do a large size project for 12 weeks.</p>
<p>In one of the <a target="_blank" href="https://opensource.googleblog.com/2021/11/expanding-google-summer-of-code-in-2022.html">blogs</a>, Stephanie shares what is new in GSoC 2022, and the thought that goes behind it. </p>
<blockquote>
<p>We realize there are many folks that could benefit from the GSoC program that are at various stages of their career, recent career changers, self-taught, those returning to the workforce, etc. so we wanted to allow these folks the opportunity to participate in GSoC. – Stephanie Taylor, Program Manager, Google Open Source</p>
</blockquote>
<p>You can extend your project for a few more weeks depending on your organization's discretion and the complexity of your project</p>
<p>These new changes cater to the different needs of the organization and contributors.</p>
<h2 id="heading-why-should-i-apply-to-gsoc">Why should I apply to GSoC?</h2>
<ul>
<li>GSoC allows you to contribute to projects that have made a significant mark in the world.</li>
<li>You get to network with some of the best engineers around the world.</li>
<li>You are assigned a mentor. With a mentor as your guide, you can speed up things that otherwise might have taken you a long time to figure out by yourself.</li>
<li>You are paid a stipend (to help you sustain and concentrate on the project) for the time you dedicate to the project. </li>
<li>You will learn many best practices of coding, and write production quality code.</li>
</ul>
<p>Nothing matches learning from the experts of the industry.</p>
<h2 id="heading-am-i-eligible-for-gsoc">Am I Eligible for GSoC?</h2>
<p>A contributor is <a target="_blank" href="https://summerofcode.withgoogle.com/get-started">eligible</a> for GSoC if:</p>
<ol>
<li>They are 18 years or older.</li>
<li>They are a beginner in open source.</li>
<li>They are not restricted legally or geographically from contributing.</li>
</ol>
<p>GSoC has no other criteria. As this is a summer coding program that does not require office visits, you need to have a setup where you can code along with a good internet connection (at least video call quality).</p>
<h2 id="heading-how-to-apply-to-gsoc">How to Apply to GSoC</h2>
<p>You can think of a GSoC proposal as a university SOP. Submitting the SOP takes a few seconds. You start preparing for your SOP a year or so in advance by doing internships, participating in various programs, and working on personal projects. This will help your SOP be strong and stand out. </p>
<p>You'll need to put in quite a bit of effort and time to the GSoC proposal as well. As GSoC is for open source beginners, you could have been be contributing to open source for a year or less and are eligible to apply for the program.</p>
<p>I started contributing to open source in Feb 2022. I came across the Github repository that has a <a target="_blank" href="https://github.com/MunGell/awesome-for-beginners">list of beginner-friendly projects</a> along with the label names you should look at. That's how I found my first organisation to contribute to open source: <a target="_blank" href="https://www.freecodecamp.org/">freeCodeCamp</a>. </p>
<p>After making minor document changes, I wrote test cases for <a target="_blank" href="https://github.com/freeCodeCamp/coderadio-client">freeCodeCamp's CodeRadio Client</a>, and this was my first actual code contribution.</p>
<p>The GSoC organizations were announced in March. I was looking for Python and JavaScript projects. I used the search bar on the <a target="_blank" href="https://summerofcode.withgoogle.com/programs/2022/organizations">organization's listing page</a> to list the organizations in my preferred technology. I read their GSoC page (every org has its own GSoC page, so make sure you read it thoroughly) and went through their Github repositories. I cloned their repositories, used their product, read the issues list, and so on.</p>
<p>That's how came across <a target="_blank" href="https://world.openfoodfacts.org/">Open Food Facts</a>, a food database that holds details about each food product. The information comes from the manufacturer's nutrition details. The project is turning 10 this year and has 2.3M+ food products,  2.7M+ monthly visitors, and has reached 182 countries (Source: <a target="_blank" href="https://en.blog.openfoodfacts.org/news/a-makeover-for-our-10th-anniversary">Open Food Facts blog</a>).</p>
<h3 id="heading-how-did-i-select-my-first-gsoc-organization">How did I select my first GSoC organization?</h3>
<p>Selecting the right organization is as important as writing a good proposal. If your goals do not align with the organization there is a high chance your proposal won't be accepted.</p>
<p>Here are the reasons why I selected Open Food Facts as my first GSoC organization:</p>
<ul>
<li>I was able to set up and run Open Food Facts Hunger games repository easily. Previously I had tried to set up Chrome, Brave, and Django but wasn't successful. I was aware of how difficult things can get at the setup stage itself.</li>
<li>It was easy to understand what they did. I quickly found a beginner-friendly issue and commented on it for further guidance. (A beginner-friendly issue is already picked by the organization and reserved for beginners. It is usually under the label: <em>first-timers only</em>, <em>beginner-friendly</em>)</li>
<li>Mentors here were super supportive. I am grateful for their guidance and trust. It was because of their timely guidance and mentorship that I completed my proposal in time.</li>
<li>I understood their technology. This does not mean I knew everything. The main part of the project that reads nutrition data from the food label is in Python AI/ML. The main website is in Perl. I am not a Perl or ML student. I mostly go for Python and JavaScript projects. They have labels that say <em>no ML knowledge required</em> and I pick those to work on.</li>
<li>Coming to non-technical reasons, I had started late in March and the deadline to submit the proposal was the third week of April. I did not have enough time to explore many organizations. I focussed on quality instead of quantity. <strong>You can submit at most 3 proposals to GSoC.</strong> I worked hard on only one proposal and gave all my time and energy to it.</li>
<li>Open Food Facts has scope for both ~175 hour and ~350 hour projects.</li>
</ul>
<h3 id="heading-how-i-wrote-my-first-proposal">How I wrote my first proposal</h3>
<p>The proposal is the heart of your GSoC application. The strength of your proposal is directly proportional to the chances that you'll get selected.</p>
<p>A proposal is divided into the following parts:</p>
<h4 id="heading-topic-background">Topic background:</h4>
<p>You should be able to prove that you know what you are talking about. You should demonstrate the motivation behind your project, and how it will help the community. </p>
<p>Why is it worthy of your mentor's time? What is the long-term impact? You should be clear about what you are doing and why.</p>
<h4 id="heading-the-deliverables">The deliverables:</h4>
<p>Describe your deliverables in detail. Depending on your project you might have one or two major deliverables, and minor deliverables each week. </p>
<p>Each deliverable should be broken down into subtasks that you will complete each week. A delivery should include: detail description of your solution, any unforseen challenges, and how you plan to cope with them.</p>
<h4 id="heading-timeline">Timeline:</h4>
<p>Deliverables with a timeline is the best way to convince your organization that your goals are well planned. Everything might not go to plan, so it is a good idea to leave some room for uncertainties. </p>
<p>Be clear about the size of your project, the number of hours you will be available each week, and what is the best time for the mentor to contact you.</p>
<h4 id="heading-proof-of-your-capabilities">Proof of your capabilities:</h4>
<p>The organization does not know you, so it's up to you to prove that you are capable of achieving everything you claim. </p>
<p>Share links to all the open-source code you have written. Write about your background, what you like to do in your free time, other non-coding activities you do, and how they will help you succeed in GSoC.</p>
<h4 id="heading-background-on-yourself">Background on yourself:</h4>
<p>Mention your commitment to other things (university, jobs) that will keep you away from GSoC, or any personal plans to take some time off. </p>
<p>Share you contribution to other open source projects, as this will help the organization trust you that you know to work with remote teams, and will stay committed to the project.</p>
<p><a target="_blank" href="https://wiki.gnuradio.org/index.php?title=GSoCStudentInfo">GNU Radio</a> has an established road map to becoming a successful GSoC applicant. </p>
<h2 id="heading-how-i-applied-to-gsoc-with-a-full-time-job">How I Applied to GSoC with a Full-time Job</h2>
<p>Whether you are a university student or a working professional, time is limited for everyone. When I started open source contribution I was working from home. This saved traveling time and I spent my weekends contributing to GSoC. </p>
<p>If you are someone with a full-time commitment I would suggest the following: </p>
<ul>
<li>Identify how much time you can spare each week.</li>
<li>Plan your project around that time.</li>
<li>Let your mentors know about your commitment, available hours, and the best time to contact you.</li>
</ul>
<p>I had proposed a ~175-hour project. I also mentioned in my proposal that I could contribute 16-18 hours each week and my maximum availability would be on weekends.</p>
<h2 id="heading-what-if-im-not-selected">What if I'm Not Selected?</h2>
<p>Being turned down does not mean you cannot apply next year. Asking for feedback from the mentors is the first step in identifying your weak areas. The second step is working towards them.</p>
<p>GSoC is a part of the open-source journey. You can always contribute to your favorite organizations and keep exploring.</p>
<blockquote>
<p>To those that didn’t make it into the 2022 edition, my message is “don’t give up”. Rather, reflect on what you can do to have a stronger proposal for the next GSoC edition. – Source: <a target="_blank" href="https://community.jenkins.io/t/message-to-gsoc-2022-applicants/2533">Jenkins message to GSoC 2022 Applicants</a></p>
</blockquote>
<h2 id="heading-where-can-i-get-some-help-and-guidance">Where Can I Get Some Help and Guidance?</h2>
<p>There are people there who will help if you ask. No one can write your proposal for you, but they can guide you while you're writing it.</p>
<h3 id="heading-how-do-i-get-help-as-a-beginner-in-the-organisation">How do I get help as a beginner in the organisation?</h3>
<p>When you are working on an issue and get stuck, you can post your questions and doubts in the organization's chatroom (Slack channels, Discord channels, IRC channels, Google groups). Someone will answer your questions. </p>
<p>Posting in a group is always better than messaging someone directly. In a DM you're relying on one person, while in a group many people will read your question, and you might get a faster response.</p>
<h3 id="heading-whom-do-i-ask-help-for-writingreviewing-my-proposal">Whom do I ask help for writing/reviewing my proposal?</h3>
<p>Once you have completed your proposal it is always a good idea to get it reviewed before the final submission. </p>
<p>Proofread it yourself first. You can then ask your friends or family to proofread it again. A fresh pair of eyes can catch a lot of things you might have missed. </p>
<p>Make friends with people in GSoC and the open source community. You can ask fellow GSoC participants to review your proposal. You may find open source enthusiasts who are open to guiding you on LinkedIn, Twitter and other social media platforms. Search for them with hashtag #gsoc. </p>
<h2 id="heading-tips-to-help-you-succeed-in-gsoc">Tips to Help You Succeed in GSoC</h2>
<p>Here's what I would advise if you're applying to GSoC:</p>
<ol>
<li><strong>Be nice</strong>: You are not interacting with robots, but rather humans at the other end who may be separated by timezones. They might have other full-time commitments apart from the project. Be kind when asking questions and waiting for a reply. No one wants to work with someone who doesn't treat them fairly.<br> <br></li>
<li><strong>Be patient</strong>: A famous quote says: <em>good things come to those who wait</em>. Learning new things is never easy. It requires you to get out of your comfort zone, push yourself, and manage your time. <br> <br>Understanding a new project demands both - time and patience. Don't try to understand the whole project at once. Start with the part that interests you and go up. <br> <br></li>
<li><strong>It is not a rat race</strong>: GSoC is not a competition or a race. It is an experience, an opportunity to contribute to products you have been knowingly or unknowingly using in your day-to-day life. You can continue doing the good work without GSoC as well. <br> <br>As a GSoC contributor, you will be accountable to someone. There will always be a mentor to guide you within the organization when you get stuck. Enjoy the process while you are at it.<br><br></li>
<li><strong>Start early</strong>: A strong proposal is well-thought out and well-written. This requires the exchange of ideas. Some organizations are open to proposals that are outside their ideas list. Discuss it beforehand, submit PRs, and assure the organization that you can pull off your idea in the proposed time period. <br> <br>Start as early as possible. If your proposal is ready before time, say before the application window opens, you can ask the organization to review your proposal. Get their feedback and incorporate it. You cannot make changes to your proposal once the application window closes. <br><br></li>
<li><strong>Discuss and ask questions</strong>: Mentors understand that you cannot figure out everything by yourself. Before asking a question, make sure you've read the documentation well, and show that it is well-researched. <strong>Communication plays a very important role</strong> here. </li>
</ol>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>It's time to say goodbye now. Before leaving you, I want to share that I was not selected for GSoC this year. I did ask for feedback from my mentor and I'm working on improving myself.</p>
<p>I will continue contributing to open source, and I'll explore new organizations and apply again next year. So should you!</p>
<p>I also encourage you to read <a target="_blank" href="https://www.linkedin.com/in/dheeraj-sj/">Dheeraj Singh Jodha</a>'s story and learn from his GSoC 2022 journey.</p>
<blockquote>
<p>I was looking for a job right after graduating from my college and landed an internship which was exciting and highly challenging.<br> </p>
<p>Plus, one important thing is that I didn't know that I'm even eligible to participate in GSoC 2022 till Oct 2021 when Google announced that they were expanding their program to everyone. Otherwise, after graduating in June last year, I believed that I would never be participating in GSoC. I'm glad Google took this big step to make this program more inclusive.<br></p>
<p>As they say "Life doesn't make sense as we go on, but makes perfect sense when we look back." – Dheeraj Singh Jodha, GSoC 2022 contributer @Jenkins project</p>
</blockquote>
<p>GSoC has extended the eligibility criteria and allows multiple projects of varying time spans. This is a great opportunity to find a project that suits you best. What's keeping you from getting in the program?</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Google – Search Tips for Better Results ]]>
                </title>
                <description>
                    <![CDATA[ By Marko Denic Google is the most powerful tool in the world if you know how to use it properly. Let me show you how to get better at Googling. 1. Use Quotes for Exact-Match Search You can use quotes to force an exact-match search. This is super usef... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-google-search-tips/</link>
                <guid isPermaLink="false">66d45e00787a2a3b05af439a</guid>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 29 Mar 2022 18:21:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/pexels-photomix-company-218717.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Marko Denic</p>
<p>Google is the most powerful tool in the world if you know how to use it properly. Let me show you how to get better at Googling.</p>
<h2 id="heading-1-use-quotes-for-exact-match-search">1. Use Quotes for Exact-Match Search</h2>
<p>You can use quotes to force an exact-match search. This is super useful if you know exactly the search phrase you're looking for. You'll simply get more accurate results if you do this.</p>
<p><code>"what is javascript"</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-exact.PNG" alt="Google search exact match example" width="600" height="400" loading="lazy"></p>
<h2 id="heading-2-use-the-and-operator">2. Use the AND Operator</h2>
<p>The AND operator will return only results related to both terms. In the example bellow you can see the perfect use-case of this operator.</p>
<p><code>html AND css</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-and.PNG" alt="Google search with AND keyword" width="600" height="400" loading="lazy"></p>
<h2 id="heading-3-use-the-or-operator">3. Use the OR Operator</h2>
<p>You can use the OR operator to get results related to one of the search terms you enter.</p>
<p><code>(javascript OR python) free course</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-or.PNG" alt="Google search OR keyword example" width="600" height="400" loading="lazy"></p>
<h2 id="heading-4-use-the-minus-operator">4. Use the - (minus) Operator</h2>
<p>The - operator will exclude results that contain a term or phrase. So, in our case we want to get JavaScript related results, but exclude any CSS results from them.</p>
<p><code>javascript -css</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-minus.PNG" alt="Google search with - operator example" width="600" height="400" loading="lazy"></p>
<h2 id="heading-5-use-wildcards-as-placeholders">5. Use (*) wildcards as placeholders</h2>
<p>You can use the (*) wildcards as placeholders, which will be replaced by any word or phrase. </p>
<p>This one is my favorite. I use it when I know almost the whole search phrase and just replace the part I don't know with asterisk. Super useful.</p>
<p><code>"how to start * in 6 months"</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-wildcard.PNG" alt="Google search with wildcard example" width="600" height="400" loading="lazy"></p>
<h2 id="heading-6-how-to-search-inside-a-single-website">6. How to Search Inside a Single Website</h2>
<p>This is another one I use frequently. If I'm searching for something in particular on a specific website, this is my approach.</p>
<p><code>site:freecodecamp.org</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-site.PNG" alt="Google search inside a single website example" width="600" height="400" loading="lazy"></p>
<h2 id="heading-7-how-to-find-a-specific-file-type">7. How to Find a Specific File Type</h2>
<p>You can also use this very useful feature to help you find a specific file type. It's handy if you're looking for some materials like PDFs. If you haven't used it before, from now on you will.</p>
<p><code>filetype:pdf learn css</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-filetype.PNG" alt="Google search for specific filetype" width="600" height="400" loading="lazy"></p>
<h2 id="heading-8-how-to-search-for-a-range-of-numbers">8. How to Search for a Range of Numbers</h2>
<p>This can be anything at all. If you're looking to buy something that falls within a specific price range, or you're searching for results that include a specific range of years, this is for you.</p>
<p><code>ecmascript 2016..2018</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-range.PNG" alt="Google search for specific range of numbers" width="600" height="400" loading="lazy"></p>
<h2 id="heading-9-use-the-before-operator">9. Use the <code>before</code> Operator</h2>
<p>Use the before operator to return only results before a given date.<br>You must provide year-month-day dates or only a year. For example:</p>
<p><code>javascript before:2020</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-before.png" alt="Google search with before operator" width="600" height="400" loading="lazy"></p>
<h2 id="heading-10-use-the-after-operator">10. Use the <code>after</code> Operator</h2>
<p>Use the after operator to return only results after a given date. You must provide year-month-day dates or only a year. Super useful if you want exclude outdated results.</p>
<p><code>web development after:2020</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/google-after.png" alt="Google search with after operator" width="600" height="400" loading="lazy"></p>
<p>As you can see, Google can be a powerful tool if you know how to use it properly. </p>
<p>If you have any questions, you can contact me on <a target="_blank" href="https://twitter.com/denicmarko">Twitter</a>.</p>
<p>You can find a ton of real-life tips and resources on my <a target="_blank" href="https://markodenic.com/blog/">blog</a>. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What to Know Before Taking Google's Machine Learning or Data Science Course ]]>
                </title>
                <description>
                    <![CDATA[ Whether you decide to take Andrew Ng’s Machine Learning and Deep Learning course on YouTube or any Data Science bootcamp, you will need a certain degree of mathematical and statistical knowledge. This will not only help you understand basic ML/DS con... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-prepare-for-googles-machine-learning-data-science-course/</link>
                <guid isPermaLink="false">66d45f4e706b9fb1c166b975</guid>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Harshit Tyagi ]]>
                </dc:creator>
                <pubDate>Wed, 27 Oct 2021 20:03:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/10/7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Whether you decide to take Andrew Ng’s Machine Learning and Deep Learning course on YouTube or any Data Science bootcamp, you will need a certain degree of mathematical and statistical knowledge.</p>
<p>This will not only help you understand basic ML/DS concepts, but it will also help you make a long-lasting, robust career as a data professional.</p>
<p>This is a short and precise guide for all self-taught devs and beginners in the field of Data Science and Machine Learning.</p>
<p>There's a common question that pops up in all my training programs, LinkedIn courses, videos on YouTube, or newsletters. It's that when people start learning DS/ML, after a certain point they feel lost in mathematics or statistics and sometimes programming.</p>
<p>And I have always recommended learning or refreshing some mathematical concepts that underpin ML as it helps you build intuition which keeps you curious throughout your learning journey.</p>
<p>To back up this claim, here are the <a target="_blank" href="https://developers.google.com/machine-learning/crash-course/prereqs-and-prework">prerequisites and prework Google recommends before taking their Machine Learning Crash Course</a>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/Screenshot-2021-10-23-at-8.41.02-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Google ML course prerequisites</em></p>
<p>I’d recommend that you go through this article first and then look up all the links one by one and use this blog as a reference.</p>
<p>After going through the complete list of concepts and skills that are mentioned in the Google article, I also went through several books (Deep Learning by Ian Goodfellow, Deep Learning with Python by Francois Chollet, and several others).</p>
<p>From them, I tried to distill the essentials into <strong>three branches</strong> that you'll need to build a solid foundation for a career as a <strong>Data Analyst/Scientist/ML Engineer.</strong></p>
<p>Following are the three pillars along with the a list of concepts that make for a good starter program:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/pillars_ds.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>From my</em> <a target="_blank" href="https://www.wiplane.com/p/foundations-for-data-science-ml"><em>course here</em></a><em>.</em></p>
<h2 id="heading-programming-for-complete-beginners-in-data-science-and-machine-learning">Programming for Complete Beginners in Data Science and Machine Learning</h2>
<p>Programming means telling a computer predefined rules that help it process input data and then get the results.</p>
<p>Machine learning, on the other hand, is giving the machine the results and data to find the rules that best approximate the relationship between the data and the results.</p>
<p>Programming offers that base platform which you can use to automate, verify, and solve problems of any scale.</p>
<p>The next question is which language should you learn?</p>
<p>Since most of the courses, libraries, and books are written to support Python infrastructure, I recommend learning Python and so does Google’s guide. Which language you use is a personal choice and a lot of it depends on the type of problem you’re trying to solve.</p>
<p>Most beginners prefer Python as it is the best way to develop end-to-end projects and there is a very large community of fellow developers who can help you. Chances are that ~90% of the problems that you’ll encounter in your journey (especially in the beginning phase) are already solved and documented for you.</p>
<h2 id="heading-1-essential-python-programming-for-machine-learning">1. Essential Python Programming for Machine Learning</h2>
<p>Most data roles are programming-based except for a few like business intelligence, market analysis, and product analysis.</p>
<p>I am going to focus on technical data jobs that require expertise in at least one programming language. I personally prefer Python over any other language because of its versatility and ease of learning  – hands-down a good pick for developing end-to-end projects.</p>
<p>Here are some of the topics/libraries you should study for data science/ML:</p>
<ul>
<li><p><strong>Common data structures</strong> (data types, lists, dictionaries, sets, tuples), writing functions, logic, control flow, searching and sorting algorithms, object-oriented programming, and working with external libraries.</p>
</li>
<li><p><strong>Writing Python scripts</strong> to extract, format, and store data into files or back to databases.</p>
</li>
<li><p><strong>Handling multi-dimensional arrays</strong>, indexing, slicing, transposing, broadcasting and pseudorandom number generation using NumPy.</p>
</li>
<li><p>Performing vectorized operations using scientific computing libraries like NumPy.</p>
</li>
<li><p><strong>Manipulate data with Pandas  –</strong>  series, dataframe, indexing in a dataframe, comparison operators, merging dataframes, mapping, and applying functions.</p>
</li>
<li><p><strong>Wrangling data using pandas  –</strong>  checking for null values, imputing it, grouping data, describing it, performing exploratory analysis, and so on.</p>
</li>
<li><p><strong>Data Visualization using Matplotlib  –</strong> the API hierarchy, adding styles, color, and markers to a plot, knowledge of various plots and when to use them, line plots, bar plots, scatter plots, histograms, boxplots, and seaborn for more advanced plotting.</p>
</li>
</ul>
<h2 id="heading-2-essential-mathematics-for-data-science-and-machine-learning">2. Essential Mathematics for Data Science and Machine Learning</h2>
<p>There are <a target="_blank" href="https://towardsdatascience.com/practical-reasons-to-learn-mathematics-for-data-science-1f6caec161ea">practical reasons why Math is essential</a> for folks who want a career as an ML practitioner, Data Scientist, or Deep Learning Engineer.</p>
<h3 id="heading-use-linear-algebra-to-represent-data">Use linear algebra to represent data</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/3-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>_An image from the course: [https://www.wiplane.com/p/foundations-for-data-science-ml](https://www.wiplane.com/p/foundations-for-data-science-ml" data-href="https://www.wiplane.com/p/foundations-for-data-science-ml" class="markup--anchor markup--figure-anchor" rel="noopener ugc nofollow noopener" target="<em>blank)</em></p>
<p>ML is inherently data-driven – data is at the heart of machine learning. We can think of data as <strong>vectors</strong> , an object that adheres to arithmetic rules. This leads us to understand how rules of linear algebra operate over arrays of data.</p>
<h3 id="heading-use-calculus-to-train-ml-models">Use calculus to train ML models</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/IMG_0071.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Image from the course: [https://www.wiplane.com/p/foundations-for-data-science-ml](https://www.wiplane.com/p/foundations-for-data-science-ml" rel="noopener ugc nofollow noopener)</em></p>
<p>Model training happens does not happen “automatically”. Calculus is what drives the learning of most ML and DL algorithms.</p>
<p>One of the most commonly used optimization algorithms  ( <strong>gradient descent</strong>)  is an application of partial derivatives.</p>
<p>A model is a mathematical representation of certain beliefs and assumptions. It is said to learn (approximate) the process (linear, polynomial, etc) how the data is provided, was generated in the first place, and then make predictions based on that learned process.</p>
<p>Important topics include:</p>
<ul>
<li><p><strong>Basic algebra</strong>  –  ****  variables, coefficients, equations, functions — linear, exponential, logarithmic, etc.</p>
</li>
<li><p><strong>Linear Algebra</strong>  –  scalars, vectors, tensors, Norms(L1 &amp; L2), dot product, types of matrices, linear transformation, representing linear equations in matrix notation, solving linear regression problem using vectors and matrices.</p>
</li>
<li><p><strong>Calculus</strong>  –  **** derivatives and limits, derivative rules, chain rule (for backpropagation algorithm), partial derivatives (to compute gradients), the convexity of functions, local/global minima, the math behind a regression model, applied math for training a model from scratch.</p>
</li>
</ul>
<h2 id="heading-3-essential-statistics-for-data-science">3. Essential Statistics for Data Science</h2>
<p>Every organisation today is striving to become data-driven. To achieve that, Analysts and Scientists need to be able to use data in different ways in order to drive decision making.</p>
<h3 id="heading-describing-data-from-data-to-insights">Describing data — from data to insights</h3>
<p>Data always comes in raw and ugly. The initial exploration tells you what’s missing, how the data is distributed, and what’s the best way to clean it to meet the end goal.</p>
<p>In order to answer the questions you've defined, descriptive statistics enables you to transform each observation in your data into insights that make sense.</p>
<h3 id="heading-quantifying-uncertainty">Quantifying uncertainty</h3>
<p>Furthermore, the ability to quantify uncertainty is the most valuable skill that is highly regarded at any data company. Knowing the chances of success in any experiment/decision is crucial for all businesses.</p>
<p>Here are a few of the main staples of statistics that constitute the bare minimum:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/IMG_0059-2.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn-images-1.medium.com/max/1440/1*2hPdANUMw9jkTtItAMrhaA.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>_Image from the lecture on Poisson distribution — [https://www.wiplane.com/p/foundations-for-data-science-ml](https://www.wiplane.com/p/foundations-for-data-science-ml" data-href="https://www.wiplane.com/p/foundations-for-data-science-ml" class="markup--anchor markup--figure-anchor" rel="noopener ugc nofollow noopener" target="<em>blank)</em></p>
<ul>
<li><p>Estimates of location  – mean, median and other variants of these.</p>
</li>
<li><p>Estimates of variability</p>
</li>
<li><p>Correlation and covariance</p>
</li>
<li><p>Random variables  – discrete and continuous</p>
</li>
<li><p>Data distributions –  PMF, PDF, CDF</p>
</li>
<li><p>Conditional probability –  bayesian statistics</p>
</li>
<li><p>Commonly used statistical distributions –  Gaussian, Binomial, Poisson, Exponential.</p>
</li>
<li><p>Important theorems  – Law of large numbers and Central limit theorem.</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/IMG_0074.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn-images-1.medium.com/max/1440/1*HieA3gtxaVyjQsSsbc8b2Q.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>_Image from the lecture on Poisson distribution — [https://www.wiplane.com/p/foundations-for-data-science-ml](https://www.wiplane.com/p/foundations-for-data-science-ml" data-href="https://www.wiplane.com/p/foundations-for-data-science-ml" class="markup--anchor markup--figure-anchor" rel="noopener ugc nofollow noopener" target="<em>blank)</em></p>
<p>Every beginner-level data science enthusiast should focus on these three pillars before diving into any core data science or core ML course</p>
<h2 id="heading-how-to-learn-these-foundational-ds-and-ml-concepts">How to Learn these Foundational DS and ML Concepts</h2>
<p><a target="_blank" href="https://towardsdatascience.com/data-science-learning-roadmap-for-2021-84f2ba09a44f">I created a learning roadmap that you can find here</a>. It also told you what to learn and was also loaded with resources, courses, and programs that you can check out.</p>
<p>But there are a few inconsistencies in the recommended resources and the roadmap that I charted out.</p>
<h3 id="heading-problems-with-data-science-or-ml-courses">Problems with Data Science or ML Courses</h3>
<ol>
<li><p>Every data science course that I listed in that article requires students to have a decent understanding of Programming, Math, or Statistics. For example, <a target="_blank" href="https://www.youtube.com/watch?v=PPLop4L2eGk&amp;list=PLLssT5z_DsK-h9vYZkQkYNWcItqhlRJLN">the most famous course on ML by Andrew Ng</a> also relies heavily on the understanding of vector algebra and calculus.</p>
</li>
<li><p>Most courses that cover Math and Statistics for Data Science are just a checklist of concepts required for DS/ML with no explanation on how they are applied and how they are programmed into a machine.</p>
</li>
<li><p>There are exceptional resources to dive deep into Math but most of us are not made for it and you don't need to be a gold medalist to learn data science.</p>
</li>
</ol>
<p><strong>Bottom line:</strong> you need a resource that covers just enough applied math or statistics or programming to get started with data science or ML is missing.</p>
<h3 id="heading-wiplane-academy-wiplanecom">Wiplane Academy — wiplane.com</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/10/WIPLane-Profile-Pic.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>https://www.wiplane.com</em></p>
<p>So, I decided to give in and develop the course myself. I have spent months designing and developing a curriculum that will provide a solid foundation for your career as a…</p>
<ul>
<li><p>Data Analyst</p>
</li>
<li><p>Data Scientist</p>
</li>
<li><p>Or an ML Practitioner/Engineer</p>
</li>
</ul>
<p>Here's the course – <a target="_blank" href="https://www.wiplane.com/p/foundations-for-data-science-ml"><strong>Foundations for Data Science or ML</strong></a> <strong>—</strong> <a target="_blank" href="https://www.wiplane.com/p/foundations-for-data-science-ml"><strong>First Steps to learn Data Science and ML</strong></a></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/ZHCFVwq2Dgk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>It's a comprehensive yet compact and affordable course that not only covers <strong>all the essentials, pre-requisites, and pre-work</strong> but also explains how each concept is used <strong>computationally and programmatically ( in Python)</strong>.</p>
<p>And that’s not it – I will keep updating the course content every month based on your inputs. Learn more <a target="_blank" href="https://www.wiplane.com/p/foundations-for-data-science-ml">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Doodle Games – Baseball, PacMan, and More ]]>
                </title>
                <description>
                    <![CDATA[ The homepage for the Google Search engine is the most viewed webpage in the world. People conduct billions of searches every day. When you land on the page, right above the search box, you'll see Google's logo. On many occassions the logo will be dif... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-doodle-games-baseball-pacman-and-more/</link>
                <guid isPermaLink="false">66b1e40a8f7b9fe685bd6135</guid>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Mon, 26 Jul 2021 23:01:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/google-doodle-article-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The homepage for the Google Search engine is the most viewed webpage in the world. People conduct billions of searches every day.</p>
<p>When you land on the page, right above the search box, you'll see Google's logo. On many occassions the logo will be different and accompanied by what's called a <em>Doodle</em>.</p>
<p>These Doodles range from small, simple and temporary alterations to the traditional logo. But more often that not, they are very creative and artistic expressions.</p>
<p>They highlight world issues, major historical events, worldwide holidays, local celebrations, anniversaries and important figures' brithdays (including pioneers, artists, and scientists) along with their contributions to society.</p>
<p>When you click on the Doodle animation you can find more information about that specific topic and a little game or interaction sometimes sometimes accompanies the doodle.</p>
<h2 id="heading-the-first-google-doodle">The First Google Doodle</h2>
<p>The first doodle was created when Google co-founders Larry Page and Sergey Brin attended the annual Burning Man Festival in the Nevada desert in the United States on 30 August 1998.</p>
<p>They put a stick figure icon, resembling the Burning Man logo, behind the second "O" as an "Out Of Office" message to let users know of their absence in a fun and creative way.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-10.43.13-AM.png" alt="Screenshot-2021-07-25-at-10.43.13-AM" width="600" height="400" loading="lazy"></p>
<p>Google was very young at the time – it had only been a couple of years since the search engine had been built by these two Stanford students. And this was just less than a week before it would be offically incorporated as a company. </p>
<p>You can also see that the logo was different, with an exclamation mark at the end.</p>
<h2 id="heading-the-development-of-google-doodles">The Development of Google Doodles</h2>
<p>Since then, this new idea of altering the logo when celebrating notable  events was born, and the Doodles progressed.</p>
<p>Nearly two years later, Page and Brin asked Dennis Hwang – an intern at the time – to create a doodle in honor of Bastille Day, on July 14 2000. It was very well received and Dennis Hwang was appointed Chief Doodler.</p>
<p>Doodles started to appear more regularly on the homepage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-11.03.13-AM.png" alt="Screenshot-2021-07-25-at-11.03.13-AM" width="600" height="400" loading="lazy"></p>
<p>Since then, Google has a whole dedicated team of talented illustrators (called doodlers) responsible for the doodle that appears on Google's homepage for the entire globe.</p>
<p>The early doodles were fairly simple. When you hovered over the doodle, a little pop up text would appear noting what was being commemorated.</p>
<p>For Halloween in 2000, guest artist Lorie Loeb created the very first animated doodle. It featured two jack-o-lanterns in place of the "O"’s and a spider was dangling from the "L".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/halloween_loop.gif" alt="halloween_loop" width="600" height="400" loading="lazy"></p>
<p>Another notable tech-related, nostalgic doodle was that of March 12 2019, where Google commemorated the 30th anniversary of the World Wide Web.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/30th-anniversary-of-the-world-wide-web-4871946884874240-2xa-1.gif" alt="30th-anniversary-of-the-world-wide-web-4871946884874240-2xa-1" width="600" height="400" loading="lazy"></p>
<p>You can view a <a target="_blank" href="https://www.google.com/doodles#archive">historical archive</a> of all the Google Doodles that have appeared on the homepage, letting you relive any Doodle and discover new ones you may not have seen already.</p>
<h2 id="heading-the-first-google-doodle-game">The First Google Doodle Game</h2>
<p>The doodle technology kept on improving, and on May 21st 2010 Google released its first interactive game – the first ever playable Doodle Google game.</p>
<p>This release celebrated the 30th anniverary of one of the most popular and classic arcade games, Pac Man, which was released in 1980.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-4.57.49-PM.png" alt="Screenshot-2021-07-25-at-4.57.49-PM" width="600" height="400" loading="lazy"></p>
<p>It was an immense development for Google and it must have brightend many peoples' days by bringing back such a fun and addictive throwback game. It was estimated that over 1 billion people played the game in the first three days of its release.</p>
<p>The PacMan doodle game brings up 8-bit nostalgic memories as it uses the same graphics, and the same original colors, sounds, and iconic characters. It even incudes the same original game logic and bugs (!).</p>
<p>If you want to take a trip down memory lane, or be introduced to the game for the first time, you can play it <a target="_blank" href="https://www.google.com/doodles/30th-anniversary-of-pac-man">here</a>.</p>
<p>Just press "Insert Coin" and use the arrow keys on your keyboard. You are a yellow hero aiming to eat all the dots without getting caught by ghosts of different colors.</p>
<p>Be prepared to spend one too many hours on this one.</p>
<h2 id="heading-how-to-play-doodle-google-games">How to Play Doodle Google Games</h2>
<p>Since then there have been many more fun and interactive games and puzzles.</p>
<p>The doodles and games usually stay up for one day to commemorate a specific event. But Google archives all its old doodles and doodle games on the <a target="_blank" href="https://www.google.com/doodles?q=interactive">dedicated archive page</a> instead of just getting rid of them. </p>
<p>Thanks to this, you can play any of the games that have been featured on the search engine's homepage.</p>
<p>Playing them is easy and fuss free.</p>
<p>They are all web based and can be played on both desktop and mobile without needing to download anything or set up a console. You don't need any equipment – just a browser and an internet connection.</p>
<p>Click on the links to go to the page for the specific game and then click to start the game.</p>
<p>In most cases you'll use your mouse or trackpad and keyboard. If you're playing from a mobile you'll be swipping or tapping.</p>
<h2 id="heading-popular-doodle-google-games">Popular Doodle Google Games</h2>
<p>Below is a list of some of the most well known and popular doodle games, grouped together based on different categories.</p>
<h3 id="heading-doodle-brain-teaser-games">Doodle brain teaser games</h3>
<h4 id="heading-rubiks-cube">Rubik's Cube</h4>
<p>The <a target="_blank" href="https://www.google.com/doodles/rubiks-cube">Rubik's cube</a> appeared on the homepage on May 19, 2014 and is one of the biggest and most fascinating mental challenges. </p>
<p>The colors move horizontally, but you can move its pieces by clicking anywhere on the cube to turn it on all its sides. 
<img src="https://www.freecodecamp.org/news/content/images/2021/07/rubik-1.gif" alt="rubik-1" width="600" height="400" loading="lazy"></p>
<h4 id="heading-crossword-puzzles">Crossword puzzles</h4>
<p>On December 21st 2013, Google came out with a tribute to <a target="_blank" href="https://www.google.com/logos/2013/crossword/crossword13.html">crosswords</a> to commemorate 100 years of crossword puzzles. </p>
<p>With the help of Merl Reagle, one of the best and most well known crossword instructors, Google created their own version of a crossword with clues. It also shared bits of puzzle history throughout.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-8.13.01-PM.png" alt="Screenshot-2021-07-25-at-8.13.01-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-coding-games">Doodle coding games</h3>
<h4 id="heading-coding-for-carrots">Coding for carrots</h4>
<p><a target="_blank" href="https://www.google.com/doodles/celebrating-50-years-of-kids-coding">Coding for carrots</a> introduces childern (or you!) to the world of programming by connecting blocks that represent coding concepts. This helps guide a rabbit across 6 levels to get to its favorite food – a carrot – and collect it. </p>
<p>The game was released on 4 December 2017 during Computer Science Education week in collaboration with MIT to celebrate 50 years of Kids Coding and of coding languages for kids. It's based on the Scratch programming language.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/carrot.gif" alt="carrot" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-sports-fans">Doodle games for sports fans</h3>
<h4 id="heading-cricket">Cricket</h4>
<p><a target="_blank" href="https://www.google.com/doodles/icc-champions-trophy-2017-begins">Cricket</a> was introduced to celebrate the 2017 ICC Champions Trophy and you play cricket as an animated cricket.  </p>
<p>Just click on the bat to swing it when you see the ball coming towards you and want to hit it to score. It's a clever re-creation of the sport. 
<img src="https://www.freecodecamp.org/news/content/images/2021/07/cricket.gif" alt="cricket" width="600" height="400" loading="lazy"></p>
<h4 id="heading-baseball">Baseball</h4>
<p><a target="_blank" href="https://www.google.com/doodles/fourth-of-july-2019">Baseball</a> was introduced in honor of 4th of July, US Independence day, in 2019. The players are classic American snacks like hot dogs, fries, and ketchup. </p>
<p>Click to swing the bat and if you're like I am, be prepared to hear "You're Out" too many times (otherwise you'll see plenty of fireworks).
<img src="https://www.freecodecamp.org/news/content/images/2021/07/4th.gif" alt="4th" width="600" height="400" loading="lazy"></p>
<h4 id="heading-basketball">Basketball</h4>
<p><a target="_blank" href="https://www.google.com/doodles/basketball-2012">Basketball</a> came out in 2012, honoring the 2012 Olympic Summer games with this interactive basketball game. You try to make as many baskets as you can in 24 seconds. </p>
<p>Besides this game, for that period Google released three other separate interactive sports games, like <a target="_blank" href="https://www.google.com/doodles/soccer-2012">Soccer</a>. With this one you're a goal keeper, using the space key to stop the incoming ball from reaching the net and the arrow keys to change your position.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-2.48.47-PM.png" alt="Screenshot-2021-07-26-at-2.48.47-PM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-2020-tokyo-olympics">2020 Tokyo Olympics</h4>
<p>In celebration of the <a target="_blank" href="https://www.google.com/doodles/doodle-champion-island-games-july-24">2020 Tokyo Olympics</a>,Google released its most ambitious, elaborate, and complex game to date – a full on anime sports game called the Doodle Champion Island Games. </p>
<p>It's a homage to retro 16-bit Japanese video games, with 7 mini Olympic game sporting event themes to choose from (including table tennis, skateboarding, and artistic swimming among others). It's the largest game Google has released. </p>
<p>You play as a Calico ninja warrior cat named Lucky that arrives on the island where the festival is underway. You can choose from one of 4 teams - the Blue, Red, Yellow, or Green team - represented by Ushi, Karasu, Inari, or Kappa. </p>
<p>To play, use the arrow keys and space bar and pay tribute by celebrating Japanese history, culture, and sports throughtout the game. It was made in partnership with Japanese animation studio Studio 4°C.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-11.01.56-AM.png" alt="Screenshot-2021-07-26-at-11.01.56-AM" width="600" height="400" loading="lazy"> </p>
<h3 id="heading-doodle-games-for-music-lovers">Doodle games for music lovers</h3>
<h4 id="heading-celebrating-oskar-fischinger">Celebrating Oskar Fischinger</h4>
<p><a target="_blank" href="https://www.google.com/doodles/oskar-fischingers-117th-birthday">Fischinger</a> was created on 17 June 2017 to celebrate Oskar Fischinger's 117th birthday. </p>
<p>To honor the filmmaker and visual artist, Google released an interactive design with a visual music composition tool, letting users click and create their own visual pieces of music with the wide variety of settings you can change.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-7.47.35-PM.png" alt="Screenshot-2021-07-25-at-7.47.35-PM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-celebrating-the-birth-of-hip-hop">Celebrating the birth of Hip Hop</h4>
<p><a target="_blank" href="https://www.google.com/doodles/44th-anniversary-of-the-birth-of-hip-hop">Hip Hop</a> was released to commemorate the 44th anniversary of the birth of  hip-hop, on 11th August 2017. </p>
<p>With the crossfader you can mix legendary beats together, change the volume and intensity of playback speed, and pick tracks. The classic DJ interactive turntable will let you cut and scratch tracks and relive hip-hop history. </p>
<p>The graffiti was made by artist Cey Adams, and it's narrated by hip-hop icon Fab Five Freddy. It pays tribute to Kool Herc and Coke La Rock, the two founding fathers of hip hop.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.38.20-AM.png" alt="Screenshot-2021-07-26-at-10.38.20-AM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-rockmore">Rockmore</h4>
<p><a target="_blank" href="https://www.google.com/doodles/clara-rockmores-105th-birthday">Rockmore</a> simulates the experience of the Theremin. This is an electronic musical instrument that works without physical contact – only by gesture controls. </p>
<p>The game celebrates the anniversary of Clara Rockmore’s 105th birthday, the inventor and the instrument's most well known performer, on 9th March 2016. </p>
<p>It will let you create music and experiment with the different settings and replicate different notes. Move your cursor or mouse over the notes on the screen to create music using a virtual Theremin.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-4.07.53-PM.png" alt="Screenshot-2021-07-26-at-4.07.53-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-creatives">Doodle games for creatives</h3>
<h4 id="heading-quick-draw">Quick draw</h4>
<p><a target="_blank" href="https://quickdraw.withgoogle.com/">Quick draw!</a> is a game that got its own website. You are given instructions on the screen about what to draw and a 20 second timeframe to do so. Google's neural network then makes guesses and tells you what your drawing resembles. </p>
<p>The game is built with Machine Learning and is one of the most popular Doodle games.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-7.53.52-PM.png" alt="Screenshot-2021-07-25-at-7.53.52-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-science-fiction-enthusiasts">Doodle games for science-fiction enthusiasts</h3>
<h4 id="heading-doctor-who">Doctor Who</h4>
<p>The <a target="_blank" href="https://www.google.com/doodles/doctor-whos-50th-anniversary">Doctor Who</a> doodle game, released on 23 November 2013, was created to honor the 50th anniversary of the classic and popular British television show, Doctor Who. </p>
<p>It's a simple but impressive adventure puzzle game, featuring all of the 13 doctors at the time it was made. </p>
<p>The goal is to retrieve all of the 6 letters from Google logo that the Daleks stole from the doctors, going through the 6 levels of the game.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.41.15-AM.png" alt="Screenshot-2021-07-26-at-10.41.15-AM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-food-games">Doodle food games</h3>
<p><a target="_blank" href="https://www.google.com/doodles/wilbur-scovilles-151st-birthday">Scoville</a> was released on 22nd January 2016 to celebrate Wilbur Scoville’s 151st birthday. </p>
<p>The Scoville Scale is a system that measures how hot a pepper is. In this game, you're an ice cream fighting against spicy peppers by throwing scoops at them. Peppers start progressively getting hotter each time.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.55.11-AM.png" alt="Screenshot-2021-07-26-at-10.55.11-AM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-people-who-love-halloween">Doodle games for people who love Halloween</h3>
<h4 id="heading-the-magic-cat-academy">The Magic Cat Academy</h4>
<p><a target="_blank" href="https://www.google.com/doodles/halloween-2016">The Magic Cat Academy</a> celebrated Halloween in 2016 and follows a cat named Momo who wants to restore peace at the Magic Cat Academy where she's a student so she can rescue the school. </p>
<p>The muse for this game was a black cat that belongs to the Doodler who built the game, Juliana Chen. </p>
<p>Momo has to go through 5 levels in her school – the library, cafeteria, classroom, gym, and building rooftop. And along the way she has to swipe her wand to trace symbols above the heads of the ghosts that appear! This way, Momo casts spells and won't get her spellbook taken away from her by the ghosts that are lurking. </p>
<p>Use your keypad to swipe above the ghosts's heads, turning them into thin air.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-3.39.40-PM.png" alt="Screenshot-2021-07-26-at-3.39.40-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-those-who-enjoy-card-games">Doodle games for those who enjoy card games</h3>
<h4 id="heading-loteria">Loteria</h4>
<p><a target="_blank" href="https://www.google.com/doodles/celebrating-loteria">Loteria</a> is a traditional Mexican card game. You can start a match with your friends or with random people from all around the globe. </p>
<p>It was released on 9th December 2019, celebrating this traditional game with a virtual version. There is a tutorial before your first trial round if you've never played Lotería before.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-3.53.58-PM.png" alt="Screenshot-2021-07-26-at-3.53.58-PM" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you enjoyed this write-up of some of Google's most popular Doodle Games for you to try.</p>
<p>There are many more available on the dedicated <a target="_blank" href="https://www.google.com/doodles?q=interactive">archive page</a>, so go have a look and see what interests you.</p>
<p>Thanks for reading!</p>
<p>Copyright: All images belong to Google</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
