software development



programming language

definition

Programming Language (Programming Language) is a bridge between people and computers. It is used to write instructions, control computer operations and implement various applications.

Classification

common programming languages

Factors to consider when choosing a language

Application areas of programming languages

Study suggestions



Comprehensive program development link list

  • Microsoft Technology Learning Center/Microsoft Learn
  • vscode/Vidual Studio Code
  • Meta/Facebook Developer
  • Chrome developer

    Programming language ranking

    According to the latest programming language rankings, here are the top 20 programming languages ​​in 2024:



    lambda expression

    1. What is a Lambda expression?

    A lambda expression is an anonymous function that is often used to simplify code, especially when you need to pass small functions or callbacks. The syntax of Lambda expression is concise and function logic can be defined in one line. Lambda expressions are most commonly found in Languages such as C++, JavaScript, Python and C#.

    2. Basic syntax of Lambda expressions

    The basic syntax of lambda expressions usually includes parameters, arrow symbols=>and function body, for example:

    (parameter) => function body

    The exact syntax varies from language to language, for example:

    3. Lambda expression examples in various languages

    C++ example

    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    int main() {
        std::vectornumbers = {1, 2, 3, 4, 5};
    
        // Use lambda expression to calculate the sum of even numbers
        int sum = 0;
        std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
            if (n % 2 == 0) sum += n;
        });
    
        std::cout << "The sum of even numbers: " << sum << std::endl;
        return 0;
    }

    Python example

    # Use lambda expression to calculate the sum of two numbers
    add = lambda x, y: x + y
    print(add(5, 10)) # Output: 15

    C# example

    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    class Program {
        static void Main() {
            List numbers = new List{ 1, 2, 3, 4, 5 };
            
            // Use a Lambda expression to filter out even numbers and calculate the sum
            int sum = numbers.Where(n => n % 2 == 0).Sum();
            
            Console.WriteLine($"The sum of even numbers: {sum}");
        }
    }

    4. Application scenarios of Lambda expressions

    5. Advantages and Disadvantages



    Reflection

    concept

    Reflection allows programs to dynamically inspect and manipulate types (categories/structures), properties, fields, methods and annotations (metadata) during execution. The exact type does not need to be known at compile time to read and write members or call methods.

    Common uses

    Advantages and Disadvantages

    Language support status

    Typical example

    # Python: List and read object properties
    class User:
        def __init__(self): self.id = 0; self.name = "Ann"
    u = User()
    for k, v in vars(u).items():
        print(k, v) # id 0 / name Ann
    // C#: Get the field/property and read the value
    using System;
    using System.Reflection;
    
    var t = typeof(MyType);
    foreach (var p in t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
        Console.WriteLine($"{p.Name}={p.GetValue(obj)}");
    // JavaScript: dynamic enumeration and calling
    const obj = { x: 1, y: 2, add(){ return this.x + this.y; } };
    for (const [k,v] of Object.entries(obj)) console.log(k, v);
    console.log(obj["add"]()); // 3
    // Java: Reading/writing fields using reflection
    import java.lang.reflect.*;
    class U { private int id = 42; }
    U u = new U();
    Field f = U.class.getDeclaredField("id");
    f.setAccessible(true);
    System.out.println(f.getInt(u)); // 42
    // Go: reflect visit structure
    import "reflect"
    func Dump(v any) {
        val := reflect.ValueOf(v)
        for i := 0; i < val.NumField(); i++ {
            name := val.Type().Field(i).Name
            fmt.Println(name, val.Field(i).Interface())
        }
    }

    best practices

    When to avoid



    Checks whether any structure is all zeros

    Concept summary

    Language support comparison

    languageSupportillustrate
    PythonDynamic, full reflection, easy recursive object/container inspection.
    JavaScript / TypeScriptThe object is key-value and availableObject.valuesrecursion.
    Rubyinstance_variablesreflective member.
    PHPget_object_vars()Or Reflection.
    C# (.NET)Reflection obtains fields/properties and has good type safety.
    Javajava.lang.reflectScannable fields.
    KotlinJVM reflection is complete, similar to Java.
    GoreflectAccessible to struct fields.
    SwiftMirrorVisits are possible, but the scenes are limited and additional processing is required.
    C++ (to C++23)No runtime reflection, you need to manually write checks for types.
    RustNo runtime reflection, often implemented by derive/trait.

    Python example

    def is_all_zero(obj, eps=1e-6):
        if isinstance(obj, (int, float)): # Basic numerical value
            return abs(obj) < eps
        elif isinstance(obj, (list, tuple, set)): # sequence/set
            return all(is_all_zero(x, eps) for x in obj)
        elif isinstance(obj, dict): # Dictionary
            return all(is_all_zero(v, eps) for v in obj.values())
        elif hasattr(obj, "__dict__"): # General objects
            return all(is_all_zero(v, eps) for v in vars(obj).values())
        else:
            return False
    
    # test
    class point:
        def __init__(self, x=0, y=0): self.x, self.y = x, y
    class Line:
        def __init__(self, p1=None, p2=None):
            self.p1 = p1 or Point()
            self.p2 = p2 or Point()
    
    print(is_all_zero([[0,0],[0,0]])) # True
    print(is_all_zero(Line(Point(0,0),Point(0,0)))) # True
    print(is_all_zero(Line(Point(1,0),Point(0,0)))) # False

    JavaScript example

    function isAllZero(obj, eps = 1e-6) {
      const isNumZero = n => Math.abs(n) < eps;
      if (typeof obj === "number") return isNumZero(obj);
      if (Array.isArray(obj)) return obj.every(v => isAllZero(v, eps));
      if (obj && typeof obj === "object")
        return Object.values(obj).every(v => isAllZero(v, eps));
      return false;
    }
    
    console.log(isAllZero([[0,0],[0,0]])); // true
    console.log(isAllZero({x:0, y:{z:0}})); // true
    console.log(isAllZero({x:0.000001, y:0})); // depends on eps

    C# (.NET) Example

    using System;
    using System.Linq;
    using System.Reflection;
    
    public static class ZeroCheck {
        public static bool IsAllZero(object obj, double eps = 1e-6) {
            if (obj == null) return true;
            switch (obj) {
                case int i: return i == 0;
                case long l: return l == 0;
                case float f: return Math.Abs​​(f) < eps;
                case double d: return Math.Abs​​(d) < eps;
            }
    
            var t = obj.GetType();
            if (t.IsArray)
                return ((Array)obj).Cast<object>().All(x => IsAllZero(x, eps));
    
            //Scan fields and attributes
            foreach (var f in t.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
                if (!IsAllZero(f.GetValue(obj), eps)) return false;
    
            foreach (var p in t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
                if (p.CanRead && !IsAllZero(p.GetValue(obj, null), eps)) return false;
    
            return true;
        }
    }

    Go examples

    package main
    
    import (
        "math"
        "reflect"
    )
    
    func IsAllZero(v interface{}, eps float64) bool {
        val := reflect.ValueOf(v)
        switch val.Kind() {
        case reflect.Float32, reflect.Float64:
            return math.Abs(val.Float()) < eps
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
            return val.Int() == 0
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
            return val.Uint() == 0
        case reflect.Slice, reflect.Array:
            for i := 0; i < val.Len(); i++ {
                if !IsAllZero(val.Index(i).Interface(), eps) { return false }
            }
            return true
        case reflect.Map:
            for _, k := range val.MapKeys() {
                if !IsAllZero(val.MapIndex(k).Interface(), eps) { return false }
            }
            return true
        case reflect.Struct:
            for i := 0; i < val.NumField(); i++ {
                if !IsAllZero(val.Field(i).Interface(), eps) { return false }
            }
            return true
        case reflect.Pointer, reflect.Interface:
            if val.IsNil() { return true }
            return IsAllZero(val.Elem().Interface(), eps)
        default:
            return false
        }
    }
    

    C++/Rust limitations and practices

    Practical suggestions



    message queue

    Definition and function

    Message Queue (MQ) is an architectural pattern for asynchronous communication between software systems. It allows independent applications or services to exchange information by sending and receiving messages without having to call each other directly or rely on each other's real-time status. The core role of MQ is to act as a middle layer that temporarily stores messages until the intended recipient is ready to process them.

    Main components

    Common message patterns

    Schema name describe Typical application scenarios
    Point-to-Point (P2P) A message is sent to a queue, and **only one** recipient will take it out of the queue and consume the message. Once consumed, the message is deleted. Order processing, task dispatch, and workload balancing.
    Publish/Subscribe, Pub/Sub A message is published to a topic, and **all** recipients (Subscribers) subscribed to the topic will receive a copy of the message. System event broadcast, log collection, data change notification.

    Key Benefits of Message Queuing

    Conclusion

    Message queues are the cornerstone of modern distributed systems, microservices architectures, and high-availability applications. It significantly improves the system's resilience, scalability, and robustness by introducing indirection in time and space.



    Message Queuing vs. HTTP API

    Differences in communication modes

    characteristic Message Queue (MQ) HTTP API (REST/RPC)
    Communication type Asynchronous Synchronous
    Coupling Low coupling (the sender and receiver do not interact directly) High coupling (the client needs to know the server's address and wait for a reply)
    data flow One-way, passed through the intermediate Broker Two-way, request and response (Request-Response)
    fault tolerance High, the Broker stores the message and the message will not be lost even if the recipient is offline. Low, the server is offline or times out, causing the request to fail.
    Scalability High, multiple consumers can be easily added to handle the load Relatively low, relying on load balancer to distribute requests

    Applicable situation comparison

    Advantages and application scenarios of Message Queuing (MQ)

    Advantages and application scenarios of HTTP API

    in conclusion

    MQ and HTTP API are not replacement technologies, but are designed for different problems.

    In modern distributed systems, the two modes often coexist and cooperate with each other to meet different business needs.




    Application examples suitable for message queues

    1. Asynchronous task processing

    In many network applications, some operations are time-consuming, and if users are made to wait simultaneously, it will result in a poor user experience. MQ allows these tasks to be executed asynchronously.

    2. Traffic peak shaving and buffering

    MQ is critical in handling transient high-traffic scenarios and can protect backend services from crashing.

    3. System decoupling and microservice communication

    In complex distributed systems and microservice architectures, MQ is used to isolate services and reduce interdependence.

    4. Log collection and monitoring

    Collect large amounts of log data from front-end applications or servers into a centralized processing system.

    5. Data streaming processing

    In particular, high-throughput MQ/streaming platforms like Apache Kafka are ideal for handling continuous streams of real-time data.



    HTTP API transfers images and videos

    Challenges of transferring large binary data

    The main challenges in using HTTP API to transfer large binary data (Binary Data) such as images and videos are:

    HTTP API method to upload (send) pictures/videos

    1. Use multipart/form-data format (most commonly used for file upload)

    This is the most standard and common way for a browser or client application to upload files.

    2. Use binary body directly

    If you only need to upload a single file, you can directly use the binary content of the file as the subject of the request.

    3. Use Base64 encoding (not recommended for large files)

    Convert binary data into ASCII strings and embed them into text formats such as JSON or XML for transmission.

    HTTP API method to download (receive) pictures/videos

    Downloading binary data is relatively simple. The server directly returns the original binary content of the file as the body of the HTTP response (Response Body).

    Optimization of video transmission: chunked transmission and streaming

    For particularly large files (especially videos), the following techniques are recommended to improve reliability and efficiency:



    Streaming key technologies

    1. Transport protocols (Protocols)

    The core of streaming transmission lies in how to transmit audio and video content from the server to the client efficiently, stably and with low latency.

    2. Core technologies and concepts

    Adaptive Bitrate Streaming (ABR)

    This is the cornerstone of modern streaming services. The server will encode the same piece of video content into multiple versions of different qualities (bit rate, resolution).

    Content Delivery Network (CDN)

    CDN is indispensable for streaming services targeting global users.

    Audio and video codecs (Codecs)

    Used to compress and decompress audio and video data to reduce file size.

    3. Content protection and monetization



    Shell

    Bash - $?

    In Bash, $? represents the exit status code (Exit Status) of the last executed command. This is an integer value usually used to determine whether the previous command was executed successfully.

    The meaning of exit status code

    Example 1: Checking successfully executed commands

    #!/bin/bash
    ls
    echo "The exit status code of the previous command was: $?"

    In this example,lsThe command will list the directory contents. After successful execution,$?The value will be 0.

    Example 2: Check for failed commands

    #!/bin/bash
    ls /nonexistent-directory
    echo "The exit status code of the previous command was: $?"

    In this example,lsAttempting to list a directory that does not exist will cause the command to fail.$?The value of will be a non-zero number.

    Example 3: Using exit status code for conditional judgment

    #!/bin/bash
    cp file1.txt /some/directory/
    if [ $? -eq 0 ]; then
        echo "File copied successfully."
    else
        echo "File copy failed."
    fi

    This example determines which message to display based on the exit status of the command.



    Bash if

    basic grammar

    if [condition]; then
        instructions
    fi

    Use AND

    To satisfy multiple conditions simultaneously in if , use:

    1. Use-a(outdated but available)

    if [ "$a" -gt 0 -a "$b" -gt 0 ]; then
        echo "a and b are both greater than 0"
    fi

    2. Use[[ ]] &&(recommend)

    if [[ "$a" -gt 0 && "$b" -gt 0 ]]; then
        echo "a and b are both greater than 0"
    fi

    3. Use multiple if combinations&&

    if [ "$a" -gt 0 ] && [ "$b" -gt 0 ]; then
        echo "a and b are both greater than 0"
    fi

    Use OR

    It can be executed as long as one of the conditions is true:

    1. Use-o(outdated but available)

    if [ "$a" -eq 0 -o "$b" -eq 0 ]; then
        echo "a or b is 0"
    fi

    2. Use[[ ]] ||(recommend)

    if [[ "$a" -eq 0 || "$b" -eq 0 ]]; then
        echo "a or b is 0"
    fi

    3. Use multiple if combinations||

    if [ "$a" -eq 0 ] || [ "$b" -eq 0 ]; then
        echo "a or b is 0"
    fi

    Mix AND and OR

    Can be used with parentheses to control precedence:

    if [[ ( "$a" -gt 0 && "$b" -gt 0 ) || "$c" -eq 1 ]]; then
        echo "a and b are both greater than 0, or c is equal to 1"
    fi

    Common usage of NOT

    In Bash,ifInstructions are usually paired with[ ](test command) or[[ ]](Extended Test Command) is used. To express NOT, use an exclamation point!

    if [ ! condition ]; then
        # Code to be executed when the condition is false
    fi

    1. Check whether the file or directory exists

    This is the most common usage, for example: create a file if it "doesn't exist".

    # If no file named config.txt exists
    if [ ! -f "config.txt" ]; then
        echo "File does not exist, creating..."
        touch config.txt
    fi
    
    # If the directory does not exist
    if [ ! -d "/var/log/myapp" ]; then
        mkdir -p "/var/log/myapp"
    fi

    2. String comparison

    Check whether the string is "not equal to" or "not empty".

    STR="hello"
    
    # Check if the variable is not equal to "world"
    if [ "$STR" != "world" ]; then
        echo "String does not match"
    fi
    
    # Check if the string is not empty (! -z is equivalent to -n)
    if [ ! -z "$STR" ]; then
        echo "There is data in the variable"
    fi

    3. Numerical comparison

    Although the numerical value is relatively-ne(not equal), but can also be matched!use.

    NUM=10
    
    if [ ! "$NUM" -eq 20 ]; then
        echo "The number is not equal to 20"
    fi

    Conditional logic comparison table

    operator illustrate example
    ! -f File does not exist [ ! -f file ]
    ! -d Directory does not exist [ ! -d dir ]
    != String is not equal to [ "$a" != "$b" ]
    ! -z String is not empty [ ! -z "$str" ]
    -ne Value is not equal to [ "$n" -ne 5 ]

    Advantages of using double brackets [[ ]]

    In more modern Bash scripts, it is recommended to use[[ ]], which is processing!More powerful and less error-prone when combined with logic.

    # Combine multiple conditions: if it is not a directory and cannot be read
    if [[ ! -d $path && ! -r $path ]]; then
        echo "Invalid path or insufficient permissions"
    fi

    Things to note



    Bash conditional branching

    basic grammatical structure

    caseStatement is used to compare the value of a variable with multiple patterns (patterns), and its function is similar to that in other languages.switch. Its grammatical structure is as follows:

    case variable in
        Mode 1)
            # Execute instructions
            ;;
        Mode 2)
            # Execute instructions
            ;;
        *)
            # Default execution command (similar to default)
            ;;
    esac

    Common usage examples

    1. Simple menu judgment

    This is the most common usage, performing different actions based on user input.

    read -p "Please enter (yes/no): " input
    
    case "$input" in
        "yes")
            echo "You selected Yes"
            ;;
        "no")
            echo "Did you choose No"
            ;;
        *)
            echo "Input error"
            ;;
    esac

    2. Combine multiple patterns (OR)

    use|Symbols allow multiple modes to execute the same block of instructions.

    read -p "Please enter the month abbreviation: " month
    
    case "$month" in
        Jan|Feb|Mar)
            echo "Season 1"
            ;;
        Apr|May|Jun)
            echo "Season 2"
            ;;
        *)
            echo "other months"
            ;;
    esac

    3. Use wildcards

    Pattern matching supports extended symbols like file paths (e.g.*, ?, [a-z])。

    read -p "Please enter a character: " char
    
    case "$char" in
        [a-z])
            echo "This is lowercase letter"
            ;;
        [A-Z])
            echo "This is a capital letter"
            ;;
        [0-9])
            echo "This is a number"
            ;;
        *)
            echo "This is a special symbol or multiple characters"
            ;;
    esac

    Explanation of key symbols

    symbol Function description
    ) The end tag of the pattern.
    ;; The end marker of the instruction block (similar tobreak)。
    * Compares any string, usually placed last as the default option.
    | Used to separate multiple matching patterns (representing "or").
    esac caseSpelled backwards, it represents the end of the grammar block.

    Precautions for use

    Case sensitivity

    Default behavior: case sensitive. In a standard Bash environment,caseThe statement isCase sensitiveof. This means "A" and "a" are treated as different patterns.

    read -p "Enter a character: " char
    case "$char" in
        a) echo "This is lowercase a" ;;
        A) echo "This is capital A" ;;
    esac
    ---

    Method 1: Use the nocasematch option

    If you want the entirecaseThe statement ignores case and can be usedshoptcommand enablednocasematchset up. This will affect all subsequent string comparisons andcasejudge.

    # Enable ignoring case
    shopt -s nocasematch
    
    read -p "Enter yes or YES: " input
    case "$input" in
        yes) echo "Match successful (ignore case)" ;;
    esac
    
    # Turn off ignoring case (restore default)
    shopt -u nocasematch
    ---

    Method 2: Manually specify the range in the pattern

    If you don't want to change the global setting, defining the case range directly in the schema is the most standard and consistent approach.

    read -p "Enter a letter: " char
    case "$char" in
        [aA])
            echo "You entered a or A"
            ;;
        [b-zB-Z])
            echo "You entered additional letters"
            ;;
    esac
    ---

    Method 3: Combine pipe symbols (OR)

    For specific words, you can use|to list all possible spellings.

    case "$input" in
        stop|STOP|Stop)
            echo "stop execution"
            ;;
    esac
    ---

    Comparison of setting methods

    method advantage shortcoming
    shopt -s nocasematch The program code is concise and suitable for large-scale comparisons. It will affect the behavior of the entire script, so remember to turn it off manually.
    [a-zA-Z]scope Precise control without affecting other parts. If the words are very long, writing will become very cumbersome.
    pipe character| High readability, suitable for a specific few words. Cannot handle random case combinations (such as YeS).


    Bash operation precedence order

    Use parentheses inside (( ))

    Arithmetic extensions in Bash(( ))Internally, you can just use parentheses( )to explicitly specify the precedence of operations, consistent with the logic of C or most programming languages. This is very important when dealing with complex logic (combining AND, OR, addition, subtraction, multiplication and division).

    # Example: (A and B) or C
    if (( (MIN > 91 && MIN< 110) || FORCE_MODE == 1 )); then
        echo "條件成立"
    fi

    precedence rules

    exist(( ))Within, the order of precedence of operations follows standard mathematical and logical conventions:

    1. Items in brackets: ( )Highest priority.
    2. Multiplication and division: *, /, %
    3. Addition and subtraction: +, -
    4. Comparison operations: <, >, <=, >=
    5. Logical operations: &&(AND) takes precedence over|| (OR)。

    Complex condition example

    Suppose you need to determine: the value must be within the range, and (must be a specific multiple or in forced mode):

    if (( MIN > 91 && (MIN % 5 == 0 || FORCE_MODE == 1) )); then
        {
            echo "Trigger complex conditional judgment"
            IS_SHUTDOWN=true
        } |& tee -a "$LOGFILE"
    fi

    Comparisons and recommendations

    syntax type Grouping symbol Things to note
    (( ... )) ( ) The most intuitive, symbols do not need to be escaped, and are recommended for pure numerical operations.
    [[ ... ]] ( ) exist[[ ]]It is also legal to use parentheses within for logical grouping.
    [ ... ] \( ... \) TraditiontestSyntax, brackets must be escaped with backslashes, which is not recommended.


    Bash exit usage

    exit command and status code

    In a Bash script,exitUsed to terminate script execution and return a status code (Exit Status) to the parent program.

    if [ -f "config.txt" ]; then
        echo "File exists"
        exit 0
    else
        echo "Error: Profile not found"
        exit 1
    fi

    Get exit status code

    After executing a script or instruction, you can use special variables$?to get the previous programexitstatus code.

    ./script.sh
    echo "Script end status: $?"

    Use backtick `` or $() to get the output value

    when you call.shfile and want to "output the contents" of it (i.e.echoWhen storing the contents of a variable, you can use backticks or$(). This is called Command Substitution.

    Sample script (get_name.sh)

    #!/bin/bash
    # This is the output content and will be captured
    echo "Ubuntu_User"
    # This is the end state and will not be captured by backticks
    exit 0

    Call from another script or terminal

    # Use backticks
    RESULT=`./get_name.sh`
    
    # Use $() (recommended modern writing)
    RESULT=$(./get_name.sh)
    
    echo "The result obtained is: $RESULT"

    Important difference: return value vs output content

    Target How to obtain use
    Exit Status (status code) $? Determine whether the instruction execution was successful (0 or 1).
    Standard Output (output content) ` `or$( ) Get the string data generated after the script is executed.

    If you want to get both at the same time, you can refer to the following example:

    OUTPUT=$(./script.sh)
    STATUS=$?
    
    echo "Content is: $OUTPUT"
    echo "The status code is: $STATUS"


    Bash return usage

    Basic definition of return

    In Bash,returninstructions are specifically used toFunctionor throughsourceThe script to execute. It stops execution of the current function or script and returns the specified status code to the caller, but does not close the current shell program.

    1. Use return within a function

    This is the most common usage.returnWhat is returned is the status code (0-255), not the string data.

    Sample script (func_test.sh)

    #!/bin/bash
    
    # define function
    check_file() {
        if [ -f "$1" ]; then
            return 0 # success
        else
            return 1 # failed
        fi
    }
    
    # Call function
    check_file "test.txt"
    RESULT=$?
    
    if [ $RESULT -eq 0 ]; then
        echo "File exists"
    else
        echo "File does not exist"
    fi

    2. Use return (with source) in the .sh file

    If you want the variables and environment to remain in the current terminal after a script is executed, you usually usesource. Must be used at this timereturnrather thanexit

    callee (sub_script.sh)

    # Simulate logical judgment
    if [ "$USER" != "root" ]; then
        echo "Insufficient permissions, only for root use"
        # If you use exit, you will directly close the terminal. If you use return, you will only stop the execution of this script.
        return 1
    fi
    
    export APP_STATUS="Ready"
    return 0

    caller (directly in CMD or another script)

    source ./sub_script.sh
    echo "Script returns status: $?"
    echo "Get environment variables: $APP_STATUS"

    3. How to obtain the "return value" through the return mechanism

    becausereturnOnly numbers (status codes) can be returned. To obtain strings or large amounts of data, it is recommended to combineechoandcommand substitution

    callee (get_data.sh)

    #!/bin/bash
    calculate() {
        local val=$(( $1 + $2 ))
        # Output results to stdout
        echo "$val"
        # Return execution status code
        return 0
    }
    
    calculate 10 20

    caller

    # Get the output content
    DATA=$(./get_data.sh)
    # Get the status code of return
    STATUS=$?
    
    echo "The calculation result is: $DATA"
    echo "Execution status: $STATUS"

    Usage summary and comparison

    Keywords Scope of application Impact on the main program
    exit 0/1 Independent scripts and subroutines Will terminate the entire current Shell (if executed with source).
    return 0/1 Function, source script loaded Only exits the current scope and does not affect the main program Shell.
    echo "..." anywhere Used to pass the actual "data content" to the caller.


    Bash check if variable is empty

    In Bash, you can use conditional judgment to check whether a variable is empty. Here are several common ways:

    Example 1: Using-zCheck if variable is empty

    #!/bin/bash
    
    var=""
    if [ -z "$var" ]; then
        echo "The variable is empty"
    else
        echo "The variable is not empty"
    fi

    -zUsed to check whether the variable is empty. If the variable is empty, the condition is true.

    Example 2: Use-nCheck if the variable is not empty

    #!/bin/bash
    
    var="some value"
    if [ -n "$var" ]; then
        echo "The variable is not empty"
    else
        echo "The variable is empty"
    fi

    -nUsed to check whether the variable is not empty. If the variable has a value, the condition is true.

    Example 3: Using double quote comparison to check if a variable is empty

    #!/bin/bash
    
    var=""
    if [ "$var" == "" ]; then
        echo "The variable is empty"
    else
        echo "The variable is not empty"
    fi

    This method directly compares the variable with the empty string to check whether the variable is empty.



    Array structure in Bash

    Introduction

    Bash supports two types of arrays:

    index array

    Defined way

    fruits=("apple" "banana" "cherry")

    Read elements

    echo "${fruits[0]}"     # apple
    echo "${fruits[1]}"     # banana

    list all elements

    echo "${fruits[@]}"

    Get array length

    echo "${#fruits[@]}"

    Add new element

    fruits+=("date")

    Traverse elements

    for fruit in "${fruits[@]}"; do
        echo "$fruit"
    done

    associative array

    Definition and usage (requires Bash 4+)

    declare -A capital
    capital["Taiwan"]="Taipei"
    capital["Japan"]="Tokyo"

    Access and traverse

    echo "${capital["Japan"]}" # Tokyo
    
    for key in "${!capital[@]}"; do
        echo "The capital of $key is ${capital[$key]}"
    done

    Things to note

    in conclusion

    Bash array is an important structure for storing multiple pieces of data, and is suitable for data processing such as parameter lists, directory sets, and key-value pairs.



    Bash merge two arrays

    basic grammar

    combined=("${array1[@]}" "${array2[@]}")

    This will merge all elements from both arrays into a new arraycombined

    Complete example

    array1=("apple" "banana")
    array2=("cherry" "date")
    
    combined=("${array1[@]}" "${array2[@]}")
    
    echo "Combined array:"
    for item in "${combined[@]}"; do
        echo "$item"
    done

    Merge into original array

    array1+=("${array2[@]}")

    This willarray2content is added directly toarray1rear.

    Things to note



    Bash determines whether a string begins with a certain word

    Use string pattern comparison (recommended)

    str="hello world"
    
    if [[ "$str" == hello* ]]; then
        echo "String starts with hello"
    fi

    illustrate:use[[ ]]Support shell pattern comparison,*Represents any character.

    Use regular expressions

    if [[ "$str" =~ ^hello ]]; then
        echo "String starts with hello"
    fi

    illustrate: ^Indicates the beginning,[[ ]]in=~is a regular operation.

    usecaseNarrate

    case "$str" in
      hello*) echo "String starting with hello" ;;
      *) echo "does not start with hello" ;;
    esac

    illustrate: caseIt is a good tool for processing string patterns, concise and highly readable.

    useexpr(Old style of writing)

    if expr "$str" : '^hello' &> /dev/null; then
        echo "String starts with hello"
    fi

    illustrate:useexprRegular matching function, suitable for older versions of the shell.

    Things to note



    Bash determines whether a file or directory exists

    Determine whether it exists:-e

    -eUsed to check whether a file or directory exists (regardless of type).

    FILE="/etc/passwd"
    
    if [ -e "$FILE" ]; then
        echo "$FILE exists"
    else
        echo "$FILE does not exist"
    fi

    Determine whether the directory does not exist:! -d

    -dUsed to check whether it is a directory,!It is a negative operation.

    DIR="/tmp/myfolder"
    
    if [ ! -d "$DIR" ]; then
        echo "$DIR does not exist, creating..."
        mkdir -p "$DIR"
    else
        echo "$DIR already exists"
    fi

    Other commonly used condition options

    Example: Combining inspection and creation

    PATH_TO_CHECK="/home/user/config"
    
    if [ -e "$PATH_TO_CHECK" ]; then
        echo "$PATH_TO_CHECK already exists"
    else
        echo "$PATH_TO_CHECK does not exist and is being created..."
        mkdir -p "$PATH_TO_CHECK"
    fi

    suggestion



    List all subdirectories and store them in an array

    Example: Store to Array

    target_dir="/path/to/your/dir"
    subdirs=()
    
    while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)

    illustrate

    Example output

    for dir in "${subdirs[@]}"; do
        echo "$dir"
    done

    Alternative simple writing (if there are no special characters)

    subdirs=( "$target_dir"/*/ )
    

    This way of writing uses wildcards to match subdirectories, but it cannot exclude files or handle spaces and special characters.



    Get the actual path containing ~

    Method 1: Use eval to expand

    path="~/myfolder/file.txt"
    realpath "$(eval echo "$path")"
    

    Method 2: Replace with $HOME

    path="~/myfolder/file.txt"
    realpath "$(echo "$path" | sed "s|^~|$HOME|")"
    

    Method 3: Use readlink

    path="~/myfolder/file.txt"
    readlink -f "$(eval echo "$path")"
    

    Recommended usage

    realpath "$(eval echo "$path")"
    


    grep

    basic search

    grep "keyword" file name

    Ignore case

    grep -i "keyword" file name

    Show line number

    grep -n "keyword" file name

    recursive search

    grep -r "keyword" directory path

    Only show matching text

    grep -o "keyword" file name

    Also display file name

    grep -H "keyword" file name

    Two sets of keywords appear together (AND)

    grep "keyword 1" file name | grep "keyword 2"

    Any one of the two keywords appears (OR)

    #Method 1: Regular expression
    grep -E "Keyword 1 | Keyword 2" file name
    
    #Method 2: Multiple -e parameters
    grep -e "keyword 1" -e "keyword 2" file name

    Solve binary file matches problem

    #Method 1: Force the file to be treated as text
    grep -a "keyword" file name
    
    #Method 2: Convert the file encoding to UTF-8 and then search
    iconv -f original encoding -t UTF-8 file name | grep "keyword"
    
    # Example (convert from BIG5 to UTF-8)
    iconv -f BIG5 -t UTF-8 file name | grep "keyword"

    Common combinations

    grep -rin "keyword" directory path


    -print0 with read -d $'\0'

    Instructions for use

    When processing file names or paths that contain spaces or special symbols (such as blanks, quotation marks, newlines), the traditionalfindDistribution linexargsorreadMisjudgment may occur.

    -print0Allowablefindwith null(\0) characters as output delimiters, whileread -d $'\0'Can accurately read null-delimited content to ensure accurate separation of each file/path.

    Basic example: collect all subdirectories

    subdirs=()
    while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done < <(find . -type d -print0)

    illustrate

    Example 1: List the absolute paths of all .txt files

    txt_files=()
    while IFS= read -r -d $'\0' file; do
        txt_files+=("$file")
    done < <(find "$(pwd)" -type f -name "*.txt" -print0)

    Example 2: Send files to a command for processing (security)

    find . -type f -print0 | while IFS= read -r -d $'\0' file; do
        echo "Processing: $file"
        # your_command "$file"
    done

    Example 3: Process only directories containing spaces

    find . -type d -print0 | while IFS= read -r -d $'\0' dir; do
        if [[ "$dir" == *" "* ]]; then
            echo "Directory containing spaces: $dir"
        fi
    done

    Why not use line breaks?

    Traditional usage is as follows:

    find . -type f | while read file; do ...

    However, if the file name contains a newline, it will causereadWrong parsing, even multiple lines are misjudged as multiple files.

    in conclusion



    While read only obtains one directory problem

    Problem description

    The following writing method is used in some Bash or Cygwin environments:Read only the first item

    while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)

    This is usually because `<(find ...)` 在某些系統(如 Cygwin)不是「真正的檔案描述符」,造成 `read` 無法持續讀取。

    Correction: Use pipeline with `read -d ''` (or `readarray -d`)

    Method 1: Use `find | while` pipeline combination-print0

    subdirs=()
    find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0 | while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done

    **Note**: If you want `subdirs` to be available in the main program, this method is not suitable (because `while ... |` subshell cannot return the array)

    Method 2: Change to array and process again

    mapfile -d '' -t subdirs < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)

    mapfile(orreadarray) can correctly read null-separated strings into arrays.
    This is the most reliable way to keep it in the main shell.

    Example output

    for dir in "${subdirs[@]}"; do
        echo "Found directory: $dir"
    done

    Summarize



    Read data from variable contents (use read)

    Assume that there are multiple lines of text in the variable

    var="line1
    line2
    line3"

    Use while read to read line by line

    while IFS= read -r line; do
        echo "Read: $line"
    done <<< "$var"

    Commentary

    Single line read

    read -r first_line <<< "$var"
    echo "First line: $first_line"

    read as array

    readarray -t lines <<< "$var"
    for line in "${lines[@]}"; do
        echo "$line"
    done


    Find the directory starting from the string and sort by date

    Complete instructions (sorted by directory modification time)

    find . -mindepth 1 -maxdepth 1 -type d -name "abc*" -printf "%T@ %p\n" | sort -nr | cut -d' ' -f2-

    illustrate

    Example output

    ./abc_latest
    ./abc_old
    ./abc_2020

    If you need to save it to a Bash array

    readarray -t abc_dirs << <(
      find . -mindepth 1 -maxdepth 1 -type d -name "abc*" -printf "%T@ %p\n" |
      sort -nr | cut -d' ' -f2-
    )
    
    for dir in "${abc_dirs[@]}"; do
      echo "Found: $dir"
    done

    Note



    Bash checks if storage device is writable

    Method 1: Check if the directory has write permissions

    DIR="/mnt/usb"
    
    if [ -w "$DIR" ]; then
        echo "$DIR is writable"
    else
        echo "$DIR is not writable"
    fi

    -wTo check whether the directory has "write permission". However, if the directory itself is writable but the actual device is read-only (for example, mount is readonly), this method may not work.

    Method 2: Actually try to write to the test file

    DIR="/mnt/usb"
    TESTFILE="$DIR/.write_test"
    
    if touch "$TESTFILE" 2>/dev/null; then
        echo "$DIR is writable"
        rm "$TESTFILE"
    else
        echo "$DIR is not writable"
    fi

    This method is the most reliable and can detect the mount status or whether the physical device is actually writable.

    Method 3: UsemountInstruction to check whether the mount is read-only

    MNT="/mnt/usb"
    
    if mount | grep "$MNT" | grep -q "(ro,"; then
        echo "$MNT is mounted read-only"
    else
        echo "$MNT is a writable mount"
    fi

    This method needs to check whether the device is read-only (ro) method.

    suggestion



    Shell redirection usage instructions

    1. Standard output redirection: `>`

    In the shell, use `>` to redirect a command's standard output (stdout) to a file or device. If the file already exists, the contents will be overwritten.

    echo "Hello" > output.txt

    This line of instruction will"Hello"writeoutput.txtfile.

    2. Add output redirection: `>>`

    Using `>>` will append standard output to the end of the specified file without overwriting the original content.

    echo "Hello again" >> output.txt

    This line of command will"Hello again"append tooutput.txtthe end of.

    3. Standard error redirection: `2>`

    In the shell, `2>` is used to redirect standard error (stderr) to a specified location. For example:

    ls non_existent_file 2> error.log

    This line of command will write the error message toerror.logfile.

    4. Add error redirection: `2>>`

    If you do not want to overwrite the error message file, you can use `2>>` to append the error message to the end of the file.

    ls non_existent_file 2>> error.log

    This line of command will append the error message toerror.log

    5. Redirect standard output and error at the same time: `&>`

    Use `&>` to redirect both standard output and standard error to the same file or device.

    command &> all_output.log

    This line of command willcommandAll output (standard output and error) is written toall_output.log

    6. Merge standard error to standard output: `2>&1`

    `2>&1` merges standard error into standard output to facilitate unified management. For example:

    command > output.log 2>&1

    This line of instruction will write to both standard output and erroroutput.log

    7. Disable all output: `>/dev/null 2>&1`

    If you don't want any output to be displayed, you can direct all output to/dev/null,like:

    command >/dev/null 2>&1

    This line of command willcommandAll output is discarded.



    Convert and output UTF-8 encoded files

    in useteeWhen the command appends output to a file, you can passiconvConvert the output to UTF-8 encoding, ensuring the file contents are saved in UTF-8. Below are specific instructions and examples.

    Command format

    The following saves the output as UTF-8 encodedteeInstruction format:

    command | iconv -t utf-8 | tee -a output.txt

    example

    The following example demonstrates how tolsThe output of the command is written in UTF-8 encoding tooutput.txt

    ls | iconv -t utf-8 | tee -a output.txt

    After executing this instruction,output.txtThe content will be saved in UTF-8 encoding to avoid encoding errors.



    Windows cmd

    Opening method

    Common commands

    Advanced operation

    Administrator mode



    Execute the second command after cmd /k

    Execute multiple commands in the same window

    Can be used&&&or||To continue the instructions:

    cmd /k "First command & Second command"

    Call other batch files

    After the first instruction addcall, you can continue to execute another batch file:

    cmd /k "First command & call second.bat"

    Use /c to close after executing

    If you don't need to keep the window open, you can use/c

    cmd /c "First command & Second command"

    /cwill automatically close the window after executing all commands, and/kThe window will be retained.



    CMD variable

    What are CMD variables?

    In the Windows Command Prompt (CMD), variables are namespaces used to store data or settings. They can be stored in the environment (environment variables) or defined and used in the batch file (regional variables).

    Variable type

    How to use variables

    Read variable value

    To get the value of a variable, you usually need to add percent signs before and after the variable name.%

    set NAME=CMD User
    echo My name is %NAME%

    Output:My name is CMD User

    Set regional variables in batch files

    @echo off
    set MESSAGE=This is a batch message
    echo%MESSAGE%
    pause

    Set a variable, but only if it does not exist

    You can useIF DEFINEDorIF NOT DEFINEDstatement to check whether the variable already exists or is defined (not empty).

    @echo off
    
    rem checks whether the variable MY_DEFAULT_VALUE is defined (not empty)
    IF NOT DEFINED MY_DEFAULT_VALUE (
        set MY_DEFAULT_VALUE=Default_Setting
        The echo variable MY_DEFAULT_VALUE is undefined and has been set to the default value.
    ) ELSE (
        echo variable MY_DEFAULT_VALUE already exists, the value is: %MY_DEFAULT_VALUE%
    )
    
    rem is executed once, the variable will be set to Default_Setting
    If rem is executed again, it will show that it already exists.
    
    set MY_DEFAULT_VALUE=Existing_Setting
    
    rem check again
    IF NOT DEFINED MY_DEFAULT_VALUE (
        set MY_DEFAULT_VALUE=Another_Default
        echo variable MY_DEFAULT_VALUE is undefined, set to Another_Default.
    ) ELSE (
        echo variable MY_DEFAULT_VALUE already exists, the value is: %MY_DEFAULT_VALUE%
    )
    
    pause

    Another neat trick is to take advantage of variable augmentation's default value functionality (but this is mainly used for loops and parameter processing, and in standardsetThe logic of "set if not set" is not directly applicable to the command. therefore,IF NOT DEFINEDThis is the most standard approach. )

    Enable delayed environment variable expansion (Delayed Expansion)

    In loops or conditional statements, standard percent sign variable expansion occurs once during statement parsing. In order to be able to read the new value of the variable on each iteration of the loop, you need to enable lazy expansion and use the exclamation mark!to reference variables.

    @echo off
    setlocal enabledelayeexpansion
    setCOUNTER=0
    :LOOP
        if %COUNTER% LSS 5 (
            set /A COUNTER+=1
            echo current count: !COUNTER!
            goto LOOP
        )
    endlocal

    Special variables/system variables

    variable describe
    %DATE% current date.
    %TIME% current time.
    %CD% The current directory path.
    %ERRORLEVEL% The end code of the previous command (usually 0 for success).
    %RANDOM% A random decimal number between 0 and 32767.
    %~dp0 The drive and path where the batch file is being executed.

    Advanced usage of parameter variables

    For parameter variables (such as%1) or a loop variable (such as%%A), you can use modifiers to extract different parts of the path:

    echo full path: %~1
    echo drive: %~d1
    echo path: %~p1
    echo file name: %~n1
    echo file extension: %~x1

    This is useful when working with archive paths.



    Filter keywords in CMD

    Use the find command

    example

    dir | find "txt" :: Only show files containing "txt"
    ipconfig | find "IPv4" :: Only show lines containing IPv4
    tasklist | find "chrome" :: Filter out executable programs containing chrome

    Common parameters

    Multiple keyword search

    type log.txt | find "Error" | find "2025"
    type log.txt | findstr /I "error warning fail"

    Advanced: use findstr

    dir | findstr /R ".*\.txt$" :: Use regular expressions to find .txt files
    type log.txt | findstr /I "timeout error fail"


    CMD automatically executes the setting method when starting

    Concept Note

    Method 1: Use AutoRun to log in values

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor
    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
    
    AutoRun = "C:\Users\YourName\cmd_startup.bat"

    Method 2: Modify CMD shortcut

    %SystemRoot%\System32\cmd.exe /k "C:\Users\YourName\cmd_startup.bat"

    Method 3: Use login to start the batch file

    %AppData%\Microsoft\Windows\Start Menu\Programs\Startup

    Correspondence instructions

    Linux bash Windows CMD corresponding method
    ~/.bash_profile or ~/.bashrc Login form AutoRun or CMD /k starts the batch file
    Automatically execute custom instructions Customized environment variables and path settings can be placed in the batch file


    Automatically set the batch file of CMD AutoRun

    Function description

    Sample batch file content

    @echo off
    setlocal
    
    :: Set the batch file path to be executed by AutoRun
    set "AUTORUN_PATH=C:\Users\%USERNAME%\cmd_startup.bat"
    set "REG_PATH=HKCU\Software\Microsoft\Command Processor"
    
    echo Check CMD AutoRun setting...
    
    :: Check whether the login code exists
    reg query "%REG_PATH%" >nul 2>&1
    if errorlevel 1 (
        echo [Information] The Command Processor code cannot be found, creating...
        reg add "%REG_PATH%" /f >nul
    )
    
    :: Check if AutoRun is set
    reg query "%REG_PATH%" /v AutoRun >nul 2>&1
    if errorlevel 1 (
        echo [Information] AutoRun not found, creating new value...
        reg add "%REG_PATH%" /v AutoRun /d "%AUTORUN_PATH%" /f >nul
        echo [Done] AutoRun has been set to: %AUTORUN_PATH%
    ) else (
        echo [OK] AutoRun already exists and has not been changed.
    )
    
    endlocal
    pause

    illustrate



    Determine batch file running terminal

    Sample batch file

    @echo off
    
    :: Detect PowerShell
    if defined PSModulePath (
        echo is currently executed in PowerShell
        goto :eof
    )
    
    :: Detecting Cygwin
    if defined CYGWIN (
        echo is currently executed in Cygwin
        goto :eof
    )
    if defined SHELL (
        echo is currently executed in Cygwin (SHELL=%SHELL%)
        goto :eof
    )
    
    ::Default is CMD
    echo is currently executed in CMD

    Judgment basis



    PowerShell

    Opening method

    Common commands

    Advanced operation

    Administrator mode



    List all variables in PowerShell

    command method

    example

    # List all variables
    Get-Variable
    
    # Show only variable names
    Get-Variable | Select-Object Name
    
    # Display the value of a specific variable
    Get-Variable PATH | Format-List *
    
    #Use variable driver method
    Get-ChildItem variable:

    illustrate



    C and C++ languages

    High efficiency

    static type system

    Resource control

    Grammatical flexibility

    Wide range of applications

    Cross-platform



    C/C++ preprocessor directives

    Overview

    Preprocessor Directives are commands executed by a program module called "Preprocessor" before the C or C++ program code is officially processed (compiled) by the compiler. These instructions are preceded by a pound sign (#) and not preceded by a semicolon (;) at the end.

    The role of the preprocessor is to perform text replacement, file inclusion, conditional compilation and other operations to generate the final "Translation Unit" for use by the compiler.

    Main command categories and examples

    1. File Inclusion

    Used to insert the contents of other files into the current file.

    #include <iostream> // Include the standard I/O library
    #include "my_utility.h" // Include custom header file

    2. Macro Definition and Substitution

    Literal replacement macro used to define symbolic constants or code fragments.

    #define MAX_SIZE 100 //Define a symbolic constant
    #define SUM(a, b) ((a) + (b)) // Define a macro with parameters
    
    int main() {
        int size = MAX_SIZE; // After preprocessing, it becomes int size = 100;
        int total = SUM(5, 3); // After preprocessing, it becomes int total = ((5) + (3));
        return 0;
    }

    3. Conditional Compilation

    Allows you to decide whether a specific block of code should be compiled based on the value of a preprocessor macro.

    #define DEBUG_MODE 1
    
    #if DEBUG_MODE
        std::cout << "Debug mode enabled" << std::endl;
    #else
        std::cout << "Production mode running" << std::endl;
    #endif
    
    #ifndef MY_HEADER_H
    #defineMY_HEADER_H
        // ... header file content (Include Guard example)
    #endif

    4. Error and Warning

    #ifndef VERSION_DEFINED
    #error "Must define version number macro VERSION_DEFINED!"
    #endif

    5. Other Directives



    #pragma once

    Definition and function

    #pragma onceIs one of the C and C++ languagesPreprocessor Directive. Its core function is to ensure that the header file containing this directive will only be processed by the compiler during a single compilation process.once

    The purpose of this directive is to solve the problem of repeated inclusion of header files and prevent the same piece of code (such as class definitions, function prototypes or constant declarations) from being seen multiple times by the compiler due to multiple source code files or multi-level header file inclusion relationships, thereby causingRedefinitioncompilation error.

    Comparison with Include Guard

    In the C/C++ standard, traditionally by usingInclude GuardTo achieve the purpose of preventing repeated inclusion.#pragma onceProvides a cleaner alternative.

    Include Guard (standard method)

    This is the standard and portable approach, using conditional compilation directives:

    #ifndef MY_HEADER_H
    #defineMY_HEADER_H
    
    // Header file content
    
    #endif // MY_HEADER_H

    It relies on a unique macro name (e.g.MY_HEADER_H) to control whether content is included.

    #pragma once (non-standard method)

    Use a single line directive:

    #pragma once
    
    // Header file content

    The compiler will automatically track whether it has already processed this file in the current compilation session, and if so, skip the remaining contents of the file.

    Advantages and Disadvantages

    Advantages of #pragma once:

    Disadvantages of #pragma once:

    in conclusion

    In modern development environments, especially when using Visual Studio or mainstream compilers,#pragma onceBecause of its simplicity and convenience, it prevents repeated inclusion of header files.Common and recommendedpractices.



    #pragma warning

    Definition and purpose

    #pragma warningare preprocessor directives in the C and C++ languages ​​that are used within specific blocks of code.Selectively suppress, restore, or modify the severity of compiler warnings

    The main purpose of this directive is to provide finer control than project-level settings. Use this command, for example, when you need to include an older version of a library that generates a lot of warnings, but don't want to turn off the warnings globally.

    Main operation syntax (MSVC format)

    Although#pragma warningThe specific implementation may vary slightly between different compilers (especially MSVC is the most widely used), but its core actions are divided into the following types:

    1. Disable warning (Disable)

    From this point on, the compiler ignores the specified warning code.

    #pragma warning( disable : 4996 ) // Disable C4996 (for example: warning about using unsafe functions)
    // Contain or write code that will generate C4996

    2. Recovery warning (Default)

    Restores the specified warning to the default behavior set by the project or command line.

    #pragma warning(default: 4996) //Restore C4996 to default state

    3. Save and restore status (Push and Pop)

    This is the safest and most recommended mode. It allows the warning settings to be modified while processing a specific block of code, and then ensures that the original warning state is restored immediately after the block ends to avoid side effects.

    #pragma warning( push ) // 1. Save the current warning settings
    #pragma warning( disable : 4996 4244 ) // 2. Disable multiple specific warnings
    // Contains third-party header files or legacy code
    #pragma warning( pop ) // 3. Restore to original settings
    // Subsequent code will use the restored settings

    4. Increase warning level (Error)

    Promote a specific warning code to a compilation error. If the warning occurs, compilation will fail.

    #pragma warning( error : 4005 ) // Treat warning 4005 as an error

    Things to note



    C++ standard namespace

    Overview

    In C++ programming,std::Refers to the Standard Namespace. It is a container that contains all standard entities in the C++ language core and its Standard Library (Standard Library), including functions, classes, templates, macros, and objects.

    usestd::The main purpose is to avoidName Collisions. If a standard function (e.g.coutorvector) are not placed in a separate namespace. When the user defines an entity with the same name, the compiler will not know which one to use.

    The main content of std::

    Most of the functionality of the C++ standard library is located instd::within the namespace. Main categories and features include:

    1. Input/output streams (I/O Streams)

    2. Standard Containers (Containers)

    Collection categories used to store data:

    3. Algorithms

    A set of common functions for container and range operations:

    4. Other core tools (Utilities)

    Using std::

    to accessstd::There are two main methods for entities in a namespace:

    1. Fully Qualified Names

    Write it clearly every time you use itstd::prefix. This is the safest and recommended approach, especially in header files, to avoid polluting the global namespace.

    
    int main() {
        std::cout << "Hello World" << std::endl;
        std::vector<int> numbers;
        return 0;
    }
    

    2. using declarations (using Directives)

    useusing namespace std;The entirestd::The contents of the namespace are introduced into the current scope, and the name can be used directly withoutstd::prefix.

    #include <iostream>
    using namespace std; // Introduce std:: namespace
    
    int main() {
        cout << "Hello World" << endl; // No std:: prefix required
        vector<int> numbers;
        return 0;
    }

    althoughusing namespace std;Convenient, but should be avoided in large projects or header files as it increases the risk of naming conflicts.



    std::string

    1. Declaration and initial value

    In C++,std::stringIs a category (Class). When you declare astd::stringWhen a variable is not given an initial value, it calls the Default Constructor.

    #include <string>
    #include <iostream>
    
    void initialization_example() {
        std::string s; // declared but no value given
        
        std::cout << "Length: " << s.length() << std::endl; // Output: 0
        std::cout << "Content: '" << s << "'" << std::endl; // Output: ''
    }

    2. How to check if it is empty (Empty)

    To check if a string does not contain any characters, the most recommended way is to useempty()member functions, which are better than checkinglength() == 0More semantic and more efficient in some containers.

    void check_empty(std::string s) {
        if (s.empty()) {
            std::cout << "This is an empty string." << std::endl;
        }
    }

    3. How to check if it is Null?

    This is a common misunderstanding:The std::string object itself is never null.

    In C++, only "pointers" can benullptr. If you are referring to checking whether a string has not been assigned a value, usually checking whether itempty(). If you are dealing with C-style string pointers (char*), you need to check for null.

    type Check method Remark
    std::string s; s.empty() Check if content length is 0
    std::string* ptr; ptr == nullptr Check if the "indicator" itself points to a gap
    char* c_str; c_str == nullptr Check if C-style string pointer is empty

    4. Method to clear string

    If you want to restore an existing string to its original empty state, you can use the following method:

    void clear_example() {
        std::string s = "Hello";
        
        s.clear(); // Method 1: Most commonly used
        s = ""; // Method 2: Reassign
        s = std::string(); // Method 3: Assign a default object
    }


    float to std::string

    1. Use std::to_string (the simplest method)

    This is the most straightforward method introduced in C++11, converting a numeric value into a string. By default, it retains 6 decimal places.

    #include <string>
    #include <iostream>
    
    void simple_convert() {
        float val = 3.14159f;
        std::string s = std::to_string(val);
        
        std::cout << s << std::endl; // Output example: "3.141590"
    }

    2. Use std::stringstream (custom precision)

    If you need to control the number of decimal places or a specific format,stringstreamIt is the most flexible option. it combines<iomanip>library to precisely control the output.

    #include <sstream>
    #include <iomanip>
    
    void precision_convert() {
        float val = 3.1415926f;
        std::stringstream ss;
        
        // Set fixed point counting method (fixed) and retain 2 decimal places
        ss << std::fixed << std::setprecision(2) << val;
        
        std::string s = ss.str();
        std::cout << s << std::endl; // Output: "3.14"
    }

    3. Use std::format (C++20 efficient method)

    In C++20, you can use format strings to handle type conversion and precision control at the same time, with the most concise syntax.

    #include <format>
    
    void modern_format() {
        float val = 123.456f;
        
        // {:.2f} represents float type and retains two decimal places
        std::string s = std::format("{:.2f}", val);
        
        std::cout << s << std::endl; // Output: "123.46" (will be automatically rounded)
    }

    4. Related processing usage: remove extra zeros at the end

    std::to_stringOften there are extra zeros like "3.140000". you can combinefind_last_not_ofanderaseto clean up the string.

    std::string remove_trailing_zeros(float val) {
        std::string s = std::to_string(val);
        
        // Remove trailing '0' until non-zero character is encountered
        s.erase(s.find_last_not_of('0') + 1, std::string::npos);
        
        // If the last character is a decimal point, also remove it
        if (s.back() == '.') {
            s.pop_back();
        }
        return s;
    }

    Conversion method comparison

    method Features Suggested scenarios
    std::to_string The syntax is the shortest and the performance is acceptable Quick debugging, when there are no requirements on the number of decimal places
    std::stringstream Highly customizable (zero padding, width, carry) When the output format needs to be strictly controlled
    std::format Type safety, performance, and modern syntax Preferred solution in C++20 environment
    sprintf (C style) Extremely fast but less safe Maintenance of old code with extreme pursuit of performance


    std::string delimiter parsing

    1. Use std::string::find loop analysis

    This is the most standard approach in C++ that does not rely on external libraries. throughfindFind the position of the delimiter and usesubstrRetrieve substring.

    #include <iostream>
    #include <vector>
    #include <string>
    
    void split_by_three_chars() {
        std::string text = "Apple---Banana---Cherry---Date";
        std::string delimiter = "---";
        std::vector<std::string> tokens;
        
        size_t pos = 0;
        size_t last_pos = 0;
    
        //Loop to find delimiter
        while ((pos = text.find(delimiter, last_pos)) != std::string::npos) {
            tokens.push_back(text.substr(last_pos, pos - last_pos));
            last_pos = pos + delimiter.length();
        }
        
        //Put in the last fragment
        tokens.push_back(text.substr(last_pos));
    
        //output result
        for (const auto& t : tokens) std::cout << "[" << t << "]" << std::endl;
    }

    2. Use std::string_view (C++17 performance optimization)

    If your string is very large, usestd::string_viewIt can avoid generating a large number of string copies during the splitting process, thereby greatly improving performance.

    
    #include <string_view>
    #include <vector>
    
    std::vector<std::string_view> split_sv(std::string_view str, std::string_view del) {
        std::vector<std::string_view> output;
        size_t first = 0;
    
        while (first < str.size()) {
            const auto second = str.find(del, first);
            if (second == std::string_view::npos) {
                output.emplace_back(str.substr(first));
                break;
            }
            output.emplace_back(str.substr(first, second - first));
            first = second + del.size();
        }
        return output;
    }
    

    3. Use Regex regular expressions

    If you want your code to look more concise, or if the separators may change, you can usestd::regex. But note that the execution performance of regular expressions is usually better than that of manualfindslow.

    #include <regex>
    
    void regex_split() {
        std::string text = "One###Two###Three";
        std::regex ws_re("###"); // Define 3 character separator
        
        std::copy(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
                  std::sregex_token_iterator(),
                  std::ostream_iterator<std::string>(std::cout, "\n"));
    }

    Comparison of analytical methods

    method advantage shortcoming
    std::find + substr Highest compatibility (C++98+) and stable performance. The code is lengthy and requires manual processing of the last fragment.
    string_view Most effective, no additional memory copy is generated. Requires C++17 support, and attention must be paid to the original string life cycle.
    std::regex The syntax is the most concise and extensible. The execution speed is the slowest and the compilation time is longer.


    Check if std::vector is empty

    Overview

    In C++, to checkstd::vectorIf the container contains no elements (i.e. has size zero), the most standard and recommended way is to use its member functionsempty(). This is becauseempty()Functions are usually better than direct checkssize()Is equal to zero more efficient, especially in some container implementations.

    Check method

    1. Use empty() function (recommended)

    This is the preferred way to check if a vector is empty. It returns a Boolean value: if vector has no elements, it returnstrue; Otherwise returnfalse

    #include <vector>
    #include <iostream>
    #include <string>
    
    void check_empty(const std::vector<std::string>& vec)
    {
        if (vec.empty()) {
            std::cout << "Vector is empty (empty() == true)." << std::endl;
        } else {
            std::cout << "Vector is not empty (empty() == false). Number of elements: " << vec.size() << std::endl;
        }
    }
    
    int main()
    {
        std::vector<std::string> empty_vec;
        std::vector<std::string> non_empty_vec = {"apple", "banana"};
    
        check_empty(empty_vec);
        check_empty(non_empty_vec);
    
        return 0;
    }

    2. Check the size() function

    While valid, this is not the most idiomatic or potentially most efficient way of checking for empty state. It directly checks whether the number of elements in the vector is zero.

    void check_size(const std::vector<int>& vec)
    {
        if (vec.size() == 0) {
            std::cout << "Vector is empty (size() == 0)." << std::endl;
        } else {
            std::cout << "Vector is not empty (size() != 0)." << std::endl;
        }
    }

    Efficiency considerations

    forstd::vectorIn terms ofempty()andsize() == 0The time complexity is $O(1)$ because vector stores its size as a member variable. However, for some other C++ standard containers (e.g.std::listorstd::forward_list), the standard recommendation is always to useempty(), because it is generally the most common and fastest idiom in the C++ standard container library for checking for empty status.



    C++ parsing string into string vector

    Overview

    In C++, a character containing a space (Space) or Tab character (\t) separated string is parsed into individual words or tokens and stored instd::vector<std::string>, the most common method is to use **std::stringstream**. File streaming categorystd::stringstreamLike an in-memory stream, it defaults to using whitespace characters (including spaces, tabs, and newlines) as delimiters for reading operations.

    Code example

    The following is usedstd::stringstreamExample of C++ code that accomplishes this task:

    #include <iostream>
    #include <sstream> // include stringstream
    #include <string>
    #include <vector>
    
    using namespace std;
    
    /**
     * Separate the input string by any whitespace characters (space or Tab) and store it in the vector.
     * @param input_str The string to be parsed.
     * @return A vector containing all separated words.
     */
    vector<string> split_string_by_whitespace(const string& input_str)
    {
        vector<string> tokens;
        
        // 1. Create a stringstream object and initialize it with the input string
        stringstream ss(input_str);
        
        string token;
        
        // 2. Loop reading
        // The stream extraction operator (>>) will automatically read the next token using whitespace characters (space, Tab, etc.) as delimiters.
        // The operator returns true when a token is successfully read, otherwise (the end of the string is reached) it returns false.
        while (ss >> token)
        {
            tokens.push_back(token);
        }
        
        return tokens;
    }
    
    int main()
    {
        //The input string contains multiple spaces and tab symbols (\t)
        string test_string = "Hello \tWorld this is \ta test string";
        
        cout << "Original string: " << test_string << endl;
        
        vector<string> result = split_string_by_whitespace(test_string);
        
        cout << "--- separate results ---" << endl;
        
        for (size_t i = 0; i < result.size(); ++i)
        {
            cout << "Token " << i + 1 << ": [" << result[i] << "]" << endl;
        }
        
        return 0;
    }

    Key mechanism explanation



    .NET and std str transcoding garbled characters

    reason

    In C++/CLI,gcnew System::String(stdStr.c_str())willstd::string(usuallyANSI / UTF-8encoding) directly into .NETSystem::String,andSystem::StringThe expectation isUTF-16
    ifstdStrIf it contains non-ASCII characters (such as Chinese), garbled characters will appear.

    Solution 1: Usemarshal_as(suggestion)

    Namespace needs to be quoted:

    #include <msclr/marshal_cppstd.h>
    using namespace msclr::interop;
    
    std::string stdStr = "Chinese test";
    System::String^ netStr = marshal_as<System::String^>(stdStr);

    ✅ This method can automatically convert UTF-8 / ANSI to .NET Unicode correctly.

    ---

    Solution 2: If you are sure that std::string is UTF-8, you can manually convert it

    #include <codecvt>
    #include <locale>
    
    std::string utf8Str = u8"Chinese test";
    std::wstring wideStr = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>{}.from_bytes(utf8Str);
    System::String^ netStr = gcnew System::String(wideStr.c_str());
    ---

    Solution 3: If the source isstd::wstring

    If the C++ side originally uses wide character strings, just use it directly:

    std::wstring wstr = L"Chinese test";
    System::String^ netStr = gcnew System::String(wstr.c_str());
    ---

    suggestion



    C++ multidimensional array initialized to 0

    Initialized using std::array

    In C++, you can usestd::arrayInitialize a multidimensional array to 0:

    #include <iostream>
    #include <array>
    using namespace std;
    
    int main() {
        array<array<int, 4>, 3> arr = {0}; // Initialize all elements to 0
    
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                cout << arr[i][j] << " ";
            }
            cout << endl;
        }
        return 0;
    }

    Things to note



    C++ std array loop method

    Overview

    In C++, looping is the basic operation of iterating over all elements in a container or array.std::vector(dynamically sized container) andstd::array(fixed-size containers) are containers in the C++ Standard Library (STL) whose elements can be iterated over in a variety of standard and safe ways.

    1. Range-based for loop

    This is the most modern, safest, and most concise traversal method introduced in C++11. It works with all standard containers (includingstd::vectorandstd::array)。

    applicability:

    #include <iostream>
    #include <vector>
    #include <array>
    
    void range_based_loop_example()
    {
        std::vector<int> vec = {10, 20, 30};
        std::array<int, 4> arr = {1, 2, 3, 4};
        
        // Use auto& to traverse by reference, which is efficient and allows modification of elements
        std::cout << "--- Vector (modifiable) ---" << std::endl;
        for (auto& element : vec) {
            element += 1; // Modify element
            std::cout << element << " ";
        }
        std::cout << std::endl;
        
        // Use const auto& to traverse by constant reference, which is safe and does not allow modification of elements
        std::cout << "--- Array (read only) ---" << std::endl;
        for (const auto& element : arr) {
            std::cout << element << " ";
        }
        std::cout << std::endl;
    }

    2. Index-based for loop

    This is a traditional and universal method. Suitable for situations where you need to access element indexes (for example: you need to operate two containers or arrays at the same time, or terminate at a specific index).

    applicability:

    #include <iostream>
    #include <vector>
    #include <array>
    
    void index_loop_example()
    {
        std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
        std::array<double, 3> prices = {10.5, 20.99, 5.0};
        
        // Use size_t or auto with size() to ensure the index type is correct and the bounds are safe
        for (size_t i = 0; i < names.size(); ++i) {
            // Use operator[] to access elements
            std::cout << "Name: " << names[i] << ", Price: " << prices[i] << std::endl;
        }
    }

    NOTE: Use[]C++ does not perform bounds checking when operators access elements. If bounds checking is required, useat()function (it will throw when out of boundsstd::out_of_rangeabnormal).

    3. Iterator loop

    This is the most flexible traversal method in C++ and works with all standard containers. Iterators are necessary when interacting with C++ Standard Library (STL) algorithms.

    applicability:

    #include <iostream>
    #include <vector>
    
    void iterator_loop_example()
    {
        std::vector<double> values = {100.0, 50.0, 10.0};
        
        // Simplify the iterator type using auto and use begin() and end() to get the range
        for (auto it = values.begin();
             it != values.end();
             ++it)
        {
            *it /= 10.0; // *it dereferences the iterator and accesses elements
            std::cout << *it << " ";
        }
        std::cout << std::endl;
        
        // Use cbegin() and cend() to ensure the iterator is const for read-only traversal
        for (auto cit = values.cbegin(); cit != values.cend(); ++cit)
        {
            // Trying *cit = 5; will result in a compilation error
            std::cout << *cit << " ";
        }
        std::cout << std::endl;
    }

    Summary and recommendations

    loop method Applicable containers advantage Applicable time
    Range-based std::vector, std::array, all standard containers The cleanest, safest, modern C++ idiom. No index is needed, only each element needs to be traversed.
    Index-based std::vector, std::array Indexes can be accessed and have high versatility. When you need to know or manipulate the index of an element.
    Iterator All standard containers Extremely flexible and can be used with STL algorithms such asstd::find) fits perfectly. When you need to use STL algorithms or perform complex operations on containers.


    Method for copying the contents of a multidimensional std::array

    problem situation

    std::array<std::array<std::array<float, 2>, 2>, 2> twoLines;
    std::array<std::array<std::array<float, 2>, 2>, 2> twoLinesCopy;
    

    Solution 1: Directly specify (= operator)

    std::arraySupports complete copying from shallow to deep levels, so it can be used directly=

    twoLinesCopy = twoLines;
    

    Solution 2: Use std::copy

    std::copy(twoLines.begin(), twoLines.end(), twoLinesCopy.begin());
    

    Solution 3: Use std::memcpy (suitable for POD type, float is applicable here)

    std::memcpy(&twoLinesCopy, &twoLines, sizeof(twoLines));
    

    suggestion



    C++ capture indicator memory access error

    Overview

    In C++, this happens when you access an invalid or out-of-bounds memory location when you manipulate pointers or use indexes to access arrays/memory.Undefined Behavior. This behavior usually manifests itself as a programCrash, such as a Segmentation Fault or Access Violation error.

    C++ standardtry-catchThe mechanism is mainly used to catch C++ exceptions (Exceptions) that are explicitly thrown in the program code, but cannot directly catch hardware or memory access errors issued by the operating system.

    Why can't try-catch catch memory access errors?

    When a C++ program attempts to access invalid memory, for example:

    1. Out-of-Bounds Access:Access memory after the end of the array.
    2. Dereferencing a Null Pointer:An attempt was made to read or write at addressnullptrof memory.
    3. Use After Free:Access passeddeleteorfreeFreed memory.

    These operations will trigger the protection mechanism of the underlying operating system (such as Access Violation on Windows or SIGSEGV signal on Unix/Linux), and the program will be terminated by the operating system. These errors are not C++ language-level exception objects (such asstd::exception), so the standardtry-catchThere is no way to capture them.

    Error example (standard try-catch does not work)

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    void crash_function()
    {
        // Array out-of-bounds access example
        vector<int> vec = {10, 20};
        cout << "Attempt to access out-of-bounds index..." << endl;
        
        // This is undefined behavior and is likely to lead to an access violation crash
        int value = vec[100]; // Error: Accessing invalid index
        cout << "value: " << value << endl;
    }
    
    int main()
    {
        try
        {
            crash_function();
            //The program will crash at vec[100] above and will not be executed here.
            // And the catch block will not be executed.
        }
        catch (const exception& e)
        {
            // Operating system level errors cannot be captured here
            cerr << "Caught C++ exception: " << e.what() << endl;
        }
        catch(...)
        {
            // Still unable to catch memory access errors
            cerr << "Unknown exception caught" << endl;
        }
    
        return 0;
    }

    How to deal with this kind of error?

    1. Use safe C++ mechanisms (preferred)

    The best approach is to prevent such errors from happening during the design phase of your code rather than trying to catch them:

    void safe_function()
    {
        vector<int> vec = {10, 20};
        try
        {
            int value = vec.at(100); // throw std::out_of_range exception
            cout << "value: " << value << endl;
        }
        catch (const std::out_of_range& e)
        {
            // Successfully caught C++ exception
            cerr << "Safe capture: " << e.what() << endl;
        }
    }

    2. Use platform-specific Structured Exception Handling (SEH)

    In a Windows environment, you can use Microsoft's extended Structured Exception Handling (SEH) to catch operating system-level errors, including Access Violations. This is usually done using__tryand__exceptKeywords.

    Note: SEH is non-standard and not recommended for use in portable C++ code. In C++/CLI projects, you can use .NET'stry/catchCatch some SEH exceptions, but this requires specific compiler settings (e.g./EHa)。



    C++ catching array index memory access error

    Overview

    In C++, when you use a raw array (C-style array) or pointer for indexing operations, it occurs if a memory location that is outside the range of the array or is invalid is accessed.Undefined Behavior. This behavior often results in programs running at the operating system levelCrash, such as Access Violation or Segmentation Fault.

    The key points are:C++ standardtry-catchThe mechanism is designed to catch C++ exceptions (Exceptions) that are explicitly thrown in the program code. It cannot catch hardware or memory protection errors issued by the operating system.

    Why doesn't standard try-catch work?

    When a C++ program attempts to access invalid memory (for example, accessing a static arrayarr[100], but the array only has 10 elements), which violates the operating system's memory protection rules. The operating system steps in and sends a signal or exception to terminate the program, preventing it from damaging the system or other programs. These errors are not C++ language levelstd::exceptionobject and therefore cannot be used by the standardtry-catchBlock capture.

    Error demonstration (standard try-catch cannot catch crashes)

    #include <iostream>
    #include <stdexcept> // Include standard exceptions
    
    using namespace std;
    
    void crash_function()
    {
        // C-style primitive array
        int raw_array[5] = {1, 2, 3, 4, 5};
        cout << "Attempt to access out-of-bounds index..." << endl;
        
        // Array out-of-bounds access: This is a typical undefined behavior
        // If a memory that the program does not have permission to access is accessed, an access violation will be triggered immediately, causing the program to crash.
        int value = raw_array[100]; // Error: Accessing invalid index
        cout << "Value (if reachable): " << value << endl;
    }
    
    int main()
    {
        try
        {
            crash_function();
            // The program will terminate at raw_array[100] and will not be executed here.
        }
        catch (const exception& e)
        {
            // Operating system level memory access errors cannot be captured here
            cerr << "Caught C++ exception: " << e.what() << endl;
        }
    
        return 0;
    }

    Correct handling and prevention methods (preferred)

    The best practice is to avoid out-of-bounds accesses entirely, or to use the safe containers and methods provided by C++, which throw catchable C++ exceptions when an error occurs:

    1. Use std::vector::at()

    forstd::vectorcontainer, useat()member function instead of original[]operator. When access goes out of bounds,at()will throw **std::out_of_range**Exception, this is a standard C++ exception and can betry-catchCaught and disposed of safely.

    #include <vector>
    // ... (other include)
    
    void safe_vector_access()
    {
        std::vector<int> vec = {10, 20};
        try
        {
            // Use at() for bounds checking
            int value = vec.at(100);
            std::cout << "value: " << value << std::endl;
        }
        catch (const std::out_of_range& e)
        {
            // Successfully caught C++ exception
            std::cerr << "Safely caught out-of-bounds exception: " << e.what() << std::endl;
        }
    }

    2. Avoid using raw arrays and use std::array instead

    Introduced using C++11std::arrayReplaces C-style arrays. Althoughstd::arrayof[]The operator is not checked, but itsat()The function will also throwstd::out_of_rangeabnormal.

    #include <array>
    // ...
    
    void safe_array_access()
    {
        std::array<int, 5> arr = {1, 2, 3, 4, 5};
        try
        {
            int value = arr.at(5); // Access out of bounds, throw exception
        }
        catch (const std::out_of_range& e)
        {
            std::cerr << "std::array out-of-bounds capture: " << e.what() << std::endl;
        }
    }

    Platform-specific structured exception handling (advanced/non-standard)

    On certain platforms such as Windows, you can use **Structured Exception Handling (SEH)** to catch hardware exceptions (such as access violations) issued by the operating system. This usually involves using a Microsoft extension__tryand__exceptKeywords. This method is platform non-standard, sacrifices code portability, and is generally not recommended as a routine error handling mechanism.



    .NET List

    Basic introduction

    In .NET (languages ​​like C++/CLI, C#, VB.NET, etc.),List<T>is a generic collection category, Can store any type of data (T) and provide dynamic resizing function. it belongs toSystem::Collections::Genericnamespace.

    Declaration and initialization

    //Import namespace
    using namespace System;
    using namespace System::Collections::Generic;
    
    int main()
    {
        // Declare a List to store int
        List<int>^ numbers = gcnew List<int>();
    
        //Add elements directly during initialization
        List<String^>^ names = gcnew List<String^>({ "Alice", "Bob", "Charlie" });
    }

    Add, remove and access elements

    List<int>^ nums = gcnew List<int>();
    
    //Add new element
    nums->Add(10);
    nums->Add(20);
    nums->Add(30);
    
    //Insert at specified position
    nums->Insert(1, 15); // Insert 15 at index 1
    
    //Remove specified value
    nums->Remove(20);
    
    //Remove the specified index
    nums->RemoveAt(0);
    
    // Get elements
    int value = nums[1]; // Get the element at index 1
    
    // Check if it contains
    if (nums->Contains(30))
        Console::WriteLine("Found 30");
    
    // Clear all elements
    nums->Clear();

    Traverse List

    // for loop
    for (int i = 0; i < nums->Count; i++)
    {
        Console::WriteLine("{0}th element: {1}", i, nums[i]);
    }
    
    // for each loop
    for each (int n in nums)
    {
        Console::WriteLine(n);
    }

    Common properties and methods

    Properties/Methodsillustrate
    CountCurrent number of elements
    CapacityInternal capacity (can grow automatically)
    Add(item)add an element
    AddRange(collection)Join all elements of another collection
    Insert(index, item)Insert element at specified position
    Remove(item)Removes the specified value (first match found)
    RemoveAt(index)Remove element at specified index
    Clear()Remove all elements
    Contains(item)Check if the specified value is contained
    IndexOf(item)Returns the index of the element (-1 if it does not exist)
    Sort()Sorting elements (for comparable types)
    Reverse()Reverse the order of elements

    Example output

    10
    15
    30
    


    C++/CLI List access out of range

    1. What happens when an index goes out of range?

    in C++/CLISystem::Collections::Generic::List<T>, if you try to access an index that doesn't exist (e.g.sizeis 1 but accessindex1), programWon'tGiven a default value (such as 0 or null), an exception will be thrown immediately.


    2. Safe access practices

    Before making an index access, you should always checkCountattribute, or usetry-catchBlocks capture potential errors.

    //Method A: Pre-inspection (most recommended, best performance)
    if (nums->Count > 1) {
        int value = nums[1];
        // Processing logic
    } else {
        // Handle insufficient index situation
    }
    
    //Method B: Exception catching
    try {
        int value = nums[1];
    } catch (System::ArgumentOutOfRangeException^ ex) {
        System::Diagnostics::Debug::WriteLine("Index out of range!");
    }

    3. Performance in different situations

    context result Remark
    Index exists (e.g., Count=5, index=1) Return the correct value normal operation.
    Index does not exist (e.g., Count=1, index=1) throws ArgumentOutOfRangeException The program will interrupt execution.
    Native C++ array/std::vector [ ] Undefined Behavior You may get garbled code or crash, but will not actively throw .NET exceptions.

    4. Summary of preventive measures



    C++ std maximum and minimum values

    1. C++ standard library functions: std::min and std::max

    In C++, the most commonly used tools are defined in<algorithm>instd::minandstd::max. They support basic types, objects, and even initialization lists.

    #include <algorithm>
    #include <iostream>
    #include <vector>
    
    void basic_usage() {
        int a = 10, b = 20;
    
        // 1. Compare two numbers
        int small = std::min(a, b);
        int large = std::max(a, b);
    
        // 2. Compare initialization lists (C++11)
        int lowest = std::min({5, 1, 9, 3}); // return 1
    
        // 3. std::minmax (C++11) - get the maximum and minimum values at the same time
        auto result = std::minmax({10, 20, 30, 40});
        std::cout << "Min: " << result.first << ", Max: " << result.second;
    }

    2. Numeric limits: FLT_MAX and std::numeric_limits

    When you need to initialize a "minimum" variable, you usually set it to the largest positive number that the type can express, to ensure that it will be updated on the first comparison.

    C-style limits (from <cfloat> and <climits>)

    C++ style limits (recommended to use <limits>)

    std::numeric_limitsProvides a consistent and templated way to obtain numeric properties, which is very useful when writing generic code.

    #include <limits>
    
    void limits_example() {
        // Get the maximum value
        float max_f = std::numeric_limits<float>::max();
        int max_i = std::numeric_limits<int>::max();
    
        // Get the "minimum positive number" (note: for floating point numbers, min() returns the minimum positive number instead of the maximum negative number)
        float min_positive_f = std::numeric_limits<float>::min();
    
        // Get the "lowest value" (the real smallest negative number)
        float lowest_f = std::numeric_limits<float>::lowest();
    }

    3. The maximum and minimum values ​​in the collection: std::min_element

    If you are dealing withstd::vectoror array, you need to usestd::min_elementorstd::max_element, what they return isIterator

    #include <vector>
    #include <algorithm>
    
    void collection_example() {
        std::vector<float> scores = {88.5f, 92.0f, 79.5f, 100.0f};
    
        // Get the iterator of the maximum value
        auto it = std::max_element(scores.begin(), scores.end());
    
        if (it != scores.end()) {
            std::cout << "Highest score: " << *it;
        }
    }

    4. Key Differences and Pitfalls

    name use Things to note
    FLT_MAX Initialize minimum value search defined in<cfloat>, is a legacy macro from C.
    std::min Compare two numbers or lists If the parameter types are inconsistent (such as int and long), the template needs to be specified explicitly:std::min<long>(a, b)
    lowest() Get the smallest negative number In floating point numbers,min()is the smallest positive number close to 0,lowest()is the maximum negative value.
    min_element search container What is returned is an iterator, and you need to check whether the container is empty before using it.


    C++ std gets pi

    Overview

    In the C++ standard math library, although the constant definition of $\pi$ was not officially standardized until C++20, there are several commonly used methods to obtain approximate values ​​of pi in different C++ versions and compiler environments.

    To ensure code portability and accuracy, the most recommended approach is to use thestd::numbers::pi

    1. Use C++20 standard constants (recommended)

    Starting with C++20, the standard library is<numbers>Precise and type-safe mathematical constants are provided in the header file.

    Header file:

    How to use:

    #include <iostream>
    #include <numbers> // introduced in C++20
    
    void use_cpp20_pi()
    {
        // std::numbers::pi_v<T> is a template variable that provides an exact value based on type T
        // std::numbers::pi (without <T>) is equivalent to std::numbers::pi_v<double>
        
        double pi_double = std::numbers::pi;
        float pi_float = std::numbers::pi_v<float>;
        long double pi_long_double = std::numbers::pi_v<long double>;
    
        std::cout.precision(16); // Set output precision
        std::cout << "C++20 (double): " << pi_double << std::endl;
        std::cout << "C++20 (float): " << pi_float << std::endl;
    }

    2. Use macros of traditional C language (C++17 and before)

    Before C++20, many developers relied on the C math library (<cmath>or<math.h>) provides a non-standard macro. Although these macros exist on most modern systems, they are not part of the C++ standard and are not guaranteed to work in all environments.

    Header file:

    How to use:

    #include <iostream>
    #include <cmath> // Traditional C math library
    
    void use_c_macro_pi()
    {
        // M_PI is the most common PI macro, usually defined as double type.
        // Note: To enable this macro, the _USE_MATH_DEFINES macro may need to be defined on some systems.
        
        #ifdef M_PI
            double pi_value = M_PI;
            std::cout.precision(16);
            std::cout << "C Macro (M_PI): " << pi_value << std::endl;
        #else
            std::cout << "The M_PI macro is undefined. You may need to define _USE_MATH_DEFINES." << std::endl;
        #endif
    }

    3. Calculate or define by yourself

    If you cannot use C++20 or C macros, you can define $\pi$ yourself as a constant, or use a mathematical function to calculate it (e.g. $\arccos(-1)$).

    How to use:

    #include <iostream>
    #include <cmath>
    
    void define_or_calculate_pi()
    {
        // Define through mathematical operations:
        const double PI_CUSTOM_CALC = std::acos(-1.0);
        
        // Define it directly as a constant:
        const double PI_CUSTOM_DEFINE = 3.14159265358979323846;
    
        std::cout.precision(16);
        std::cout << "Custom Calculate: " << PI_CUSTOM_CALC << std::endl;
        std::cout << "Custom Define: " << PI_CUSTOM_DEFINE << std::endl;
    }

    Recommended summary



    Calculate the standard deviation of a List

    Sample program

    #include <cmath>
    #include <iostream>
    using namespace System;
    using namespace System::Collections::Generic;
    
    int main()
    {
        //Create test data
        Dictionary<int, List<float>^>^ data = gcnew Dictionary<int, List<float>^>();
        data->Add(1, gcnew List<float>({ 1.2f, 2.3f, 3.4f }));
        data->Add(2, gcnew List<float>({ 4.5f, 5.5f, 6.5f, 7.5f }));
        data->Add(3, gcnew List<float>()); // Test the empty list
    
        // Calculate the standard deviation of each key
        for each (KeyValuePair<int, List<float>^> entry in data)
        {
            int key = entry.Key;
            List<float>^ values = entry.Value;
    
            if (values == nullptr || values->Count == 0)
            {
                Console::WriteLine("Key {0}: No data", key);
                continue;
            }
    
            // Calculate the average
            double sum = 0.0;
            for each (float v in values)
            {
                sum += v;
            }
            double mean = sum / values->Count;
    
            // Calculate the number of mutations (number of maternal mutations)
            double variance = 0.0;
            for each (float v in values)
            {
                double diff = v - mean;
                variance += diff * diff;
            }
            variance /= values->Count; // If you want the sample variation, change to (values->Count - 1)
    
            // standard deviation
            double stddev = Math::Sqrt(variance);
    
            Console::WriteLine("Key {0}: standard deviation = {1:F4}", key, stddev);
        }
    
        return 0;
    }

    illustrate

    Output example

    Key 1: Standard deviation = 0.8981
    Key 2: Standard deviation = 1.1180
    Key 3: No information


    .NET Dictionary

    Basic introduction

    In .NET (languages ​​like C++/CLI, C#, VB.NET, etc.),Dictionary<TKey, TValue>is a generic collection, Used to store "key-value pairs". Each key must be unique, and the value must be repeatable. it belongs toSystem::Collections::Genericnamespace.

    Declaration and initialization

    //Import namespace
    using namespace System;
    using namespace System::Collections::Generic;
    
    int main()
    {
        //Create a Dictionary with Key as int and Value as String
        Dictionary<int, String^>^ users = gcnew Dictionary<int, String^>();
    
        // Direct initialization
        users->Add(1, "Alice");
        users->Add(2, "Bob");
        users->Add(3, "Charlie");
    
        return 0;
    }

    Add, modify, delete and access elements

    Dictionary<String^, int>^ ages = gcnew Dictionary<String^, int>();
    
    //Add new element
    ages->Add("Tom", 25);
    ages->Add("Jerry", 30);
    
    //Modify value (via indexer)
    ages["Tom"] = 26;
    
    // Add or modify (if key does not exist, it will be added automatically)
    ages["Spike"] = 40;
    
    // delete element
    ages->Remove("Jerry");
    
    //Access elements
    if (ages->ContainsKey("Tom"))
    {
        Console::WriteLine("Tom's age is {0}", ages["Tom"]);
    }
    
    // Try to get the value (avoid exceptions)
    int age;
    if (ages->TryGetValue("Spike", age))
    {
        Console::WriteLine("Spike's age is {0}", age);
    }

    Traverse Dictionary

    Dictionary<int, String^>^ users = gcnew Dictionary<int, String^>();
    users->Add(1, "Alice");
    users->Add(2, "Bob");
    users->Add(3, "Charlie");
    
    // Use KeyValuePair loop
    for each (KeyValuePair<int, String^> entry in users)
    {
        Console::WriteLine("Key = {0}, Value = {1}", entry.Key, entry.Value);
    }
    
    //Get only Keys
    for each (int key in users->Keys)
    {
        Console::WriteLine("Key: {0}", key);
    }
    
    //Get only Values
    for each (String^ name in users->Values)
    {
        Console::WriteLine("Name: {0}", name);
    }

    Common properties and methods

    Properties/Methodsillustrate
    Add(key, value)Add a new set of key-value pairs
    Remove(key)Removes the specified key and its corresponding value
    Clear()Clear all projects
    ContainsKey(key)Check if the specified key exists
    ContainsValue(value)Check if the specified value exists
    TryGetValue(key, out value)Get the value safely without throwing an exception
    CountThe current number of elements in the dictionary
    KeysReturns a collection of all keys
    ValuesReturns a collection of all values

    Example output

    Key = 1, Value = Alice
    Key = 2, Value = Bob
    Key = 3, Value = Charlie
    Tom's age is 26
    Spike's age is 40


    std::sort

    1. Basic usage

    std::sortIs the most commonly used sorting algorithm in the C++ Standard Template Library (STL). it is located<algorithm>In the header file, by default, elements within the range will beAscendingto sort.

    #include <algorithm>
    #include <vector>
    #include <iostream>
    
    void basic_sort() {
        std::vector<int> nums = {5, 2, 9, 1, 5, 6};
        
        // Sorting range: from start iterator to end iterator
        std::sort(nums.begin(), nums.end());
        
        // Result: 1, 2, 5, 5, 6, 9
    }

    2. Custom sorting criteria (descending power or specific conditions)

    You can change the sorting logic by passing in the third parameter (comparison function or lambda expression).

    // 1. Use predefined std::greater for exponentiation
    std::sort(nums.begin(), nums.end(), std::greater<int>());
    
    // 2. Use Lambda expressions to customize logic
    std::sort(nums.begin(), nums.end(), [](int a, int b) {
        return a > b; // When true is returned, a will be ranked in front of b
    });

    3. Structure or category sorting

    For custom types, comparison logic must be provided, otherwise the compiler will report an error because it does not know how to compare sizes.

    struct Student {
        std::string name;
        int score;
    };
    
    void sort_students() {
        std::vector<Student> students = {{"Alice", 90}, {"Bob", 85}, {"Charlie", 95}};
        
        // Sort by score from high to low
        std::sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
            return a.score > b.score;
        });
    }

    4. Underlying principle: Introspective sorting (Introsort)

    std::sortNot a single sorting algorithm, but a hybrid algorithm designed to combine the advantages of each algorithm and avoid the worst-case scenario. Its operating logic is as follows:


    Summary of performance and features

    characteristic illustrate
    average time complexity $O(n \log n)$
    Worst time complexity $O(n \log n)$ (Benefit from the Introsort mechanism)
    space complexity $O(\log n)$ (recursive call stacking)
    Stability unstable(The relative positions of equal elements may change). If you need stable sorting, please usestd::stable_sort


    C++ template

    1. What is a template?

    In C++, template is a generic programming tool that allows us to write functions or categories without specifying specific data types, thereby making the code more reusable. Templates help handle different types of data in a single code, avoiding duplicate function or class definitions.

    2. Function Template

    Function templates allow us to write functions that can handle different types. The syntax of function template is as follows:

    template <typename T>
    T add(T a, T b) {
        return a + b;
    }

    In this example,addThe function can handle any type that supports addition operations, such asintfloatordouble

    When using it, you can call it like this:

    int result = add(3, 4); // use int type
    double result2 = add(3.5, 2.7); // use double type

    3. Class Template

    Category templates allow us to create categories that can be applied to multiple types. The syntax of a category template is as follows:

    template <typename T>
    class MyClass {
    private:
        T data;
    public:
        MyClass(T data) : data(data) {}
        T getData() { return data; }
    };

    In this exampleMyClassCategories can use any type of data asdata

    You can use it like this:

    MyClass<int> obj1(5); // int type
    MyClass<double> obj2(3.14); // double type

    4. Multiple template parameters

    Templates can accept multiple parameters, for example:

    template <typename T, typename U>
    class Pair {
    private:
        T first;
        U second;
    public:
        Pair(T first, U second) : first(first), second(second) {}
        T getFirst() { return first; }
        U getSecond() { return second; }
    };

    Such a template class can store two different types of data:

    Pair<int, double> pair1(1, 3.14);

    5. Template Specialization

    Template specialization allows us to specifically define templates of specific types. For example:

    template <>
    class MyClass<int> {
    public:
        MyClass(int data) { /* Specialized behavior */ }
    };

    This code is specializedMyClassrightintThe behavior of a type that makes it different from other types.

    6. Non-Type Template Parameters

    Templates can also accept non-type parameters, such as constant values:

    template <typename T, int Size>
    class Array {
    private:
        T data[Size];
    public:
        int getSize() const { return Size; }
    };

    here,SizeIs a non-type parameter indicating the size of the array.

    Usage example:

    Array<int, 10> arr; // Create an int type array with a size of 10

    7. Conclusion

    C++ templates are powerful, making code more versatile and reducing duplication. Understanding how to use technology such as function templates, category templates, and template specialization will greatly enhance the flexibility and performance of programming.



    C++ Class cross-reference

    1. Problem background

    In C++, when two classes depend on each other and need to reference each other's members at the same time, directly in their respective.hin file#includeThe other party's definition will cause a circular reference problem, resulting in failure to compile. The solution is to use "forward declaration" to avoid circular references.

    2. Solution steps

    3. Code examples

    ClassA.h

    // ClassA.h
    #ifndef CLASSA_H
    #define CLASSA_H
    
    // Forward declaration ClassB
    class ClassB;
    
    class ClassA {
    public:
        ClassA();
        void setB(ClassB* b); // Set the pointer to ClassB
        void showBData(); // Display ClassB data
    
    private:
        ClassB* b; // pointer to ClassB
    };
    
    #endif

    ClassB.h

    // ClassB.h
    #ifndef CLASSB_H
    #define CLASSB_H
    
    // Forward declaration ClassA
    class ClassA;
    
    class ClassB {
    public:
        ClassB(int data);
        int getData(); // Get data
        void setA(ClassA* a); // Set the pointer to ClassA
        void showAInfo(); // Display ClassA information
    
    private:
        int data;
        ClassA* a; // pointer to ClassA
    };
    
    #endif

    ClassA.cpp

    
    #include "ClassA.h"
    #include "ClassB.h"
    #include <iostream>
    
    ClassA::ClassA() : b(nullptr) {}
    
    void ClassA::setB(ClassB* b) {
        this->b = b;
    }
    
    void ClassA::showBData() {
        if (b != nullptr) {
            std::cout << "ClassB data: " << b->getData() << std::endl;
        }
    }
            

    ClassB.cpp

    
    #include "ClassB.h"
    #include "ClassA.h"
    #include <iostream>
    
    ClassB::ClassB(int data) : data(data), a(nullptr) {}
    
    int ClassB::getData() {
        return data;
    }
    
    void ClassB::setA(ClassA* a) {
        this->a = a;
    }
    
    void ClassB::showAInfo() {
        if (a != nullptr) {
            a->showBData();
        }
    }
            

    4. Implementation instructions



    C++ Friend

    In C++,friendKeywords can be used on functions or classes to allow other functions or classes to access private and protected members of the class. Such a design allows external functions or classes to operate without violating the encapsulation principle.

    1. Friend function

    A Friend function is an external function that is granted access to the private and protected members of another class. When declared inside a category, end withfriendJust modify the keywords.

    Examples are as follows:

    #include <iostream>
    using namespace std;
    
    class Box {
    private:
        double width;
    
    public:
        Box(double w) : width(w) {}
    
        //Declare friend function
        friend void showWidth(Box &b);
    };
    
    //Friend function definition, can access private members of Box class
    void showWidth(Box &b) {
        cout << "Box width: " << b.width << endl;
    }
    
    int main() {
        Box box(10.5);
        showWidth(box); // Access private member width
        return 0;
    }

    In this example,showWidthAlthough the function is an ordinary function outside the Box category, it can still access the private members of the Box category because it is declared as a friend function.width

    2. Friend category

    The Friend class allows one class to access all members of another class. Such a setup is useful when categories need to work closely together, but should be used with caution to avoid exposing too many internal details.

    Examples are as follows:

    #include <iostream>
    using namespace std;
    
    class Square; // forward declaration
    
    class Rectangle {
    private:
        double width, height;
    
    public:
        Rectangle(double w, double h) : width(w), height(h) {}
    
        // Declare the Square category as friend
        friend class Square;
    };
    
    class Square {
    public:
        double areaOfRectangle(Rectangle &rect) {
            return rect.width * rect.height;
        }
    };
    
    int main() {
        Rectangle rect(5.0, 3.0);
        Square square;
        cout << "Area of rectangle: " << square.areaOfRectangle(rect) << endl;
        return 0;
    }

    In this example, the Square class is declared as a friend class of the Rectangle class, so the member functions in the Square class can directly access the private members of the Rectangle class.widthandheight

    3. Application scenarios of Friend function and Friend category

    Be careful when using friend functions and friend classes in C++. Excessive use will destroy the encapsulation of the class. Therefore, the friend keyword is usually only used when designing classes or functions that require close cooperation.



    C++ read file line by line

    Overview

    In C++, the most standard and recommended way to read a text file line-by-line is to use the file streaming class from the standard librarystd::ifstreamCooperatestd::getlinefunction.

    std::ifstreamResponsible for opening and managing file streaming, andstd::getlineis responsible for reading an entire line of text from the stream (until a newline character is encountered\n) and store it instd::stringin the object.

    Code example

    The following is a complete C++ example that demonstrates how to read line by line a file namedexample.txtfile contents.

    #include <iostream>
    #include <fstream> // Include file streaming library
    #include <string> // Include string category
    
    using namespace std;
    
    void read_file_line_by_line(const string& filename)
    {
        // 1. Create std::ifstream object
        //Try to open the specified file.
        ifstream input_file(filename);
        
        // 2. Check whether the file is opened successfully
        if (!input_file.is_open())
        {
            cerr << "Error: Unable to open file" << filename << endl;
            return;
        }
        
        string line;
        int line_number = 1;
        
        // 3. Use std::getline function to read line by line
        // The loop condition (getline(stream, string)) returns true each time the read is successful.
        // When end of file (EOF) is reached or an error occurs, return false and the loop ends.
        while (getline(input_file, line))
        {
            cout << "Line " << line_number << ": " << line << endl;
            line_number++;
        }
        
        // 4. Close file streaming
        // When the input_file object exceeds its scope, the destructor will automatically close the file.
        // But calling close() explicitly is also acceptable.
        input_file.close();
        
        cout << "File reading completed." << endl;
    }
    
    int main()
    {
        read_file_line_by_line("example.txt");
        return 0;
    }

    Key concepts



    C++ Write file line by line and align fields

    Overview

    In C++, converting a data structure (e.g. fromstd::vector<std::string>To write the file line by line (tokens read in) and ensure that each column (token) maintains a fixed width alignment in the line, you need to use **std::ofstream** Use **I/O Stream Manipulators** to control the output format.

    The main format control tools are:

    Code example

    The following is a C++ example of how to convert a two-dimensional data structure containing multiple fields (usingstd::vector<std::vector<std::string>>Simulate) and write the file, making sure that each token field has a fixed width of 15 characters and is left aligned.

    #include <iostream>
    #include <fstream> // Include file output stream
    #include <string>
    #include <vector>
    #include <iomanip> // Include I/O stream manipulator (setw, left/right)
    
    using namespace std;
    
    // Simulate a two-dimensional data structure, each row contains multiple fields (tokens)
    using TableData = vector<vector<string>>;
    
    void write_aligned_data(const string& filename, const TableData& data, int column_width)
    {
        // 1. Create std::ofstream object and open the file
        ofstream output_file(filename);
        
        // 2. Check whether the file is opened successfully
        if (!output_file.is_open())
        {
            cerr << "Error: Unable to open file " << filename << " for writing." << endl;
            return;
        }
    
        //Set global alignment: left-aligned (L-Justified)
        output_file << left;
        
        // 3. Write data line by line
        for (const auto& row : data)
        {
            // 4. Write token by token and set the width
            for (const auto& token : row)
            {
                // setw(width) only affects the next output item immediately following it
                output_file << setw(column_width) << token;
            }
            
            // 5. Insert a newline character after the end of the line to start a new line
            output_file << "\n";
        }
        
        // 6. Close file streaming
        output_file.close();
        
        cout << "Data has been successfully written to the file: " << filename << endl;
    }
    
    int main()
    {
        //Sample data: contains four rows, each row has three fields
        TableData data = {
            {"Name", "Item", "Price"},
            {"Alice", "Book", "19.99"},
            {"BobJohnson", "PenSet", "4.50"},
            {"Charlie", "Notebook", "800.75"}
        };
        
        const int COLUMN_WIDTH = 15; // Define the width of each column
        
        write_aligned_data("output_aligned.txt", data, COLUMN_WIDTH);
        
        return 0;
    }

    Analysis of key technologies



    .NET C++ reads HTML table

    Overview

    In .NET C++ (or more commonly C++/CLI) projects, reading and parsing HTML tables in files usually requires the use of an external HTML parsing library, because the standard .NET framework and C++ themselves do not have built-in powerful HTML DOM parsing capabilities. A common and efficient option is to use a library in C# or another .NET language and then reference it in C++/CLI.

    For C++/CLI projects, the most practical and recommended approach is to useHtml Agility Pack(HAP), a very popular .NET HTML parser. Although HAP is written in C#, it can be used seamlessly as a reference in any .NET language, including C++/CLI.

    Steps to use Html Agility Pack

    1. Create a C++/CLI project:Make sure your project is a C++/CLI project (for example: CLR Console Application or Windows Forms App).
    2. Get Html Agility Pack:
      • Search and install through Visual Studio's NuGet package managerHtmlAgilityPack
    3. Program code implementation (C++/CLI):

    Code example

    The following is a C++/CLI code snippet that demonstrates how to read a local HTML file and parse the first table in it (<table>) content:

    #using <System.dll>
    #using <System.Xml.dll>
    #using <HtmlAgilityPack.dll> // Make sure the reference is included
    
    using namespace System;
    using namespace System::IO;
    using namespace HtmlAgilityPack;
    
    void ParseHtmlTable(String^ filePath)
    {
        // Check if the file exists
        if (!File::Exists(filePath))
        {
            Console::WriteLine("Error: File does not exist.");
            return;
        }
    
        // 1. Load HTML file
        HtmlDocument^ doc = gcnew HtmlDocument();
        try
        {
            //Load HTML from file
            doc->Load(filePath);
        }
        catch (Exception^ ex)
        {
            Console::WriteLine("An error occurred while loading the file: " + ex->Message);
            return;
        }
    
        // 2. Select the first <table> node
        HtmlNode^ table = doc->DocumentNode->SelectSingleNode("//table");
    
        if (table != nullptr)
        {
            Console::WriteLine("Find the HTML table and start parsing...");
    
            // 3. Select all <tr> (table column) nodes
            HtmlNodeCollection^ rows = table->SelectNodes(".//tr");
    
            if (rows != nullptr)
            {
                for each (HtmlNode^ row in rows)
                {
                    // 4. Select the <td> or <th> (cell) node
                    // Use the | operator to select <td> or <th>
                    HtmlNodeCollection^ cells = row->SelectNodes("td | th");
    
                    if (cells != nullptr)
                    {
                        String^ rowData = "";
                        for each (HtmlNode^ cell in cells)
                        {
                            // Get the internal text of the cell and remove the leading and trailing blanks
                            rowData += cell->InnerText->Trim() + "\t";
                        }
                        Console::WriteLine(rowData);
                    }
                }
            }
            else
            {
                Console::WriteLine("<tr> tag not found in table.");
            }
        }
        else
        {
            Console::WriteLine("<table> tag not found in file.");
        }
    }
    
    int main(array<String^>^ args)
    {
        // Please replace "your_html_file.html" with your actual file path
        String^ htmlFilePath = "C:\\path\\to\\your_html_file.html";
        ParseHtmlTable(htmlFilePath);
        return 0;
    }

    Explanation of key technical points



    .NET C++ HTTP API Server

    Using the HttpListener class

    HttpListenerClass allows you to create a simple, self-hosted HTTP server in a C++/CLI application.

    Project requirements and settings

    Create a C++/CLI project in Visual Studio (e.g. CLR Console Application) and make sure it is referencedSystem.dll

    Code example

    The following is usedHttpListenerC++/CLI code to create a simple API server and handle GET requests.

    #using <System.dll>
    
    using namespace System;
    using namespace System::Net;
    using namespace System::Threading::Tasks;
    using namespace System::Text;
    
    // Function to handle incoming HTTP requests
    void HandleRequest(HttpListenerContext^ context)
    {
        HttpListenerRequest^ request = context->Request;
        HttpListenerResponse^ response = context->Response;
    
        //Default response settings
        response->ContentType = "application/json; charset=utf-8";
        String^ responseString = "";
        response->StatusCode = 200; // Default is OK
    
        // Check the requested path and method
        String^ url = request->RawUrl->ToLower();
        
        if (url == "/api/status" && request->HttpMethod == "GET")
        {
            // Handle GET /api/status request
            responseString = "{\"status\": \"Server Running\", \"language\": \"C++/CLI\"}";
        }
        else
        {
            // Handle other undefined requests
            response->StatusCode = 404; // Not Found
            responseString = "{\"error\": \"404 Not Found\", \"path\": \"" + url + "\"}";
        }
    
        // Convert string response to bytes and write to output stream
        array<Byte>^ buffer = Encoding::UTF8->GetBytes(responseString);
        response->ContentLength64 = buffer->Length;
        
        try
        {
            response->OutputStream->Write(buffer, 0, buffer->Length);
            response->OutputStream->Close();
        }
        catch (Exception^)
        {
            // Ignore write errors, usually client disconnects
        }
    }
    
    // Function to start HttpListener
    void StartListener(String^ prefix)
    {
        HttpListener^ listener = gcnew HttpListener();
        
        try
        {
            listener->Prefixes->Add(prefix);
            listener->Start();
            Console::WriteLine("C++/CLI API Server started, listening: {0}", prefix);
        }
        catch (Exception^ ex)
        {
            Console::WriteLine("An error occurred while starting HttpListener. Please confirm whether the permission or address is occupied.");
            Console::WriteLine("Error message: {0}", ex->Message);
            return;
        }
    
        // Asynchronous loop, continue to receive requests
        while (listener->IsListening)
        {
            try
            {
                // Wait for the next request synchronously
                HttpListenerContext^ context = listener->GetContext();
                
                // Use Task to process requests asynchronously to avoid blocking listening loops
                Task::Factory->StartNew(gcnew Action<HttpListenerContext^>(&HandleRequest), context);
            }
            catch (Exception^)
            {
                // An exception will be thrown when the listener is stopped
                break;
            }
        }
        
        if (listener->IsListening)
        {
            listener->Close();
        }
    }
    
    int main(array<String^>^ args)
    {
        //Set the URL prefix for monitoring
        // NOTE: On Windows, administrator rights or using netsh to register the URL namespace may be required.
        String^ listeningPrefix = "http://localhost:8080/";
        StartListener(listeningPrefix);
        
        Console::WriteLine("Press any key to end the server...");
        Console::ReadKey(true);
        
        return 0;
    }

    Note on execution permissions

    On Windows systems, if the code is not run with administrator privileges,HttpListenerAn access-denied exception may be thrown when listening on a specific port. You can register a URL namespace to allow non-administrator accounts to run the server with the following command:

    
    netsh http add urlacl url=http://+:8080/ user=Everyone
    

    inhttp://+:8080/should be replaced with the actual prefix used in your code.



    ASP.NET Core C# HTTP API Server

    Overview

    In ASP.NET Core, the standard project type for creating an HTTP API server is Web API. Latest .NET version (.NET 6 and above) recommendedMinimal APIsto quickly and lightweightly create API endpoints.

    Minimal APIs combine startup logic (Startup) and routing definitions (Routing) into a single file using minimal files and lines of codeProgram.csmiddle.

    Project setup (using CLI)

    To create a new Minimal API project, you can use the .NET CLI (Command Line Interface):

    
    dotnet new web -n MinimalApiServer
    cd MinimalApiServer
    

    Program code example: Program.cs

    The following is the Minimal API server core fileProgram.csfull content. It defines server startup, middleware, and two API endpoints (one GET, one POST).

    // 1. Create a WebApplication instance (replacing the traditional Startup category)
    var builder = WebApplication.CreateBuilder(args);
    
    // 2. Register service (Service Configuration)
    //Here you can add database connection, verification services, etc.
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(); // Enable Swagger/OpenAPI support
    
    var app = builder.Build();
    
    // 3. Configure HTTP request pipeline (Middleware Configuration)
    
    // In the development environment, enable Swagger UI for testing
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    
    // Enable HTTPS redirection (recommended for production environments)
    // app.UseHttpsRedirection();
    
    // 4. Define API endpoint (Endpoint Definition)
    // Entity class used for POST requests
    public record Product(int Id, string Name, decimal Price);
    
    // GET request endpoint: /api/hello
    app.MapGet("/api/hello", () =>
    {
        return Results.Ok(new { message = "Hello from ASP.NET Core Minimal API!", timestamp = DateTime.Now });
    });
    
    // GET request endpoint: /api/products/{id}
    app.MapGet("/api/products/{id}", (int id) =>
    {
        // Assume querying products from the database
        if (id == 1)
        {
            return Results.Ok(new Product(1, "laptop", 1200.00m));
        }
        return Results.NotFound(new { error = $"Product ID {id} not found" });
    });
    
    // POST request endpoint: /api/products
    app.MapPost("/api/products", (Product product) =>
    {
        // ASP.NET Core will automatically deserialize the JSON request body into a Product entity
        Console.WriteLine($"Received new product: {product.Name} (ID: {product.Id})");
        
        //In actual application, the database addition operation will be performed here.
        //Return 201 Created status code
        return Results.Created($"/api/products/{product.Id}", product);
    });
    
    // 5. Start the application and start listening for HTTP requests
    app.Run();

    Execution and testing

    1. Run the server:Execute in project directorydotnet run
    2. Test endpoint:Servers are usually defaulted tohttp://localhost:5000orhttps://localhost:7000run.
      • Access using a browser or tool such as Postman/api/hello (GET)。
      • access/swaggerPath to view Swagger UI for testing all defined API endpoints.

    Key technical points



    vcpkg C++ package manager

    1. Download vcpkg source code

    vcpkg is not installed through the installation file, but directly copies the source code from GitHub to local. It is recommended to place it in the root directory of the disk (such asC:\vcpkg) to avoid paths that are too long or contain spaces. Please open the terminal (CMD or PowerShell) and execute:

    git clone https://github.com/microsoft/vcpkg.git
    cd vcpkg

    2. Perform initial compilation (Bootstrap)

    After downloading, you need to execute the script to compile the executable file of vcpkg, which will generatevcpkg.exe

    3. Integrate into development environment

    This step allows development tools (such as Visual Studio) to automatically recognize the packages installed by vcpkg:

    Common instruction comparison table

    instruction illustrate example
    search Search available packages vcpkg search libuv
    install Install specified packages vcpkg install libuv:x64-windows
    list List installed packages vcpkg list
    update Check for package version updates vcpkg update

    Set environment variables (recommended)

    In order to facilitate the use of vcpkg in any path, it is recommended to add the vcpkg folder path to the systemPATHin environment variables. In addition, if you want to install the 64-bit package by default, you can add an environment variableVCPKG_DEFAULT_TRIPLETand set its value tox64-windows

    Things to note

    Before using vcpkg on Windows, make sure it is installedVisual Studio 2015 or newer, and check the "Desktop development using C++" workload (including English language pack), otherwise errors may occur when compiling the package.



    .NET MessageBox

    1. Basic syntax and common overloading

    In C++/CLI,MessageBox::ShowIt is a static method used to pop up a dialog box. The most complete call method includes: message content, title, button type, icon and default button.

    using namespace System::Windows::Forms;
    
    //The simplest display
    MessageBox::Show("Operation completed");
    
    //Full parameter version
    DialogResult result = MessageBox::Show(
        "Are you sure you want to delete this file?", // Message content (Text)
        "Confirm deletion", // window title (Caption)
        MessageBoxButtons::YesNo, // Button combination
        MessageBoxIcon::Warning, // Prompt icon
        MessageBoxDefaultButton::Button2 // Default focus is on the second button (No)
    );

    2. Process the return value (DialogResult)

    Must be checked when a button contains multiple options such as Yes/No or OK/CancelDialogResultto determine the subsequent logic.

    if (result == DialogResult::Yes) {
        //Execute deletion logic
    } else {
        //Cancel operation
    }

    3. Common enumeration value reference

    category Common options illustrate
    MessageBoxButtons OK, OKCancel, YesNo, YesNoCancel Defines which buttons appear below the dialog box.
    MessageBoxIcon Information, Warning, Error, Question Define the icon and system sound effects displayed on the left.
    DialogResult OK, Cancel, Yes, No ShowThe return value of the method represents which key the user pressed.

    4. Advanced technique: combine std::string or float

    becauseMessageBox::ShowReceived is .NETSystem::String^, if you have native C++ data, you need to convert it.

    #include <string>
    #include <msclr/marshal_cppstd.h>
    
    // Display std::string in MessageBox
    std::string cpp_str = "Core Error";
    MessageBox::Show(msclr::interop::marshal_as<System::String^>(cpp_str));
    
    //Format the float and display it
    float dist = 1.23456f;
    MessageBox::Show("The distance is: " + dist.ToString("F2")); // Display "The distance is: 1.23"

    Common errors and solutions



    .NET custom input dialog box

    1. Why does MessageBox not support Edit Box?

    System::Windows::Forms::MessageBoxis designed to display "notifications" or "warnings" and obtain user decisions via standard buttons. It does not have the function of dynamically inserting control items. If you need to enter text, the standard approach is to inheritSystem::Windows::Forms::FormCreate a custom dialog box.


    2. Implement custom InputBox

    This is a simple, reusable category that contains labels, text boxes, and OK buttons.

    using namespace System;
    using namespace System::Windows::Forms;
    using namespace System::Drawing;
    
    public ref class CustomInputBox : public Form {
    public:
        TextBox^ txtInput;
        Button^ btnOK;
        Label^ lblPrompt;
    
        CustomInputBox(String^ title, String^ prompt) {
            //Set basic properties of the form
            this->Text = title;
            this->Size = System::Drawing::Size(300, 150);
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog;
            this->StartPosition = FormStartPosition::CenterParent;
            this->MaximizeBox = false;
            this->MinimizeBox = false;
    
            // Prompt text
            lblPrompt = gcnew Label();
            lblPrompt->Text = prompt;
            lblPrompt->Location = Point(15, 15);
            lblPrompt->Size = System::Drawing::Size(250, 20);
    
            // input box
            txtInput = gcnew TextBox();
            txtInput->Location = Point(15, 40);
            txtInput->Size = System::Drawing::Size(250, 20);
    
            // OK button
            btnOK = gcnew Button();
            btnOK->Text = "OK";
            btnOK->DialogResult = System::Windows::Forms::DialogResult::OK;
            btnOK->Location = Point(190, 75);
            
            // Add controls
            this->Controls->Add(lblPrompt);
            this->Controls->Add(txtInput);
            this->Controls->Add(btnOK);
            
            //Set the default button (pressing Enter is equivalent to clicking OK)
            this->AcceptButton = btnOK;
        }
    };

    3. How to call in the main program

    useShowDialog()The method opens the window in forced response mode and checks whether the return value isOK

    void OnButtonClick() {
        CustomInputBox^ ibox = gcnew CustomInputBox("System input", "Please enter the file name:");
        
        if (ibox->ShowDialog() == System::Windows::Forms::DialogResult::OK) {
            String^ userInput = ibox->txtInput->Text;
            
            if (!String::IsNullOrWhiteSpace(userInput)) {
                // Process the string entered by the user
                MessageBox::Show("You entered: " + userInput);
            }
        }
    }

    4. Plan comparison

    plan Implementation complexity advantage shortcoming
    Custom Form middle Full control over the layout and the ability to add validation logic (such as limited numbers). More interface code needs to be written.
    VB Interaction Low One line of code completed. Need to quoteMicrosoft.VisualBasic, the style is fixed and cannot be adjusted.
    Win32 API high No .NET environment required. Developing in C++/CLI is extremely trivial and difficult to maintain.

    Common pitfalls



    PictureBox red cross error

    Phenomenon description

    PictureBox displays a red cross, indicating that theOnPaintAn exception occurred during execution, However, .NET swallows this exception by default and will not show it in the general log or interruption points, making it difficult to debug.

    Common causes

    reason illustrate
    Bitmap has been Disposed PictureBox still holds a reference to the Bitmap, and the released resources are accessed during Paint.
    Source Stream is closed After using Stream to create a Bitmap and then closing the Stream, the Bitmap data will become invalid.
    Cross-thread access The background thread directly modifies or assigns Bitmap, which conflicts with the UI thread.
    GDI+ resource exhaustion A large number of Bitmaps are not Disposed, resulting in insufficient GDI+ memory

    Error message comparison

    Exception message root cause Solution direction
    ArgumentException: Parameter is not valid Bitmap has been Disposed or Stream has been closed Deep copy Bitmap, does not rely on Stream
    InvalidOperationException: object is in use elsewhere Access the same Bitmap simultaneously across threads Add lock, or Invoke back to the UI thread
    OutOfMemoryException GDI+ resources are exhausted or the image format is not supported Dispose the old Bitmap promptly and check the image source
    ExternalException: A generic error occurred in GDI+ The file or stream corresponding to the Bitmap no longer exists Ensure that the source is still valid during the Bitmap lifetime

    Debug steps

    Since the red cross problem may not occur often, it is recommended to proceed in order:

    1. Intercepting OnPaint exceptions: Inherit PictureBox, overrideOnPaint, Use try/catch to catch exceptions and output them toDebug.WriteLine, execute after capturethis.Image = nullAvoid persistent red crosses.
    2. Confirm exception message: Observe the message in the Visual Studio Output window, Check the table of error messages above to find the root cause.
    3. Tracking Bitmap lifecycle: Each time assigned to Dispose Bitmap, recordEnvironment.StackTrace, find out who released the resource at what point in time.
    4. Prevent Dispose of a Bitmap that is still in use: Check before Dispose Whether the PictureBox still holds the Bitmap, if so, firstImageSet to null and then Dispose.

    Safe picture changing mode

    All image changing operations are performed through this mode to ensure thread safety and correct Dispose order:

    // C++/CLI
    void SafeUpdateImage(Bitmap^ newBmp) {
        if (pictureBox1->InvokeRequired) {
            pictureBox1->Invoke(gcnew Action<Bitmap^>(
                this, &YourClass::SafeUpdateImage), newBmp);
            return;
        }
        Bitmap^ old = safe_cast<Bitmap^>(pictureBox1->Image);
        pictureBox1->Image = newBmp; // Change to the new picture first
        if (old != nullptr) old->Dispose(); // Dispose the old picture again
    }

    The correct way to create Bitmap from Stream

    // Error: bitmap invalid after stream is closed
    using (var stream = new FileStream(path, FileMode.Open)) {
        pictureBox1.Image = new Bitmap(stream);
    }
    
    // Correct: deep copy, does not rely on stream
    Bitmap loaded;
    using (var stream = new FileStream(path, FileMode.Open))
    using (var tmp = new Bitmap(stream)) {
        loaded = new Bitmap(tmp);
    }
    pictureBox1.Image = loaded;

    Troubleshooting checklist

    Check items Confirmation method
    Whether the Bitmap is Disposed elsewhere Unifiedly change images through SafeUpdateImage and record StackTrace
    Whether the source Stream is closed Use deep copy insteadnew Bitmap(tmp)
    Whether to access across threads Check InvokeRequired when changing images, always Invoke back to the UI execution thread
    Does the red cross appear immediately or after a while? If it appears immediately, it may be a source problem; after a while, it may be a Dispose timing problem.


    Peripheral control program development

    definition

    Peripheral control programs are applications used to communicate and operate external hardware devices (such as printers, scanners, motors, PLCs, sensors, etc.) connected to the computer or host.

    Common communication interfaces

    Common development languages ​​and environments

    languageApplicable situationsRemark
    PythonRapid development, test automationApplicable to Serial, USB HID
    C/C++Embedded control and driver developmentAccess to low-level memory and hardware
    C#Windows UI + Control DeviceSuitable for COM Port and USB communication
    JavaCross-platform controlLess commonly used in low-end devices

    Example 1: Using Python to control the serial port

    import serial
    
    ser = serial.Serial('COM3', 9600, timeout=1)
    ser.write(b'ON\n') # Send control commands
    response = ser.readline()
    print("Device response:", response.decode())
    ser.close()

    Example 2: C# controls COM Port device

    SerialPort port = new SerialPort("COM4", 9600);
    port.Open();
    port.WriteLine("MOVE 100");
    string response = port.ReadLine();
    Console.WriteLine("Response: " + response);
    port.Close();

    Example 3: Control USB HID device

    Example 4: TCP communication control peripherals

    import socket
    
    s = socket.socket()
    s.connect(('192.168.1.100', 5000))
    s.sendall(b'START\n')
    data = s.recv(1024)
    print("Response:", data.decode())
    s.close()

    Application cases

    Things to note

    in conclusion

    Peripheral control program development requires selecting the appropriate language and function library based on the device's interface and protocol, and combining serial, USB, network and other communication methods, which can be widely used in various automation and industrial control fields.



    Barcode Reader program development

    Common platform support

    Common barcode types

    Common development kits and tools

    Android development example (using ZXing)

    // build.gradle
    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
    
    //Java call scan screen
    IntentIntegrator integrator = new IntentIntegrator(this);
    integrator.setPrompt("Please scan the barcode");
    integrator.setBeepEnabled(true);
    integrator.setOrientationLocked(false);
    integrator.initiateScan();
    //onActivityResult receives the result
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if(result != null) {
            if(result.getContents() != null) {
                String barcode = result.getContents();
                Log.d("Barcode content", barcode);
            }
        }
    }

    Web development examples (using QuaggaJS)

    <script src="https://unpkg.com/[email protected]/dist/quagga.min.js"></script>
    
    <script>
    Quagga.init({
        inputStream: {
            name: "Live",
            type: "LiveStream",
            target: document.querySelector('#scanner')
        },
        decoder: {
            readers: ["code_128_reader", "ean_reader", "upc_reader"]
        }
    }, function(err) {
        if (!err) {
            Quagga.start();
        }
    });
    
    Quagga.onDetected(function(result) {
        console.log("Barcode content: ", result.codeResult.code);
    });
    </script>

    Platform vs. Suite Comparison

    platformRecommended kitIs it free?
    AndroidZXing / ML Kityes
    WebQuaggaJS / jsQRyes
    WindowsDynamsoft / ZXing.NETDynamsoft for commercial use
    PythonZBar / pyzbaryes

    in conclusion

    To develop Barcode Reader, you can choose the appropriate open source package according to the platform. ZXing is the most widely supported choice. QuaggaJS is available for the Web. If you need commercial-level support, you can consider Dynamsoft Barcode SDK.



    Barcode with control characters

    Basic principles

    Barcode readers are essentially devices that simulate keyboard input. When a barcode is scanned, it "outputs" the content in the barcode into a character stream, just like keyboard input.

    Therefore, the barcodeCan contain control code (Control Code),butRequires barcode reader and barcode format supportJust fine.

    Common control code types in barcodes

    Condition 1: The barcode format must support control codes

    For example, the following format can encode control codes:

    Condition 2: The barcode encoding tool must support embedding control codes

    Some barcode generators allow embedding special characters, such as:

    Condition 3: The barcode scanner must support output control codes

    Most professional barcode printers (e.g. Zebra, Honeywell) are preset at the factoryDisable control code output, needs to be enabled through the "Settings barcode" provided by the scanner:

    Condition 4: The operating system and application must receive it correctly

    For example in a Windows application:

    Example: Encoding Ctrl-C barcode content

    Encoding ASCII 3 with Code128:

    Input:\x03Hello World

    After the barcode is scanned, Ctrl+C will be triggered and "Hello World" will be output.

    in conclusion



    Android development

    Android development platform

    Platform introduction

    Android is an open-source mobile operating system developed by Google and widely used in smartphones, tablets, and other smart devices. Developers can use its rich API and tools to create a variety of applications.

    development tools

  • Android Studio: An integrated development environment (IDE) officially provided by Google that supports code editing, simulator testing and debugging functions.
  • Kotlin and Java: The main programming languages ​​used for Android development, among which Kotlin is the officially recommended language.
  • Android SDK: Provides emulators, API libraries, and toolsets to support application development and testing.
  • Gradle: Tool for managing dependencies and building automation.

    Application life cycle

  • Start (onCreate): The application starts and initializes resources.
  • Run (onStart): The screen is displayed to the user.
  • Activity (onResume): The application enters an interactive state.
  • Pause (onPause): The application is partially hidden or loses focus.
  • Stop (onStop): completely hidden and may be recycled by the system.
  • Destroy (onDestroy): The application is closed and all resources are released.

    Advantages

  • Openness: Supports customization and broad device compatibility.
  • Market size: Google Play offers global app publishing opportunities.
  • Powerful tools: Rich development tools and file resources help improve development efficiency.

    learning resources

  • Official documentation: Android Developers provides detailed documentation and examples.
  • Development community: Platforms such as Stack Overflow and Reddit provide technical support.
  • Online courses: You can choose related courses from Udemy, Coursera or YouTube.

    Conclusion

    The Android development platform has attracted many developers with its flexibility and powerful functions, making it one of the first choices for mobile application development.

    Chromebook using Android Studio

    Installation steps

    1. turn onSettings → Developer → Linux Development Environment (Crostini), allocate at least 20GB of disk space and 8GB of memory.
    2. Update kit:
      sudo apt update && sudo apt upgrade -y
      sudo apt install -y wget curl unzip zip git ca-certificates
    3. Install JDK (version 17 recommended):
      sudo apt install -y openjdk-17-jdk
    4. Download and install Android Studio:
      sudo dpkg -i ~/Downloads/android-studio-*.deb || sudo apt -f install -y
      android-studio
      or decompress.tar.gz
      tar -xzf ~/Downloads/android-studio-*.tar.gz -C ~
      ~/android-studio/bin/studio.sh
    5. Follow the installation wizard to complete the SDK and tool settings.

    Test with a physical device

    1. On ChromeOS:Settings → Developer → Linux → USB Device, check the box to share the phone with Linux.
    2. Turn on the phoneDeveloper Options → USB Debugging, allowing RSA fingerprinting when connected.
    3. Linux environment confirmation device:
      sudo apt install -y android-sdk-platform-tools
      adb kill-server
      adb start-server
      adb devices

    Performance and emulator recommendations

    alternatives



    Chromebook uses VS Code + Android SDK

    Install VS Code

    1. Turn on ChromeOSSettings → Developer → Linux Development Environment (Crostini)
    2. Download the VS Code Linux version (.deb file) and install it in the Linux container:
      sudo dpkg -i ~/Downloads/code_*.deb || sudo apt -f install -y
    3. Start VS Code and install commonly used extensions (such asKotlinFlutterJava Extension Pack)。

    Install Android SDK and tools

    1. Install necessary packages:
      sudo apt update && sudo apt install -y openjdk-17-jdk unzip git
    2. Download Android SDK Command Line Tools:
      wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
      unzip commandlinetools-linux-*_latest.zip -d ~/android-sdk
    3. Set environment variables (can be added~/.bashrcor~/.zshrc):
      export ANDROID_SDK_ROOT=$HOME/android-sdk
      export PATH=$ANDROID_SDK_ROOT/cmdline-tools/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH
    4. Use sdkmanager to install platform tools and necessary packages:
      sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"

    Connect to physical mobile phone test

    1. On ChromeOS:Settings → Developer → Linux → USB Device, check phone sharing.
    2. Turn on the phoneDeveloper Options → USB Debugging
    3. Linux container confirmation device:
      adb devices
      SeedeviceThe test is ready to be deployed.

    Develop in VS Code

    Suitable for the situation



    Android App Example

    Create new project

    Create a new project in Android Studio, select the "Empty Activity" template, and set the project name and other basic information.

    Writing interface (activity_main.xml)

    existres/layout/activity_main.xmlA simple user interface designed in the file, for example, containing a button and a text display area:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:gravity="center">
            
                <Button
                    android:id="@+id/button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Click me" />
            
                <TextView
                    android:id="@+id/textView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Hello, World!"
                    android:layout_marginTop="20dp" />
            
            </LinearLayout>

    Write program logic (MainActivity.java)

    existMainActivity.java, set the click event of the button to change the content of the text display area:

    package com.example.simpleapp;
    
            import android.os.Bundle;
            import android.view.View;
            import android.widget.Button;
            import android.widget.TextView;
            import androidx.appcompat.app.AppCompatActivity;
    
            public class MainActivity extends AppCompatActivity {
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
    
                    Button button = findViewById(R.id.button);
                    TextView textView = findViewById(R.id.textView);
    
                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            textView.setText("You clicked the button!");
                        }
                    });
                }
            }

    Execute application

    Click the Run button in Android Studio to test your app on the emulator or a connected physical device. After clicking the button, the text will change to "You clicked the button!".



    Android gets current GPS location

    Permission settings

    existAndroidManifest.xmlAdd the following permissions:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    Checking and requesting permissions (Android 6.0 and above)

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }

    Get LocationManager

    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    Get current location

    LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(@NonNull Location location) {
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            Log.d("GPS", "Latitude: " + latitude + ", Longitude: " + longitude);
        }
    };
    
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        == PackageManager.PERMISSION_GRANTED) {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
            1000, // millisecond interval
            1, // Minimum distance (meters)
            locationListener);
    }

    Use FusedLocationProviderClient (recommended)

    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        == PackageManager.PERMISSION_GRANTED) {
        fusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, location -> {
                if (location != null) {
                    double lat = location.getLatitude();
                    double lng = location.getLongitude();
                    Log.d("GPS", "Lat: " + lat + ", Lng: " + lng);
                }
            });
    }


    Sound Control Android App

    Basic concepts

    To implement a voice assistant function like Siri or Hey Google, you need to combine the following components:

    Add necessary permissions

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    Voice recognition initialization

    SpeechRecognizer recognizer = SpeechRecognizer.createSpeechRecognizer(this);
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    
    recognizer.setRecognitionListener(new RecognitionListener() {
        @Override
        public void onResults(Bundle results) {
            ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            if (matches != null && !matches.isEmpty()) {
                String command = matches.get(0).toLowerCase();
                if (command.contains("Open camera")) {
                    // perform operations
                }
            }
        }
        //Other necessary overwriting methods are omitted
    });
    
    recognizer.startListening(intent);

    Speech synthesis (response to user)

    TextToSpeech tts = new TextToSpeech(this, status -> {
        if (status == TextToSpeech.SUCCESS) {
            tts.setLanguage(Locale.TAIWAN);
            tts.speak("Hello, I'm here.", TextToSpeech.QUEUE_FLUSH, null, null);
        }
    });

    Permanent background monitoring (optional)

    If you want to keep the background and wake it up by voice, you need to use:

    Things to note



    Permanent background monitoring

    Purpose

    The goal of permanent background monitoring is to allow the App to detect voice wake-up words (such as "Hey Assistant") and activate corresponding functions even when the screen is not open.

    challenge

    solution architecture

    1. useProspect services(Foreground Service) remains operational.
    2. Voice wake-up adoptsPorcupineWait for offline Hotword Engine.
    3. After waking up successfully, startSpeechRecognizerRecognize complete voice commands.

    Step 1: Prospect service establishment

    public class VoiceService extends Service {
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Notification notification = new NotificationCompat.Builder(this, "voice_channel")
                .setContentTitle("Voice assistant is operating")
                .setSmallIcon(R.drawable.ic_mic)
                .build();
            startForeground(1, notification);
    
            //Initialize Hotword detection
            startHotwordDetection();
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }

    Step 2: Create notification channel (Android 8+)

    NotificationChannel channel = new NotificationChannel("voice_channel",
        "Voice Assistant", NotificationManager.IMPORTANCE_LOW);
    NotificationManager manager = getSystemService(NotificationManager.class);
    manager.createNotificationChannel(channel);

    Step 3: Use Porcupine for voice wake-up

    Porcupine provides an Android SDK that recognizes custom keywords and operates completely offline.

    PorcupineManager porcupineManager = new PorcupineManager.Builder()
        .setAccessKey("your key")
        .setKeywordPath("hey_assistant.ppn")
        .setSensitivity(0.7f)
        .build((keywordIndex) -> {
            //Call SpeechRecognizer for speech recognition when woken up
            startSpeechRecognition();
        });
    
    porcupineManager.start();

    Step 4: Start the service

    Intent serviceIntent = new Intent(this, VoiceService.class);
    ContextCompat.startForegroundService(this, serviceIntent);

    Things to note



    Optimization of Hey Google Voice Assistant

    User-side optimization suggestions

    Developer-side optimization methods

    Optimization of voice wake-up trigger conditions

    Be aware of restrictions



    Apple product program development

    development tools

    Development environment settings

    1. Download and install the latest version ofXcode

    2. Open Xcode and go toPreferences > Accounts, sign in with your Apple ID to enable developer features.

    3. Install via XcodeCommand Line Toolsto use Swift command-line tools.

    Development platform

    Create project

    1. Open Xcode and select "Create a new Xcode project".

    2. Select a suitable application template, e.g.App (iOS/macOS)。

    3. Set the project name, Bundle Identifier and language (Swift or Objective-C).

    4. Select a UI framework (SwiftUI or UIKit).

    Simulation and testing

    Application publishing

    1. RegisterApple Developer Program(Annual fee USD $99 required).

    2. Set via XcodeApp Store Connectand submit the app.

    3. Follow Apple’sApp Store Review GuidelinesMake sure your app meets listing specifications.



    iOS development

    development tools

    iOS development mainly usesXcode, the official integrated development environment (IDE) provided by Apple.

    development process

    1. Design application architecture and interface
    2. Write code to implement functions
    3. Test using simulator or real machine
    4. Perform error troubleshooting and performance optimization
    5. Submit and publish via the App Store

    Essential knowledge

    Learning iOS development requires mastering the following basics:

    Develop resources

    Here are some helpful learning and development resources:



    Xcode

    Features

    Xcode is an integrated development environment (IDE) provided by Apple for the development of macOS, iOS, watchOS, and tvOS applications.

    Main components

    1. Code Editor:Provides syntax highlighting, code completion and error prompts
    2. Interface Builder:Supports intuitive drag-and-drop design interface
    3. Simulator:Used to test and simulate applications running on different devices
    4. Debugging tools:Supports breakpoints, memory detection and performance analysis

    Installation and updates

    You can download the latest version of Xcode from the Mac App Store or Apple's official developer website.

    Tips

    Practical tips to improve development efficiency:

    resource

    Related learning and reference resources:



    Swift

    language features

    Swift is Apple’s modern programming language for developing iOS, macOS, watchOS, and tvOS apps.

    Grammar basics

    core concepts

    1. Use Protocol to implement interfaces and protocols
    2. Extend category functionality using Extension
    3. Generics support improves code reusability
    4. Use closures to implement higher-order functions
    5. Supports custom operators and tuples

    Application scenarios

    Swift is not just for the Apple ecosystem, it can also be used for server-side development and cross-platform tools.

    resource

    Related learning and reference resources:



    Objective-C

    Features

    Objective-C is a C-based object-oriented programming language originally developed by NeXT Corporation and later widely used by Apple for macOS and iOS application development.

    grammatical structure

    Objective-C's syntax combines the features of C and Smalltalk, using the @ symbol to indicate language extensions.

    core concepts

    1. Object-oriented programming, including classes and inheritance
    2. Protocols are used to define collections of methods
    3. Categories are used to extend category functionality
    4. Block syntax for closures and callbacks

    development tools

    Objective-C development is primarily done using Apple’s Xcode.

    resource

    Here are some resources for learning and reference:



    GNews

    What is GNews?

    GNews is a news aggregation platform developed by Google, designed to help users obtain the latest global news. It integrates content from various news sources and uses artificial intelligence technology to personalize recommendations of news of interest to users.

    Main functions of GNews

    How to use GNews?

    Users can use this platform by visiting GNews’ website or downloading its app. On the platform, users can select topics of interest, follow specific news sources, and customize news feeds to suit their needs.

    Advantages of GNews

    in conclusion

    GNews is a powerful news aggregation tool that uses artificial intelligence technology to provide users with a personalized news experience. As news information changes rapidly, GNews helps users quickly keep up with world trends and obtain the information they need.



    Automated process tools

    Tool name Main features Applicable scenarios price
    n8n An open source automated workflow tool that provides highly customizable process design and supports self-built nodes. Suitable for internal process automation, large-scale automation systems, API integration, etc. Free and open source, with paid cloud version available.
    Make Provides visual workflow construction, supports the integration of multiple third-party applications and services, and emphasizes simplicity and ease of use. Suitable for workflow automation of small to medium-sized enterprises and rapid integration of various services. A free plan is available, and a paid plan offers more advanced features based on user needs.
    Zapier Supports integration with most applications, is simple and easy to use, and can create triggers and automated workflows. Suitable for automation in various business areas, especially small businesses and startups. A free plan is available, and a paid plan provides more features and runs based on user needs.


    AI development program

    Bolt

    Bolt is a fast, lightweight AI development framework that focuses on providing developers with simple and efficient tools to build applications. Features include:

    Cursor

    Cursor is an editor tool designed specifically for AI program development, providing intelligent auxiliary code writing and debugging functions. Features include:

    v0

    v0 is an AI platform based on visual development that allows users to build models and applications through a drag-and-drop interface. Features include:

    Codeium

    Codeium is a program editor combined with AI intelligent assistance, focusing on improving the efficiency and accuracy of program development. Features include:



    software engineering

    definition

    Software engineering is an engineering discipline that develops, operates, and maintains software in a systematic and planned manner. The goal is to build high-quality, maintainable, reliable, and demanding software systems.

    core goals

    Software Development Life Cycle (SDLC)

    1. Need analysis:Collect and analyze user requirements and prepare requirements specifications
    2. System design:Design system architecture, modules, databases and interfaces
    3. Implementation:Write code based on design
    4. test:Conduct unit testing, integration testing, system testing and acceptance testing
    5. Deployment and launch:Deploy the system to production environment
    6. Maintenance and updates:Fix bugs, update features, optimize performance

    Common development methodologies

    Common tools and techniques

    Quality attributes

    Division of roles



    Agile development

    core value

    main principles

    1. Address customer needs with the highest priority, providing value through early and consistent delivery.
    2. Welcome changes in requirements and use them to create competitive advantages for customers even in late stages of development.
    3. Frequent delivery of working software, often with lead times measured in weeks or months.
    4. Development and business teams should work together every day to promote communication and understanding.
    5. Center around motivated individuals, provide support and trust them to get the job done.
    6. Face-to-face communication is the most effective way of communication.
    7. The primary measure of progress is working software.
    8. Promote a sustainable development pace, and all participants should be able to maintain a stable pace.
    9. Pursue technical excellence and design simplicity, and improve flexibility and quality.
    10. Keep it simple and focus on getting the necessary work done.
    11. Self-organizing teams produce optimal designs and architectures.
    12. Reflect regularly and adjust behaviors to improve effectiveness.

    Commonly used frameworks

    Applicable scenarios



    Software development requirements document template

    Project name

    Please enter the official name of this project.

    version record

    Project background and goals

    Explain the reason for this project, background issues and core issues to be solved, and define clear project goals.

    System overview

    Outline the system functions and overall architecture, which can be paired with the system architecture diagram.

    Functional requirements

    non-functional requirements

    User roles and permissions

    Screen and interface requirements

    You can attach main screen sketches or wireframes to describe the elements and interactive processes of each screen.

    Data requirements

    List the main data table structure, fields, correlations, etc.

    Integration and interdependence

    List external systems, APIs, or other software components that need to be integrated.

    Timeline and Milestones

    Risks and Limitations

    List potential risks, constraints (such as budget, manpower, technology, etc.).

    appendix

    Related document links, reference materials, term definitions, etc.



    design pattern

    definition

    Design Patterns are a set of proven software design solutions that are mainly used in object-oriented programming to solve recurring design problems in specific situations.

    Three major categories

    Common establishment patterns

    Common structural patterns

    Common behavioral patterns

    Advantages of design patterns

    Usage suggestions



    version control

    definition

    Version Control is a system that manages file change history. It is widely used in software development, allowing multiple developers to collaborate at the same time and retaining a complete record of each change.

    Main functions

    Version control system type

    Common tools

    Git basic instructions

    branching strategy

    benefit



    Git

    Introduction

    Git is a decentralized version control system developed by Linus Torvalds (the father of Linux) in 2005 for tracking code changes, collaborative development, and version management. It is the most widely used version control tool today and is used in personal development, team projects and open source communities.

    core concepts

    Install Git

    1. Go toGit official websiteDownload the appropriate version.
    2. After installation, open Command Prompt (CMD) or PowerShell.
    3. entergit --versionto confirm the installation was successful.

    Initial settings

    When using Git for the first time, you need to set developer information:

    git config --global user.name "your name"
    git config --global user.email "Your [email protected]"

    basic instructions

    git init # Initialize local repository
    git clone URL # Copy the remote repository
    git add . # Add changes to the staging area
    git commit -m "description" # Create a commit
    git status # View current status
    git log # View commit records
    git branch # View branch list
    git checkout branch name # switch branches
    git merge branch name # Merge the specified branch
    git push # Push changes to the remote end
    git pull # Pull updates from the remote end

    Common workflow

    1. Create or copy a repository (git initorgit clone
    2. Edit or add files
    3. Add the modifications to the staging area (git add
    4. Commit changes (git commit
    5. Sync with remote end (git push / git pull

    Integrate with Visual Studio

    advantage

    Common remote services



    Git reset sync remote

    Core command: git reset

    If you want to completely discard all local changes that have not been committed (Uncommitted) and have been committed but not yet pushed (Local Commits), and reset the branch to be completely consistent with the remote end, please follow the steps below.

    1. Get the latest status of the remote end

    First, make sure your local index is updated with the latest progress on the remote end:

    git fetch --all

    2. Force reset to remote branch

    use--hardThe parameter points the current branch to the corresponding remote branch (assuming your branch is main):

    git reset --hard origin/main

    Handle untracked files (Untracked Files)

    git reset --hardOnly files already tracked by Git will be processed. If you have newly created files or folders locally but have not yet git added them, they will remain. To delete them all, usecleaninstruction:

    Delete untracked files

    # Execute the test first to see which files will be deleted
    git clean -n
    
    # Officially delete files (-f) and directories (-d)
    git clean -fd

    Common scenario comparison table

    Target Applicable directives
    Discard all local modifications git reset --hard origin/<branch_name>
    Discard only single file modifications git checkout HEAD -- <file_path>
    Temporarily save current changes (can be restored later) git stash
    Remove all clutter outside of gitignore git clean -fdx

    Things to note



    Git conflict file comparison

    When a Git merge branch conflicts, the file will be marked as "Unmerged". At this time, Git will insert a conflict mark in the file, and we need to use comparison commands to locate the problem and fix it manually.


    1. Find the conflicting file list

    Before resolving the conflict, first identify which files are in conflict:

    git status

    Conflicting files will be listed inUnmerged pathsunder section.


    2. Compare conflicting content

    When the file contains conflicting tags, you can use the following methods to view the differences:


    3. Interpret conflict markers

    Git will directly modify the conflict file, the format is as follows:

    <<<<<<< HEAD (or your branch name)
    This is the content of your current branch (Ours)
    =======
    This is the content of the other party's branch (Theirs)
    >>>>>>> branch_name

    4. Use graphical tools for comparison (recommended)

    For complex conflicts, the text interface is difficult to read. It is recommended to call a dedicated merge tool:

    git mergetool

    This will start something likeMeld, P4Merge, or VS CodeUsing other tools, compare three versions side-by-side: base version (Base), local version (Local), and remote version (Remote).


    5. Actions after resolution

    After you manually edit the files and decide which code to keep, you must perform the following steps to complete the merge:

    1. Remove from file<<<<, ====, >>>>mark.
    2. git add <file>(Add the resolved file to the temporary storage area).
    3. git commit(Complete merge commit).


    GitHub

    GitHub is a cloud-based version control and collaboration platform mainly used for software development. it usesGitImplement version control, allowing developers to manage a project's source code, track changes, and collaborate with others.

    Main functions

    Benefits of using GitHub

    Applicable objects

    GitHub is suitable for all types of developers, whether they are solo developers, open source communities, or enterprise teams. It can meet the version control and collaboration needs of small projects to large software projects.

  • GitHub

    GitHub usesgit pull --rebase

    git pull --rebaseIt pulls the latest changes from the remote branch and re-applies the local changes to the latest remote commit, instead of using traditional merge.

    Usage

    git pull --rebase

    Workflow

    1. Get the latest changes from the remote branch.
    2. Temporarily remove local commits.
    3. Apply remote commits to local branch.
    4. Reapply local commits to keep history linear.

    Why use--rebase

    Usage examples

    Suppose you commit some changes locally and there are new commits on the remote end, usegit pull --rebasemeeting:

    resolve conflicts

    If a conflict occurs while replaying a local commit, Git will ask for manual conflict resolution:

    1. resolve conflicts and usegit addStage resolved files.
    2. usegit rebase --continueContinue replaying the commit.
    3. If you want to cancel the operation, usegit rebase --abortBack to status quo.

    Summarize

    git pull --rebaseIt is an important tool for keeping Git submission history clean. It is especially suitable for multi-person collaboration. It can avoid redundant merge submissions and keep the submission record of the code base linear.



    GitHub User Access

    To allow other developers to participate in your project, you need to add them as collaborators through the repository's settings page. The following is the operation process:


    Operation steps

    1. Enter the repository: Open the homepage of the project you want to authorize on GitHub.
    2. Open settings: Click on the rightmost side of the menu bar aboveSettings(Gear icon).
    3. Manage access: In the left sidebar, clickAccessunder categoryCollaborators
    4. Authentication: You may be asked to re-enter your GitHub password or perform two-step verification to confirm your identity.
    5. Add new member:ClickAdd peoplebutton.
    6. Search for users: Enter the other party’s name in the pop-up windowGitHub account namefull nameore-mail
    7. Send invitation: After selecting the correct user, clickAdd [name] to this repository

    Permission Levels

    For personal account repositories, invitees usually have read and write permissions by default; if it is an organization account, more detailed settings can be made:

    Permission level illustrate
    Read Can only read and copy code, suitable for pure viewers.
    Triage Can manage Issues and Pull Requests, but cannot write code.
    Write Code can be pushed directly to the repository.
    Maintain In addition to writing, you can also manage some settings of the repository.
    Admin Have full control, including deleting repositories and managing other collaborators.

    Things to note



    Delete a GitHub repository

    Deleting a GitHub repository via web interface

    This is the most common and intuitive way to delete. Please note that once a repository is deleted, it cannot be restored unless you have a backup.

    1. Go to GitHub and go to the file you want to deleteRepository main page
    2. Click on the rightmost side of the paging tab aboveSettings(settings).
    3. Scroll the page to the bottom and find the one marked in redDanger Zone(danger area).
    4. ClickDelete this repositorybutton.
    5. A confirmation window will pop up asking you to enter the full name of the repository (usually in the formatUsername/repository name)。
    6. Click the button below to confirm deletion.
    ---

    Delete using GitHub CLI

    If you have GitHub's command line tool (gh) installed, you can quickly delete it through the terminal:

    gh repo delete <username>/<repository name> --confirm

    Notice:--confirmThe parameter will skip the confirmation step directly, please use it with caution.

    ---

    Delete local repository folder

    After the remote repository on GitHub is deleted, the local folder on your computer will still exist. To remove completely, delete the folder manually:

    Linux / macOS / ChromeOS

    rm -rf <folder name>

    Windows (CMD)

    rd /s /q <folder name>
    ---

    Delete Behavior Checklist

    Operation mode Scope of influence Is it recoverable?
    Web interface removal Only delete data on the GitHub remote server. No (unless contact support or fork)
    rm -rf command Only delete files local to your computer. No (unless there is a recycle bin)
    Delete .git folder Keep the file, but move it back to the normal folder (losing version control functionality). Yes (re-git init)

    Things to note



    Visual Studio uses Git

    Overview

    Visual Studio has built-in Git integration function, but you still need to install the Git executable file in the system to perform version control operations (such as Commit, Push, Pull, Merge, etc.).

    Step 1: Confirm whether Git is installed

    1. Open Command Prompt (CMD) or PowerShell.
    2. Enter the following command:
      git --version
    3. If it displays something likegit version 2.x.x, means it has been installed; if "Unrecognized git command" is displayed, you need to install Git.

    Step 2: Download and install Git

    1. Go toGit official download page
    2. Select the corresponding operating system version (Windows, macOS, or Linux).
    3. After downloading, execute the installation program. It is recommended to use the default settings and click "Next" all the way.
    4. After the installation is complete, restart Visual Studio.

    Step 3: Set up Git user information

    Turn on the command prompt and set your username and email:

    git config --global user.name "your name"
    git config --global user.email "Your [email protected]"

    This information will be appended to each commit and used to identify the developer.

    Step 4: Enable Git in Visual Studio

    1. Start Visual Studio.
    2. Click on the menu aboveView → Team Explorer
    3. chooseConnect → Clone a repositoryto copy the remote repository.
    4. Or click in an existing projectGit → Create Git repository, making the project part of version control.

    Step 5: Verify integration status

    Supplement: Use Visual Studio’s built-in Git installation

    If using Visual Studio 2022 or newer, you can check during the installation process「Git for Windows」options. In this way, Visual Studio will automatically install and integrate Git without manual configuration.

    Effect after completion

    Once the settings are complete, you can complete the following operations directly in Visual Studio:



    Azure DevOps

    Platform introduction

    Azure DevOps is an integrated development and collaboration platform provided by Microsoft that supports the complete DevOps process from code management, construction, automated testing to deployment. It is suitable for a variety of programming languages ​​and frameworks and can be used for personal projects or large enterprise team development.

    Main service components

    Main features

    Common uses

    Usage

    1. Go toAzure DevOps official website
    2. Sign in or sign up for a Microsoft account.
    3. Create new organizations and projects.
    4. Set up modules such as Repos, Pipelines, and Boards to start the development and deployment process.

    advantage

    Applicable scenarios



    Azure DevOps access tiers

    Step instructions

    1. log inAzure DevOps
    2. Click on the lower left cornerOrganization Settings
    3. Select from the menu on the leftUsers
    4. The system lists all users in the organization and their correspondingAccess Level

    Common Access Level Types

    Advanced operation

    hint

    If you encounter permission restriction issues when using Azure DevOps Pipelines, Repos or Boards, please first confirm whether your Access Level isBasicor above.



    CMake cross-platform build system

    CMake definition

    CMake is an open source, cross-platform "Meta-build System". It does not directly compile the program code itself, but automatically generates project files suitable for the current operating system and development environment by reading the configuration file (CMakeLists.txt). For example, on Windows it generates a Visual Studio solution, while on Linux it generates a Makefile or Ninja configuration file.

    Install CMake

    How to install CMake on different operating systems is as follows:

    Core functions

    CMake is designed to simplify the management of complex software projects. It supports multi-level directory structures, handles dependencies between libraries, and automatically searches for installed libraries on the system. In addition, it also provides testing (CTest) and packaging (CPack) functions, covering the complete life cycle from development to release.

    Mainstream construction process

    step Command example illustrate
    1. Configure cmake -S . -B build Read settings and detect system environment.
    2. Generate (automatically executed) Produce a Makefile or VS project file.
    3. Build cmake --build build Call the compiler to do the actual compilation.
    4. Install cmake --install build Move the generated executable file to the specified path.

    x64 and ARM64 support

    CMake has excellent cross-architecture support capabilities. In Windows environment, developers can specify the target architecture through parameters, such as using-A x64or-A ARM64. For modern Apple Silicon, CMake supports generating Universal Binaries, allowing programs to run on both Intel and Apple M-series processors.

    Why choose CMake

    Traditional Makefiles are difficult to maintain and do not have cross-platform versatility. CMake allows developers to simply write a set of configuration files, and developers around the world can easily open and compile projects in their preferred IDE (such as VS Code, CLion, Xcode). This is why most mainstream open source C++ projects currently use CMake as a standard tool.



    Program deployment

    definition

    Application Deployment is the process of moving a developed application from a development environment to a testing or production environment so that users can actually use it. It ensures that the system can perform stably and reproducibly in different environments.

    Deployment process

    1. Build:Compile and package source code into executable files or image files.
    2. Test:Verify functionality, performance and compatibility.
    3. Deploy:Deploy applications and configuration files to the server.
    4. Monitor:Continuously monitor operating status, record logs and performance indicators.

    Common deployment methods

    Common deployment architecture

    Automated deployment tools

    Deployment example

    # Deploy the example using GitHub Actions
    name: Deploy Web App
    on:
      push:
        branches: [ "main" ]
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Build Docker image
            run: docker build -t myapp .
          - name: Deploy to server
            run: docker run -d -p 80:80 myapp

    Deployment considerations

    Deployment strategy

    best practices



    Containerization technology

    definition

    Docker (container technology) is an open source platform for automating the deployment, scaling and management of applications. It uses "Containers" to package applications and their dependencies together to ensure consistent execution in different environments.

    core concepts

    Advantages of Docker

    basic instructions

    Dockerfile example

    # Use Python image file
    FROM python:3.10
    
    # Set working directory
    WORKDIR/app
    
    # Copy program files
    COPY ./app
    
    #Install dependency packages
    RUN pip install -r requirements.txt
    
    #Specify the instructions to be executed when the container starts
    CMD ["python", "app.py"]

    Docker Compose

    Docker Compose is a tool that can define multiple container applications. Usedocker-compose.ymlFiles define each service.

    version: '3'
    services:
      web:
        build: .
        ports:
          - "8000:8000"
      db:
        image: mysql:8
        environment:
          MYSQL_ROOT_PASSWORD: example
    

    Application scenarios

    Related technologies



    Deploying .NET C++ programs to Ubuntu

    Preface

    Deployment of .NET C++ (C++/CLI or .NET-based C++ applications) on Ubuntu systems needs to be handled separately according to the project type. If you use pure C++/CLI (relying on .NET Framework), you will not be able to execute it directly on Linux and you need to useCross-platform technology for .NET 6/7/8(Such as C++/CLR → C# or using C++/Native with .NET interoperability).

    Overview of deployment methods

    Depending on the nature of the application, deployment can be divided into three scenarios:

    1. Pure C++ application:Compiled with g++ and executed directly on Ubuntu.
    2. .NET Managed C++ (C++/CLI):Needs to be redesigned for C# or C++/CLI for Core supported by .NET 6 and above (supported by Windows only).
    3. Hybrid application:Mainly C#, C++ provides performance modules in the form of dynamic function libraries (.so).

    Environment installation

    Install the .NET SDK and necessary tools in Ubuntu:

    sudo apt update
    sudo apt install -y dotnet-sdk-8.0
    sudo apt install -y build-essential
    

    (Can be replaced according to versiondotnet-sdk-8.0fordotnet-sdk-7.0or other versions)

    Create project

    If you use .NET C# as the main program and call the C++ library:

    # Create the main application
    dotnet new console -n MyApp
    cdMyApp
    
    # Create native function library
    mkdir native
    cd native
    nano add.cpp

    add.cpp example:

    extern "C" int add(int a, int b) {
        return a + b;
    }
    

    Compile as a shared function library:

    g++ -fPIC -shared -o libadd.so add.cpp
    

    Calling C++ libraries in C# (.NET)

    AtProgram.csjoin in:

    using System;
    using System.Runtime.InteropServices;
    
    class Program
    {
        [DllImport("libadd.so", EntryPoint="add")]
        public static extern int Add(int a, int b);
    
        static void Main()
        {
            Console.WriteLine("3 + 5 = " + Add(3, 5));
        }
    }
    

    Execution and testing

    Return to the project root directory and execute:

    dotnet run
    

    If the output result is3 + 5 = 8, indicating successful deployment.

    Release deployment version

    Programs can be packaged into independently executable deployment files:

    dotnet publish -c Release -r linux-x64 --self-contained true
    

    The generated executable file is located inbin/Release/net8.0/linux-x64/publish/

    Docker container deployment (optional)

    Applications can be containerized using Docker to run on any Ubuntu system:

    # Dockerfile example
    FROM mcr.microsoft.com/dotnet/runtime:8.0
    WORKDIR/app
    COPY ./publish .
    COPY ./native/libadd.so /usr/lib/
    ENTRYPOINT ["./MyApp"]

    Build and execute containers:

    docker build -t myapp .
    docker run --rm myapp
    

    Things to note

    Summarize

    A feasible way to deploy .NET C++ programs to Ubuntu is usually toC# + C++ native library” structure. If the original program relies on C++/CLI, it needs to be redesigned to support cross-platform .NET. The most recommended way is to use .NET 8 + native C++ modules with Docker to achieve a stable, portable and consistent deployment process.



    Module dependency analysis

    Module dependency analysis is a software engineering technique used to identify and track external files (such as DLLs, libraries, frameworks) that an application depends on when executing. This is crucial to ensure that the software performs correctly in different environments.


    core analysis dimensions


    main purpose of analysis

    Purpose Detailed description
    troubleshooting Find program crashes caused by Missing DLL or Version Mismatch.
    security audit Identifies whether a program loads unauthorized third-party components or has security vulnerabilities.
    Performance optimization Evaluate the impact of too many dependent modules on startup time and memory usage, and remove unnecessary references.
    Transplantability assessment Determine whether the software will run on a computer that does not have a specific development environment installed, such as the .NET runtime or VC++ libraries.

    Common analysis tools



    Dependency Walker

    Dependency Walker (commonly known as Depends.exe) is a free tool for analyzing the file structure of Windows applications (such as .exe, .dll, .sys, etc.). It is primarily used to scan any 32-bit or 64-bit Windows module and build a hierarchical tree of all related dependent modules.


    Core functions


    Common application scenarios

  • DLL hell detection
  • scene describe
    System error troubleshooting Solve system errors such as 0xc000007b (parallel configuration error) or the specified module cannot be found.
    Software deployment Developers verify that the installer includes all necessary execution libraries (such as VC++ Redistributable).
    Check whether there are different versions of the DLL with the same name in the system path, causing the program to behave abnormally.

    Usage restrictions and alternatives

    Because Dependency Walker has not been updated for many years, it has poor support for some features of modern Windows 10/11 (such as API Sets or lazy-loaded DLLs), and false red warnings often appear. In this case, the following open source alternative tools are recommended:



    Dependencies

    Dependencies is an open source, modern dependency analysis tool designed to replace Dependency Walker (Depends.exe), which has been discontinued for many years. It is fully optimized for the system architecture of Windows 10 and Windows 11, and can accurately analyze module associations in modern software environments.


    Why choose Dependencies


    Function comparison table

    characteristic Dependency Walker (old version) Dependencies (modern version)
    Windows 10/11 support Poor (frequent false positives) Excellent (native support)
    API Sets Processing Unrecognized (shown as missing in red) Correctly mapped to entity DLL
    development status Updates stopped (2006) Under ongoing maintenance (GitHub)
    core technology C++ / MFC C# / WPF (some low-level C++)

    Common shortcut functions


    Obtain and install

    Dependencies is a green installation-free software that can usually be downloaded from GitHublucasg/DependenciesThe repository downloads the compiled Release version. When using it, just drag the .exe or .dll file you want to analyze into the window to start analysis.



    Execution phase detection function differences

    The two tools have different design philosophies: Dependency Walker (Depends.exe) includes a dynamic analyzer (Profiler), while modern Dependencies focus on static analysis and API Sets parsing.


    Why don't Dependencies execute the program?


    How to use Dependency Walker for motion detection (Profiling)

    If you need to use the "Executor" to troubleshoot DLL errors that only occur when running (such as delayed loading failures or path search problems), you can continue to use Dependency Walker's Profile function:

    1. Start Dependency Walker and load your .exe.
    2. Press on the keyboardF7Or click on the menuProfile -> Start Profiling
    3. Set parameters (such as working directory, command line parameters) in the pop-up dialog box, and then clickOK
    4. Look at the Log window at the bottom: When the program executes and crashes, the log at the bottom will indicate in red text which DLL the error occurred while loading.

    Comparison of advantages and disadvantages of motion detection

    advantage shortcoming
    CapableDynamic Loading(LoadLibrary) error. When running on Win10/11, the logs will be filled with a large number of false API-MS-WIN error messages.
    Can confirm the actual loaded DLL file path (related to the search path order). If the program fails to start at all due to too many dependencies, Profiler may not be able to capture useful information.

    Advanced debugging suggestions

    If you are having too many false errors in Dependency Walker's Profiler and can't see the point, it is recommended to use the following combination instead:



    Program development AI tools


    GitHub Copilot

    Developed by GitHub in partnership with OpenAI, it is currently the most widely used AI coding assistant in the world. It can be embedded directly inVisual Studio CodeJetBrainsIn other popular development environments, it analyzes comments and context to instantly suggest lines of code or entire functions.


    Cursor

    This is an independent software developed based on VS Code architecture.AI code editor. Unlike a simple plug-in, Cursor deeply integrates AI into the bottom layer of the editor. It understands the structure (Context) of the entire project and allows developers to talk directly to the entire library to perform global refactoring or bug fixes.


    Claude 3.5 Sonnet

    Although Claude is a general-purpose AI, its3.5 Sonnet modelIt is recognized as one of the top choices in terms of program logic, architectural design and debugging capabilities. matchArtifactsFunction, developers can directly preview the generated web page front-end screen or interactive components in the dialog box.


    Tabnine

    Tabnine attaches great importance toPrivacy and security, suitable for enterprises with high requirements for source code confidentiality. It supports fully localized deployment (Self-hosting), ensures that the code will not be uploaded to the cloud for training, and provides accurate auto-completion functionality.


    Amazon Q (formerly CodeWhisperer)

    Development Assistant provided by Amazon Web Services (AWS). In addition to basic code generation, it is especially enhanced withAWS cloud servicesThe integration can help developers quickly write infrastructure as code (IaC) or handle security scans and updates.


    Replit Agent

    AI agent built into the Replit online development environment. It is characterized byAutomated deploymentWith environment construction, users only need to describe the functions of the application, and Agent can automatically create files, install dependent packages, write code, and complete online operation.


    v0.dev

    Presented by VercelAI for front-end development. Users describe interface requirements through natural language, and v0 will directly generate front-end component code based on React, Tailwind CSS and Shadcn UI, greatly reducing the time of UI stereotypes.



    Agent-based AI programming assistant

    Agentic AI Coding Assistants. The characteristics of this type of tool are its ability to directly access the terminal, read and write files, execute tests, and have the ability to plan tasks independently.


    1. Terminal and CLI tools

    This type of tool is closest to Claude Code and runs directly in your terminal, making it suitable for developers who are accustomed to command line operations.


    2. IDE and editor tools

    Such tools integrate agent capabilities into the editor to provide a more intuitive visual development experience.


    3. Fully automated AI engineer (completely autonomous)

    Such tools usually have more independent operating capabilities and can complete the process from demand analysis to deployment on the web or in a stand-alone environment.


    Core function comparison table

    Tool name Main interface Core advantages
    Claude Code CLI (terminal) Developed natively by Anthropic, it follows the instructions of Claude 3.5 very closely.
    Aider CLI (terminal) Open source, supports multiple models, and has strong Git automated management.
    Cursor IDE (Editor) The UI has the highest degree of integration and is suitable for developers who don’t like to switch terminals.
    Cline VS Code plugin Open source and completely transparent, you can connect various API Keys by yourself.

    How to choose



    Claude Code

    Claude Code is an agent-based command line interface (CLI) tool developed by Anthropic. It runs directly in the developer's terminal and can understand the entire program code library, execute terminal commands, edit files, and assist in processing Git workflow, allowing developers to complete complex programming tasks through natural language.


    Core functions


    Installation method

    Claude Code requires Node.js 18+ environment, which can be installed through the following methods:

    1. Install using npm:
      npm install -g @anthropic-ai/claude-code
    2. Start the tool:
      Enter in the project directoryclaudeNow you can start interactive mode.

    Operation modes and shortcut keys

    Function Operation mode/shortcut keys
    Plan Mode Shift + Tab(Mac/Linux) orAlt + M(Windows). Make a detailed plan before executing.
    Auto-accept All changes are automatically accepted without the need to confirm each one.
    Select file enter@Quickly search and add specific files as background knowledge.
    Execute instructions use!prefix to execute Bash commands directly in the session (for example:!ls -la)。

    Commonly used built-in commands


    Hardware and system requirements


    For frequent permission confirmation pop-ups and the need for cross-directory access, optimization settings can be made through startup parameters and built-in commands.

    1. Reduce permission confirmation pop-ups

    By default, Claude Code will confirm dangerous commands (such as deleting files and executing system commands) one by one. To enter "automation mode" to reduce interference, use the following parameters:


    2. Access directories other than the current directory

    For safety reasons, Claude Code will be limited to the project directory where it is started by default. To access external paths, there are three methods:


    3. Set up a permanent alias (Alias)

    In order to facilitate quick startup and bring in these settings in the future, it is recommended that you.bashrcor.zshrc(Cygwin/Linux) Add alias:

    alias c='claude --auto-accept . /home/user/common_library'

    Things to note


    For the needs of fully automated startup (no confirmation) and access to external directories, Claude Code provides special CLI parameters to achieve this. These features are often referred to as "YOLO mode" and are suitable for use in a trusted environment or sandbox.

    1. Fully automatic execution: skip all permission confirmations

    If you don't want to executelsmkdirOr if you keep clicking OK when editing a file, you can use the following dangerous parameters:


    2. Access external directories: add permission path

    By default, Claude can only read and write the directory in which it is started. To access other paths, use--add-dir


    3. Combination skills: The most powerful automatic start command

    If you want to get it right at once and develop directly between multiple directories without hindrance, you can use a combination of:

    claude --dangerously-skip-permissions --add-dir ../library --add-dir ~/shared_configs

    Startup parameter comparison table

    Parameter name Function description Applicable situations
    --dangerously-skip-permissions Skip permission confirmation for all tools (Bash, Read, Write). Requires extensive automatic refactoring or operation in a sandbox environment.
    --add-dir <path> Authorizes Claude to access specific paths outside the current directory. Cross-project development may require reference to external documentation.
    --permission-mode acceptEdits Automatically accept file modifications, but still ask when executing Bash commands. Relatively safe automation mode.

    Safety reminder



    Cursor

    Cursor is an AI code editor developed based on VS Code. It is not just a plug-in, but it embeds AI capabilities deep into the bottom layer of the editor, allowing it to understand the context of the entire project and have the ability to automatically write, reconstruct, and repair code. Since it inherits VS Code, users can directly import all original settings and extended functions.


    Basic installation

    1. Download software:Go toCursor official website, the system will automatically detect your operating system (Windows, macOS, Linux) and provide download.
    2. Import settings:After installation and startup, Cursor will ask if you want to import extensions, shortcuts, and themes from VS Code. It is recommended to choose Import to seamlessly integrate development habits.
    3. Login account:Register and log in to your Cursor account. The free version (Hobby) provides a limited number of queries on higher-order models (such as GPT-4o or Claude 3.5 Sonnet), after which it switches to a smaller model.

    Core function usage

    1. Cmd + K (Inline Edit)

    Call the AI ​​directly in the code editor:

    2. Cmd + L (Chat Pane)

    Sidebar chat dialog:

    3. Cmd + I (Composer mode)

    This is Cursor’s most powerful “agent” mode:


    Advanced setup techniques

    Function name Setting method illustrate
    Model switching Sidebar bottom menu Switch between Claude 3.5 Sonnet, GPT-4o or Cursor Small.
    Rules for AI Settings > General Customize the AI's response style (for example: always use Traditional Chinese, code must meet specific specifications).
    Index Project Settings > Features Make sure to turn on Local Indexing so that the AI ​​can accurately search the entire project's files.

    Comparison of commonly used shortcut keys


    Things to note



    Aider


    Install

    Aider is a terminal-based AI pairing programming tool that supports direct modification of local source code. Before installation, please ensure that the system hasPython 3.8The above versions are the same asGit

    python -m pip install aider-chat

    API key configuration

    Before starting, the key provided by the AI ​​service provider needs to be set as an environment variable. Aider supports various models such as Anthropic and OpenAI by default:

    After the setting is completed, enter in the terminalaiderThis will open the conversation interface.


    File operations

    Aider will only read and modify files that you specify to join the context to save token costs and improve accuracy:


    Code editing

    You can directly use natural language to ask Aider to perform tasks, such as: "Help me split this class into two files" or "Fix existing bugs." After performing the modification, Aider will automaticallyGit Commit, and automatically compose a submission message based on the modified content.


    instruction

    instruction Function description
    /undo Undo the most recent code modification and Git commit performed by AI.
    /diff Preview the changes made to the current AI compared to the original version.
    /chat-mode Switch between conversation modes (e.g. code mode is used to modify files, ask mode is only used for Q&A).
    /help Display the complete list of built-in commands.
    /exit Exit the Aider program.


    Aider uses local model


    Feasibility and principles

    Aider supports multiple ways to interface with locally executed free and open source models. The most common method is to useOllamaLM StudioorLocalAIWait for the tool to create a local server that is compatible with the OpenAI API specification, and then let Aider point to the server address.


    Implemented via Ollama

    This is currently the simplest and most mainstream localization solution:

    aider --model ollama/deepseek-coder-v2

    core setting parameters

    parameter Function description
    --model Specify the model name. Local models are usually in the formatollama/<model_name>
    --openai-api-base If using LM Studio, you need to manually specify the local API URL (such ashttp://localhost:1234/v1)。
    --no-stream If the local inference performance is insufficient and the connection is unstable, you can turn off the streaming output to improve stability.

    Limitations and Challenges of Local Models


    Recommended local models

    Not all models are suitable for use with Aider. The following are local open source models currently recognized by the community as performing better in program development tasks:



    Laws related to software development

    Copyright law

    Software codes, design documents, user manuals, etc. are all covered by copyright protection. Copyright protection is automatically established upon completion of creation, no registration is required, and unauthorized copying, modification, distribution or commercial use is prohibited.

    patent law

    If the software involves technological innovation or unique algorithms, you can apply for patent protection. Patents are subject to review and approval and protect the inventor's exclusive rights to technical solutions, but pure program logic is usually not protected by patents.

    trademark law

    Software names, logos, and brand identities can be registered as trademarks to protect the brand image and market differentiation and prevent others from using it to cause confusion.

    Business Secrets Protection Act

    Undisclosed programming details, algorithms, database structures, etc. are business secrets. The company should protect it through confidentiality agreements, information management systems, etc.

    Information security related regulations

    For example, the Personal Information Law and the Information Security Management Law require users to properly handle personal data and ensure information security during the software development process. Violations may face administrative or criminal liability.

    Contract law and authorization clauses

    Software development often involves contract contracts, cooperative development contracts, software licensing terms, etc., which clearly define the rights and obligations of both parties, program code ownership, maintenance responsibilities, confidentiality obligations, etc. to avoid legal disputes.

    Internet and e-commerce related regulations

    The online operation of software involves network services, electronic payments, online protection of intellectual property rights, etc., and must comply with regulations such as the Electronic Signature Law and the Electronic Transaction Law.

    Intellectual Property Rights in Software Development

    Copyright

    The software code falls within the scope of copyright protection, and developers automatically own the copyright without additional registration. Copyright protection covers source code, design files, user manuals, etc.

    patent

    If the software involves novelty and technological innovation, it may be possible to apply for patent protection. Examples include unique algorithms or methods of solving technical problems, but pure code logic is usually outside the scope of patent protection.

    Trademark rights

    Software names and logos can be registered as trademarks to distinguish products from different sources and avoid market confusion.

    business secrets

    Undisclosed programming details, database structures, and algorithms can be protected through trade secrets. It needs to rely on the company's internal confidentiality agreement and management measures to maintain it.

    Authorization mode

    Software can be released through different licensing models, such as proprietary software, free software, and open source licenses (such as GPL, MIT). Different licensing models affect users' rights to modify and redistribute.

    Infringement risk

    Unauthorized use of another person's code, images or algorithms may constitute copyright infringement. The development process should ensure that the source of the program code is legal to avoid legal disputes.

    international protection

    Intellectual property rights are territorial, but can obtain a certain degree of protection in many countries through international treaties such as the Berne Convention and the TRIPS Agreement.



    Software mall

    Software sales platform

    In 2026, choosing the right software sales platform will depend on your software type and target market. The following are the classifications and characteristics of mainstream platforms:


    Universal digital products and SaaS platforms

    Game and desktop application distribution platform

    Enterprise and mobile application mall

    Taiwanese local e-commerce platform


    Platform selection comparison table

    demand target Recommended platform Core advantages
    Automate global tax processing Paddle / Lemon Squeezy Save yourself the trouble of tax declaration in various countries
    Pursue maximum traffic Steam / App Store Ready-made massive user base
    Quickly build a brand official website Shopify / SHOPLINE Highly customized shopping experience
    Early seed user acquisition AppSumo Get cash quickly through promotions



    email: [email protected]
    
    T:0000
    資訊與搜尋 | 回dev首頁
    email: Yan Sa [email protected] Line: 阿央
    電話: 02-27566655 ,03-5924828