Wednesday, February 12, 2025

What is the difference between a Junior and Senior Developer?

On Quora I've seen this question asked quite frequently: What is the difference between a junior developer and a senior developer? It is more than just years of experience. One of my co-workers was looking at a potential candidate for hire. He said that this person has 5 years of experience but he is still a junior. He repeated the beginner year of experience five times. This begs the question; what skills should a junior developer have? Whether you have completed a computer science bachelors degree, gone through a boot camp, or are self taught, these skills are essential for the basics:

Junior Developer

  • Operating system basics
  • Networking basics
  • Digital device basics
  • Programming basics
  • Cloud computing basics
  • Data structures and algorithms
  • Object oriented programming
  • Mobile device programming
  • Database basics
  • Infrastructure security
  • Cybersecurity
  • AI driven coding
  • Debugging
  • Database applications

Mid-Level Developer

A mid-level developer has at least two years of experience in either the front end or the back end. A key indicator that a developer has reached this level is that they no longer ask the team lead for help. In fact they may be helping other junior developers.

Backend Skills
  • Language:  C# or Java
  • Backend Framework:  .NET Core or Spring Boot
  • ORM:  Entity Framework or Hibernate
  • Database Language:  SQL
  • Backend Unit Testing: NUnit or JUnit
  • Backend Mocking:  MOQ or Mockito
  • API Testing:  Postman or RestAssured
  • Cloud Technologies:  AWS or Azure
  • File Formats:  JSON, YAML, XML
  • Technologies:  GIT, JIRA, Azure DevOps
  • Principles: SCRUM, Kanban, REST, Microservices, SOA, Estimation
  • IDE:  Visual Studio, Rider or IntelliJ IDEA

Frontend Skills
  • Language:  JavaScript and TypeScript
  • Frameworks:  VueJS, React, Angular, Blazor, or ASP.NET MVC
  • HTML
  • CSS
  • CSS Frameworks: Less, SASS, Bootstrap, Tailwind
  • Front End Unit Testing: Jasmine or Jest
  • File Formats:  JSON, YAML, XML
  • Technologies:  GIT, NPM, NODE, JIRA, Azure DevOps
  • Principles: SCRUM, Kanban, REST, Microservices, SOA, Estimation
  • IDE:  VSCode

Senior Developer

A senior developer is a full stack developer. They normally have at least 5 years of experience. They have mastered the front end, the back end, databases, unit testing, integration testing, GUI testing, and cloud technologies. They have also learned and are using design patterns. They adhere to the solid design principles and create clean code.  They are able to build deployment pipelines.  Here are the additional skills for a senior developer.

  • Design Patterns
  • SOLID Design Principles
  • Test Driven Development
  • Multithreaded Development
  • Memory and Performance Optimization
  • Load Testing
  • Continuous Integration
  • SAFE
  • DevOps
  • GUI Testing:  Playwright or Cypress
  • Pipelines:  Azure, AWS, Google Cloud and GitHub Actions
  • N-Tier Architecture
  • Onion Architecture
  • Clean Architecture
  • Hexagonal Architecture
  • Serverless Architecture
  • CQRS
  • Microservices Architecture

Architect

There used to be only one meaning of the word Architect, a Software Architect.  However now there are four meanings.  The Software Architect is at the application level, establishing the architecture of the application, the initial design patterns, creating feature designs, establishing coding standards, establishing testing standards, creating the onboarding process, creating the development process, GIT branching strategy, performance standards, and best practices.  If there is no SCRUM master, the Software Architect also becomes the SCRUM master.  If there is no DevOps Engineer, the Software Architect sets up all of the build and deployment pipelines.  The Cloud Architect, is familiar with all the services for AWS, Azure, and Google Cloud Platform.  They know how everything is configured and how to pass data between the different services.  They script it all with Terraform.  The Infrastructure Architect plans and implements physical data centers.  The Enterprise Architect plans how systems will interact at the enterprise level typically using TOGAF.

So how do you learn all of these skills?  Primarily I use a combination of YouTube, Udemy, and Cheatography.  You can also ask ChatGPT to explain each concept to you.

This is a great article by my friend Jonathan Danylko about the difference between knowledge and experience:

Monday, October 14, 2024

Localization in Blazor

Here are the lessons that I learned while performing the translation to Spanish for The Bed Brigade National website.  I created documentation specific for our project.

  • If you have a brownfield project, you have to find all of the strings that need to be localized in your Razor files.  I ended up creating logic to do this.  
  • You have to localize any validation messages.  I still wanted to use DataAttributes for validation so I ended up writing some custom code to pull out the validation messages and then more custom logic to actually do the validation and get the translation.
  • The need to do partial translations.  Sometimes dropdown lists, enums, or other dynamic content can be partially translated.  I created code to do this.
  • Content Management System translations.  We are seeding our whole site so that when you run it locally or you deploy it to a new environment you have data to work with.  So the content can be pre-translated.  However once the user changes words on the page, we need to check if we can translated it using what we have already translated, if not we need to queue it for translation.  
  • Translators cannot handle weird line feeds in the middle of your content.  I like to format my HTML before I save it and this does not affect the browser rendering at all.  However the language translators have no idea what you are doing and will return back strange translations.  So you have to replace all tabs, and line feeds with spaces.
  • There is one free translator available.  It is slow but it works.
Before embarking on localization in Blazor I watched most of the videos on YouTube relating to localization.  Basically there are two options, the traditional resource .resx files that have been around since WinForm days and resource files using YAML.  I would encourage you to watch both of these videos:  


I chose the second option; the multilanguages open source project to perform localization.  I contributed a bunch of new features to this project which I originally created for the Bed Brigade National website.  The main reason why I chose it was for its ability to translate the YAML files into 69 different languages.  Although my wife speaks Spanish, she did not have to translate a single word for our website.  

Bed Brigade is a charity and I did not want to break the bank on translations.  We ended up going with the free API Layer translator service.  Since everything on the entire site is pre-translated with resource files, it is only when the user adds or changes content that we might need to translate something.

Here are the other options for translating text dynamically if you have a content management system on your site.  

    Wednesday, August 14, 2024

    Resources for Learning Blazor 8

    Official Microsoft Resources

    Microsoft Official Blazor Page

    https://learn.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-8.0


    Build your first web app with ASP.NET Core using Blazor

    https://dotnet.microsoft.com/en-us/learn/aspnet/blazor-tutorial/intro


    Blazor 8 Paid Courses

    Blazor Deep Dive - From Beginner to Advanced in .NET 8

    https://www.udemy.com/course/blazor-deep-dive-from-beginner-to-advanced


    Master Blazor: Build Inventory Management System in .NET 8

    https://www.udemy.com/course/learn-blazor-while-creating-an-inventory-management-system/


    Free Courses on YouTube Ordered by Likes


    Full stack web UI with Blazor in .NET 8 | .NET Conf 2023 (3.1K Likes)

    https://www.youtube.com/watch?v=YwZdtLEtROA


    Blazor Full Course For Beginners (2.1K Likes)

    https://www.youtube.com/watch?v=RBVIclt4sOo


    CRUD w/ Blazor in .NET 8 All Render Modes (SSR, Server, Wasm, Auto), Entity Framework & SQL Server (1.9K Likes)

    https://www.youtube.com/watch?v=w8imy7LT9zY


    Intro to Blazor in .NET 8 - SSR, Stream Rendering, Auto, and more... (1.9K Likes)

    https://www.youtube.com/watch?v=walv3nLTJ5g 


    Modern Full-Stack Web Development with ASP.NET Core & Blazor (821 Likes)

    https://www.youtube.com/watch?v=NbfhbDKiFpM


    Blazor in .NET 8 in 3 Hours | Blazor Server | WebAssembly | Entity Framework Core | ASP.NET Identity (605 Likes)

    https://www.youtube.com/watch?v=LMDo38DPxZc


    Learn Blazor: Build an Inventory Management System in .NET 8 (532 Likes)

    https://www.youtube.com/watch?v=JgEjgobtDg0


    Full Complete Blazor Students Management System with Admin LTE in .NET8.0,EF Core,SQL Server (234 Likes)

    https://www.youtube.com/watch?v=2t1ZYxOMycw


    .NET 8 Blazor The Ultimate Beginners Guide (116 Likes)

    https://www.youtube.com/watch?v=a_HUyGhUI9M&list=PL285LgYq_FoI2LFCSUTpc8PSkFkLxN7cB


    People to Subscribe to on YouTube

    https://www.youtube.com/@PatrickGod

    https://www.youtube.com/@IAmTimCorey

    Friday, July 19, 2024

    Running .NET Core Tests and collecting coverage with Azure Pipelines

    Installing Coverlet

    Coverlet is an open source project that produces code coverage reports.

    In Visual Studio install the coverlet.collector and coverlet.msbuild NuGet package.

    nuget install coverlet.collector

    nuget install coverlet.msbuild

    Running Coverlet Locally

    dotnet test /p:CollectCoverage=true

    Viewing Coverage in Visual Studio

    This Visual Studio 2022 extension allows you to view coverage line by line and as a summary

    https://marketplace.visualstudio.com/items?itemName=FortuneNgwenya.FineCodeCoverage

    Defining the Azure Pipeline

    Using the wizard follow the steps below.

    Use the .NET Core SDK

    Select the .NET Core SDK appropriate for your project.



    Perform a .NET Restore

    A restore will download the Nuget packages for your project.



    Perform a .NET Build



    Run the Tests

    Ensure to define the arguments to collect coverage



    Publish the Code Coverage

    Task version 1 will be deprecated. See this post from Microsoft:

    https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/publish-code-coverage-results-v2?view=azure-pipelines




    Tuesday, July 16, 2024

    Running Jasmine Tests Using Karma and Azure Pipelines

    In order to run Jasmine tests, the runner Karma must be used.  Karma requires Chrome.  So in Azure we will be installing all of that in a container in order to run the tests.  We will also be collecting coverage.  It is important that a full Linux distribution be used like Ubuntu.  We will be using the Azure pipeline wizard.

    Install Jasmine

    This will add Jasmine to your package.json

    npm install --save-dev jasmine-core @types/jasmine @types/jasminewd2


    Install Karma

    This will add Karma to your package.json

    npm install --save-dev karma karma-chrome-launcher karma-coverage karma-jasmine
    karma-jasmine-html-reporter

    Add a karma.conf.js to your project

    Generating detailed code coverage reports can help you identify untested parts of your codebase. Add the coverageReporter to your karma.config.js

    // Karma configuration file, see link for more information
    // https://karma-runner.github.io/1.0/config/configuration-file.html

    module.exports = function (config) {
      config.set({
        basePath: "",
        frameworks: ["jasmine", "@angular-devkit/build-angular"],
        plugins: [
          require("karma-jasmine"),
          require("karma-chrome-launcher"),
          require("karma-jasmine-html-reporter"),
          require("karma-coverage"),
          require("@angular-devkit/build-angular/plugins/karma"),
        ],
        client: {
          jasmine: {
            // you can add configuration options for Jasmine here
            // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
            // for example, you can disable the random execution with `random: false`
            // or set a specific seed with `seed: 4321`
          },
          clearContext: false, // leave Jasmine Spec Runner output visible in browser
        },
        jasmineHtmlReporter: {
          suppressAll: true, // removes the duplicated traces
        },
        coverageReporter: {
          dir: require("path").join(__dirname, "./coverage/angularapp"),
          subdir: ".",
          reporters: [{ type: "html" }, { type: "text-summary" }],
        },
        reporters: ["progress", "kjhtml", "coverage"],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ["Chrome", "ChromeHeadless"],
        singleRun: false,
        restartOnFileChange: true,
      });
    };


    Add test and test-headless to your package.json

      "scripts": {
        "test": "ng test",
        "test-headless": "ng test --code-coverage --watch=false --browsers=ChromeHeadless",
      },

    In Azure Define the Pipeline



    Specify the Source Repository



    Using Bash to Install Chrome




    Here are the commands
    sudo apt-get update
    sudo apt-get install -y wget
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    sudo apt-get install -y ./google-chrome-stable_current_amd64.deb
    google-chrome --version

    Use Node

    Use the appropriate version of node for your project.





    Use NPM to install the Angular CLI




    Use NPM to install the node packages





    Use NPM to run the build




    Use NPM to run the tests








    Friday, February 9, 2024

    Cleanup Local Git Branches

     Below is a Powershell script that will remove local Git branches except for a list of excluded branches.


    # Usage:  .\RemoveGitBranches.ps1 -directoryPath "C:\path\to\your\repository"
    param (
        [string]$directoryPath
    )

    # Define the branches to keep
    $branchesToKeep = @("dev", "develop", "development", "main", "master", "qa", "test", "stage")

    # Change to the specified directory
    Set-Location -Path $directoryPath

    # Get a list of all local branches
    $branches = git branch --format "%(refname:short)"

    foreach ($branch in $branches) {
        $branch = $branch.Trim()

        # Check if the branch is not in the list of branches to keep
        if ($branch -notin $branchesToKeep) {
            # Delete the branch
            git branch -D $branch
        }
    }

    Friday, December 29, 2023

    Using MOQ

    MOQ is a popular mocking framework for .NET used to create mock objects for testing. MOQ allows you to isolate the class under test by replacing its dependencies with controlled mock objects, making it easier to test behavior in isolation.  Here are the steps to use it.  

    1.  Install MOQ.  Add MOQ using the NuGet package manager.  https://www.nuget.org/packages/Moq

    2.  Create a Mock Object. Use Mock<T> where T is the type you want to mock. For example:

    _webAPIClientMock = new Mock<IWebAPIClient>();

    3,  Setup Method Behavior. Define how the mock object should behave. For example:

    _webAPIClientMock.Setup(client => client.GetApplicationSetting(It.IsAny<GetAppSettingRequest>()).Result).Returns(appSettingResponse);

    4.  Inject the mock. Inject the mock object into the class you are testing.

    _apiSettingsProvider = new ApiSettingsProvider(Mock.Of<ILogger<ApiSettingsProvider>>(), _webAPIClientMock.Object);

    5.  Verify Interactions. Optionally, verify that certain interactions with the mock object occurred, like _webAPIClientMock.Verify(x => x.GetApplicationSetting(), Times.Once);

    6.  Run Your Test.  Execute your test method as usual.

    Full Example

    [TestClass]
    public class ApiSettingsProviderTests
    {
    private  Mock<IWebAPIClient> _webAPIClientMock;
    private  ApiSettingsProvider _apiSettingsProvider;

    [TestInitialize]
    public void Initialize()
    {
    _webAPIClientMock = new Mock<IWebAPIClient>();
    _apiSettingsProvider = new ApiSettingsProvider(Mock.Of<ILogger<ApiSettingsProvider>>(), _webAPIClientMock.Object);
    }

    [TestMethod]
    public void GetAppSettingValue_ShouldReturnFirstValueFromAppSettingsResponse()
    {
       // Arrange
    var appSettingName = "TestSetting";
    var settingValues = new string[] { "Value1", "Value2" };
    var appSettingResponse = new GetAppSettingResponse
    {
    SettingValues = new List<string>(settingValues)
    };
    _webAPIClientMock.Setup(client => client.GetApplicationSetting(It.IsAny<GetAppSettingRequest>()).Result).Returns(appSettingResponse);
    // Act
    var value = _apiSettingsProvider.GetAppSettingValue(appSettingName);
    // Assert
    Assert.AreEqual("Value1", value);
    }
    }

    Resources