Daily Linux commands

🔔 Prelude: With these commands you are able to do most text-related work the same as you are on Windows. Linux Common Commands System Management System Information # Basic system information lscpu # Detailed CPU information uname -a # Kernel and architecture info cat /etc/os-release # Distribution information # Hardware information lsblk # Block devices lsusb # USB devices lspci # PCI devices Package Management # dpkg package management sudo dpkg -i package.deb # Install deb package dpkg -l | grep package_name # Search installed packages dpkg -L package_name # List package files dpkg -S /path/to/file # Find which package owns file Monitoring and Performance Memory and Disk # Memory usage free -h # Human readable format watch -n 1 free -h # Real-time monitoring # Disk usage df -h # Disk usage du -sh /path/to/directory # Directory size du -h --max-depth=1 | sort -hr # Sort directories by size sudo fdisk -l # Partition table info System Monitoring # Temperature monitoring vcgencmd measure_temp # Raspberry Pi temperature sensors # General temperature sensors watch -n 1 vcgencmd measure_temp # Real-time temperature monitoring # Process monitoring ps aux # All processes top # Real-time process monitor htop # Enhanced top ps aux --sort=-%mem | head -10 # Sort by memory usage ps aux --sort=-%cpu | head -10 # Sort by CPU usage # I/O monitoring sudo iotop # I/O usage sudo iotop -o # Show only processes doing I/O Network Monitoring # Connection status ss -tuln # Network connections ss -a # All connections ss -tuln | grep :22 # Specific port # Traffic monitoring iftop # Interface traffic (requires installation) nethogs # Traffic by process (requires installation) Processes and Services Process Management # Find processes pgrep -f "process_name" # Find process PID ps aux | grep "process_name" # Detailed information # Terminate processes kill PID # Normal termination kill -9 PID # Force termination pkill "process_name" # Terminate by name Background Jobs # Background execution command & # Start in background nohup command & # Run without hangup # Job control Ctrl + Z # Suspend current process bg # Continue in background fg # Bring to foreground jobs # List background jobs # tmux sessions tmux new-session -d -s session_name "command" tmux attach -t session_name Service Management # systemd services systemctl status service_name # Check status systemctl start/stop/restart service_name systemctl enable/disable service_name # Auto-start on boot # Log viewing journalctl -u service_name # Service logs journalctl -f # Real-time logs journalctl --since "2 hours ago" # Time range Scheduled Tasks # cron jobs crontab -e # Edit crontab -l # List # Syntax: minute hour day month weekday command # 0 2 * * * /home/user/backup.sh # Run daily at 2 AM # */10 * * * * /usr/bin/check.sh # Run every 10 minutes Network Management Network Interfaces # View network interfaces ip addr show # All interfaces ip a # Short form ip link show up # Enabled interfaces # Manage interfaces sudo ip link set eth0 up/down # Enable/disable interface # Routing information ip route show # Routing table ip route | grep default # Default gateway WiFi Management # NetworkManager nmcli dev wifi list # Scan WiFi nmcli dev wifi connect "SSID" password "password" nmcli connection show # Saved connections # Traditional tools iwconfig # WiFi interface status Network Testing # Connectivity testing ping google.com ping -c 4 google.com # Limit count traceroute google.com # Path tracing # Port testing nc -zv google.com 80 # Port connectivity nmap -p 22,80,443 target_host # Port scanning # DNS queries dig google.com # DNS lookup cat /etc/resolv.conf # DNS configuration # Firewall sudo ufw status # Ubuntu firewall status Files and Text File Finding # Find by name find /path -name "filename" find . -name "*.txt" # By extension find . -type f -name "*.log" # Files only find . -type d -name "temp*" # Directories only # Command location which python3 # Command location whereis python3 # Binary, source, manual # Fast search sudo updatedb # Update database locate filename # Quick search Content Search # Basic search grep "pattern" file.txt grep "pattern" *.txt # Multiple files # Common options grep -i "pattern" file # Ignore case grep -r "pattern" directory/ # Recursive search grep -n "pattern" file # Show line numbers grep -v "pattern" file # Invert match # Context search grep -A 3 "pattern" file # Show 3 lines after grep -B 3 "pattern" file # Show 3 lines before grep -C 3 "pattern" file # Show 3 lines around File Content Operations # View files cat file.txt # Full content head -20 file.txt # First 20 lines tail -20 file.txt # Last 20 lines tail -f file.txt # Follow changes less file.txt # Paged viewing # Sort and unique sort file.txt # Sort sort -n numbers.txt # Numeric sort sort file.txt | uniq # Remove duplicates # File comparison diff file1.txt file2.txt # Basic comparison diff -u file1 file2 # Unified format diff -y file1 file2 # Side-by-side Text Processing and Pipes # sed stream editor sed 's/old/new/g' file.txt # Global replacement sed -i 's/old/new/g' file.txt # In-place modification sed '/pattern/d' file.txt # Delete matching lines sed -n '1,10p' file.txt # Print specific lines # awk text processing awk '{print $1}' file.txt # Print first column awk '{print $1, $3}' file.txt # Print multiple columns awk '/pattern/ {print $2}' file.txt # Conditional print awk -F':' '{print $1}' /etc/passwd # Specify delimiter awk '{sum += $1} END {print sum}' numbers.txt # Calculate sum # Pipes and redirection command > file.txt # Output redirection command >> file.txt # Append redirection command 2> error.log # Error redirection command &> all.log # All output redirection # Pipe operations command1 | command2 # Basic pipe cat log | grep "ERROR" | awk '{print $1}' | sort | uniq -c # tee splitting command | tee file.txt # Output to both file and terminal command | tee -a file.txt # Append mode echo "text" | sudo tee /root/file.txt > /dev/null # Privilege escalation write Transfer and Compression Network Downloads # wget downloads wget https://example.com/file.zip wget -O newname.zip https://example.com/file.zip # Specify filename wget -c https://example.com/largefile.iso # Resume download # curl downloads curl -O https://example.com/file.zip # Keep original filename curl -o newname.zip https://example.com/file.zip # Specify filename curl -C - -O https://example.com/largefile.iso # Resume download Remote Transfer # scp secure copy scp file.txt user@remote:/path/ # Upload file scp -r directory/ user@remote:/path/ # Upload directory scp user@remote:/path/file.txt ./ # Download file scp -P 2222 file.txt user@remote:/path/ # Specify port # rsync synchronization rsync -av source/ destination/ # Basic sync rsync -av --delete source/ destination/ # Delete extra files rsync -av source/ user@remote:/path/ # Remote sync rsync -avz --progress source/ destination/ # Compression + progress Compression and Extraction # tar archives tar -czf archive.tar.gz files/ # Create compressed archive tar -xzf archive.tar.gz # Extract archive tar -tzf archive.tar.gz # View contents tar -xzf archive.tar.gz -C /destination/ # Extract to directory # zip compression zip -r archive.zip directory/ # Compress directory unzip archive.zip # Extract unzip archive.zip -d /destination/ # Extract to directory unzip -l archive.zip # View contents Device Management USB Devices # USB device management lsusb # USB device list lsusb -v # Detailed information watch -n 1 lsusb # Real-time monitoring # Mount USB sudo mkdir /mnt/usb sudo mount /dev/sdb1 /mnt/usb # Mount sudo umount /mnt/usb # Unmount Bluetooth Devices # Bluetooth management systemctl status bluetooth # Service status sudo hciconfig hci0 up # Enable adapter sudo hcitool scan # Scan devices # Bluetooth console bluetoothctl # Common commands: power on, scan on, pair <MAC>, connect <MAC> Audio Devices # Audio devices aplay -l # Playback devices arecord -l # Recording devices pactl list sinks short # PulseAudio output devices # Volume control alsamixer # Graphical mixer amixer sset Master 80% # Set volume pactl set-sink-volume @DEFAULT_SINK@ 50% Quick Operations History Operations # History search Ctrl + R # Reverse search history Ctrl + S # Forward search history history # Show history list history | grep "pattern" # Search history commands # ! operator (history expansion) !! # Repeat last command !$ # Last argument of previous command !^ # First argument of previous command !* # All arguments of previous command !n # Execute nth command in history !ssh # Execute most recent command starting with ssh !?config # Execute most recent command containing config # Quick substitution ^old^new # Replace old with new in last command !!:s/old/new # Same as above, sed-style replacement sudo !! # Add sudo to previous command # Argument operations echo !$ # Show last argument of previous command ls !* # Use all arguments from previous command with ls Quick Editing # Cursor movement Ctrl + A # Move to beginning of line Ctrl + E # Move to end of line Ctrl + F # Move forward one character Ctrl + B # Move backward one character Alt + F # Move forward one word Alt + B # Move backward one word # Deletion operations Ctrl + K # Delete from cursor to end of line Ctrl + U # Delete from cursor to beginning of line Ctrl + W # Delete previous word Alt + D # Delete next word Ctrl + H # Delete previous character (same as Backspace) Ctrl + D # Delete current character # Copy and paste Ctrl + Y # Paste last deleted content Alt + Y # Cycle through deletion history # Other editing Ctrl + T # Transpose current and previous character Alt + T # Transpose current and previous word Alt + U # Convert current word to uppercase Alt + L # Convert current word to lowercase Alt + C # Capitalize current word Ctrl + _ # Undo last edit # System control Ctrl + L # Clear screen Ctrl + C # Interrupt current command Ctrl + Z # Suspend current process Ctrl + D # End input/exit shell # Auto-completion Tab # Auto-complete Tab Tab # Show all possible completions Alt + . # Insert last argument of previous command Alt + * # Expand all possible completions for current word Directory and File Operations # Directory operations cd - # Return to previous directory pushd/popd # Directory stack operations mkdir -p path/to/deep/directory # Create nested directories # {} Brace expansion - generates multiple names touch file{1,2,3}.txt # Creates file1.txt file2.txt file3.txt mkdir {backup,temp,logs} # Create multiple directories cp file.txt{,.bak} # Copy to file.txt.bak echo {A..Z} # Expand A B C ... Z echo {1..10} # Expand 1 2 3 ... 10 echo {01..10} # Expand 01 02 03 ... 10 (preserve format) # [] Bracket matching - matches existing files ls file[123].txt # Match file1.txt file2.txt file3.txt ls file[1-5].txt # Match file1.txt to file5.txt ls [abc]*.txt # Match txt files starting with a, b, or c ls [A-Z]*.log # Match log files starting with uppercase ls file[!123].txt # Match files except file1,2,3.txt rm temp[0-9][0-9].tmp # Delete files like temp01.tmp to temp99.tmp # Wildcard combinations cp *.{jpg,png,gif} images/ # Copy all image files ls file[1-3].{txt,log} # Match file1.txt, file1.log, etc. find . -name "*[0-9].txt" # Find txt files ending with digits

2026-09-10

Result and Option in short

🔔 Prelude: When writing Rust programs, Result and Option are data structures we can hardly avoid. I believe that rather than understanding their underlying mechanisms, we should first quickly figure out how to handle them. Gift Wrapping Actually, we don’t need to think of Option<T> and Result<T,E> as too complicated: Option contains the data we want, where the data type is T. However, there might be no data inside (None). But regardless, as long as what we care about is wrapped, it will be an Option. Result also contains the data we want, but it comes with another “restless” additional item E (Error). In fact, combinations of Result and Option are very common, such as Result<Option<T>, E>. Result provides a powerful and unified specification for Rust’s error handling. So, how do we open the gift box… The moment of unwrapping gifts is always exciting. ...

2026-09-10

Vim in (not so) short

🔔 Prelude: Yes, You can always type :h to see help, for example, :h windows Vim in not so short Preliminaries When vim is not available, you can temporarily use cat or nano as alternatives When using a new IDE, you should first learn or configure: save copy / paste duplicate line delete word / delete line line movement navigate forward / back undo / redo page navigation (page down, page up, center to middle, etc.) indent / unindent multi-cursor search / content search input commands (Ctrl + P in VSCode, double Shift in IntelliJ, : in vim…) completion, suggestion, parameter hint, hover hint go to / peek definition, type, declaration, reference, implementation rename symbol / refactor (if available) AI controlling: toggle chat box, trigger inline chat… tabs / windows management Use the :help command to query anything you don’t understand :set option? can view current settings Windows and Tabs Buffer: Can be understood as a temporary file. Even if this file is edited, it doesn’t mean it’s written to the actual file. We can observe buffers through windows and manage them through tabs. ...

2026-09-10

Golang in short

🔔 Prelude: No need for digging a big hole, just use it. Golang in short Go is A modern high-level programming language that resembles C Open-source, compiled, statically typed, and memory-safe Go has Simple yet powerful package management (pulls directly from GitHub) Built-in concurrency primitives Garbage collection (GC) Lightning-fast compilation Minimal syntax Cross-platform compilation Go doesn’t have Classes and inheritance Function overloading Implicit type conversions I use Go to Say goodbye to Java’s verbose syntax Build web services and microservices Handle high-concurrency scenarios Go is perfect for Web services and RESTful APIs Microservices architecture Network programming and distributed systems Go might not be ideal for GUI desktop applications Kernel development Machine learning (Python has a stronger ecosystem) Installing Go Using OS package managers Linux: apt, yum, snap macOS: brew Windows: choco, scoop, etc. Download official precompiled binaries Already compiled, ready to use Set up path and links manually Verify with go version Hello World // This is a comment /* This is a multiline comment */ package main // This is the main package // No semicolons at line endings import ( "fmt" "math" ) // Importing other packages const myConstant int = 0 // Constants need explicit initialization func main() { fmt.Println("helloworld") // Package names -> lowercase // Lowercase in package -> myConstant -> package-private // Capitalized -> Println() -> exported (public) } Types bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr // Has pointers but no pointer arithmetic byte // alias for uint8 rune // alias for int32 // Represents a Unicode code point // From ancient Nordic "rune" float32 float64 complex64 complex128 // Zero value for reference types is nil // Type assertion t, ok := variable.(int) // Returns two values, ok indicates success // Panics if ok is not captured and type is wrong // Type conversion var myInt int32 = 42 myAnotherInt := int64(myInt) // Type conversion // No direct conversion between bool and int // Generally, single characters and numbers can convert // Otherwise, only conversions within same type family Variables and Functions var hi bool = true // Variables outside functions must have explicit types func myFunc(x, y int) (int, int) { innerHi := "hi" // Inside functions, use := for type inference const hiConst = "hi again" // Constants cannot use := return x + 1, y + 1 } func MapFilter[T any, R comparable]( slice []T, mapper func(T) R, predicate func(R) bool, ) func(options ...int) (filtered []R, count int, err error) { // Returns a function return func(options ...int) (filtered []R, count int, err error) { // Implementation return } } // A complete function signature example // Note the second func starts parameters // The last func starts return type -> returns a function // T is generic, R is constraint, but they're essentially the same thing func(x int) int { return x * 2 } // Anonymous function definition Arrays, Slices, and Maps // Arrays - fixed length var arr [5]int = [5]int{1, 2, 3, 4, 5} arr2 := [...]int{1, 2, 3} // Compiler infers length // Slices - dynamic length var slice []int = []int{1, 2, 3} slice2 := make([]int, 5) // Length 5 slice3 := make([]int, 5, 10) // Length 5, capacity 10 // Maps var m map[string]int = map[string]int{"one": 1, "two": 2} m2 := make(map[string]int) m2["key"] = 42 // Check if key exists value, exists := m["key"] if exists { fmt.Println(value) } Control Flow // Only for loops exist // All parts of for loop are optional for i := 0; i < 10; i++ { // Loop body } // Infinite loop for { // Equivalent to while(true) } // Condition loop i := 0 for i < 10 { i++ } for i, v := range expression {} // Iterate over iterables // Similar to Python's for..in // Directly provides index and value // No enumerate function needed // Use _, v to ignore index // if statement if v := 5; v < 6 { // Can assign in condition // Condition body } // switch statement switch x := 5; x { // x is optional case 1: fmt.Println("one") case 2, 3, 4: // Multiple values fmt.Println("two, three or four") default: fmt.Println("other") } // Type switch switch v := x.(type) { case int: fmt.Printf("int: %d\n", v) case string: fmt.Printf("string: %s\n", v) default: fmt.Printf("unknown type\n") } Defer and Channels // defer - deferred execution (stack structure, LIFO) defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) panic("!") // Output order: 3 2 1 panic // defer provides stack-based deferred execution // panic triggers deferred functions // channel - channels (queue structure, FIFO) func channelExample() { myChan := make(chan int, 2) // Buffer size 2 myChan <- 10 // 10 goes in myChan <- 20 // then 20 goes in took := <-myChan // took is 10 fmt.Println(<-myChan) // 20 } func blockingChannel() { ch := make(chan int) // Unbuffered channel // ch <- 1 // Will block! Need another goroutine to receive // Correct approach go func() { ch <- 1 }() fmt.Println(<-ch) } // Channels provide a queue-like or pipe-like structure // FIFO Pointers // Go has pointers // Useful when referencing large data // Go's design philosophy is very close to C-family languages // Fun fact: When passing pointers to functions, both C and Go copy the pointer // All parameters are pass-by-value in both languages // But C++ has completely different reference passing mechanism func main() { var myPtr *int // var anotherPtr uintptr // uintptr is integer type, not pointer i := 42 myPtr = &i // Take address fmt.Println(*myPtr) // Dereference, outputs 42 *myPtr = 43 // Modify through pointer fmt.Println(i) // Outputs 43 // No pointer arithmetic } Format Verbs Verb Description Example Output %v (value) Default format Printf("%v", people) {zhangsan} %+v Adds field names for structs Printf("%+v", people) {Name:zhangsan} %#v Go syntax representation Printf("%#v", people) main.Human{Name:“zhangsan”} %T (type) Type in Go syntax Printf("%T", people) main.Human %% Percent sign Printf("%%") % %t (true) true or false Printf("%t", true) true %b (binary) Binary representation Printf("%b", 5) 101 %c (char) Unicode character Printf("%c", 0x4E2D) 中 %d (decimal) Decimal Printf("%d", 0x12) 18 %o (octal) Octal Printf("%o", 10) 12 %q (quote) Single-quoted character literal Printf("%q", 0x4E2D) ‘中’ %x Hexadecimal, lowercase Printf("%x", 13) d %X Hexadecimal, uppercase Printf("%X", 13) D %U (unicode) Unicode format: U+1234 Printf("%U", 0x4E2D) U+4E2D %b Binary exponent scientific notation Printf("%b", 10.5) 5835037194198p-49 %e Scientific notation Printf("%e", 10.2) 1.020000e+01 %E Scientific notation Printf("%E", 10.2) 1.020000E+01 %f (float) Decimal point, no exponent Printf("%f", 10.2) 10.200000 %g Compact format (%e or %f) Printf("%g", 10.20) 10.2 %G Compact format (%E or %f) Printf("%G", 10.20) 10.2 %s (string) String (string or []byte) Printf("%s", []byte(“Go”)) Go %q Double-quoted string Printf("%q", “Go”) “Go” %x Hex, lowercase, two chars per byte Printf("%x", “golang”) 676f6c616e67 %X Hex, uppercase, two chars per byte Printf("%X", “golang”) 676F6C616E67 %p (pointer) Hexadecimal with 0x prefix Printf("%p", &people) 0x4f57f0 + Always print sign; ASCII-only for %+q Printf("%+q", “中文”) “\u4e2d\u6587” - Pad with spaces on right (left-align) # Alternate format: 0 prefix for octal (%#o), 0x for hex (%#x), etc. Printf("%#U", ‘中’) U+4E2D ‘中’ ’ ' Space for elided sign; spaces between bytes for hex 0 Pad with zeros; moves padding after sign for numbers Reference: ...

2026-09-10

Basic Makefile

🔔 Prelude: I often noticed Makefile files in the root directory when browsing open-source projects on GitHub. For a long time, I thought it was some kind of sophisticated “magic tool”. So during my spare time at my internship, I decided to learn some basic syntax… only to discover that it’s actually like a “recipe” for compilation - to get a target file (the dish), you need some dependencies (ingredients) and commands (cooking instructions). Anyway, at least now I can understand it (mostly). ...

2026-09-10

JVM in short

What is the JVM? Java programs need the JVM to run. Like .NET Framework. Stands for Java Virtual Machine. Java can run on multiple platforms because JVMs are implemented for different systems. So, Java programs can run on any platform that has a JVM (Though JVM may be different). It executes bytecode, which is translated from Java code. Oh, and Kotlin code can also be compiled into bytecode. What are JRE, JDK, and JAR? JRE (Java Runtime Environment) – It’s what Java needs to run, includes the JVM. JDK (Java Development Kit) – The toolkit for Java developers (You need it to do developing things), and it includes the JRE. It also contains the javac compiler, which turns your code into bytecode. JAR (Java ARchive) – A zip file specifically for Java programs. If everything’s set up correctly, you can run it directly. What is the JVM made of? Class Loader Subsystem – Finds your classes. Runtime Data Area – Contains the native method stack, Java method stack, method area, PC Registers, and heap. Native Method Stack – For calling code in other languages (mainly C++). Java Method Stack – For storing Java function call stacks. PC Registers – Tells the interpreter where to go next. Fact: It’s the only area that won’t throw an OutOfMemoryError. Method Area – Holds class-related info. It’s shared between threads. Heap – Just the heap, shared between threads. Anything not explicitly mentioned is thread-private. Execution Engine – Interpreter, JIT (Just-In-Time compiler), and GC (Garbage Collector). Native Method Library. Class Loader Subsystem? MyClass.java -> Loading (find the class) -> Linking -> Verify, Prepare, Resolve -> Initialization. Verify – Did you write your class correctly? Prepare – Allocates memory for static variables and sets them to default. Resolve – Turns symbolic references (names) into direct references (addresses). Loading: Class Loaders Everything’s an object in Java, even the classes themselves are loaded by class loader objects. ...

2026-09-10

Simple Tree Traversal

🖋️ Leaf-Similar Trees (Leetcode 872) In short, we are gonna to compare the leaves between two tree. First, we should get the elements from the leaves. # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def dfs(self, root, list_para): temp = [] curr = root while curr is not None or len(temp) > 0: while curr: temp.append(curr) curr = curr.left // Save all elements on the left side, but // we only want the leaf element, so... curr = temp.pop() if curr.left is None and curr.right is None: list_para.append(curr.val) curr = curr.right // Attention here, we 'move' our 'pointer' to the right side // After we have done all the things we should do on the left side def leafSimilar(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool: l1 = [] l2 = [] self.dfs(root1, l1) self.dfs(root2, l2) return l1 == l2 Recursion Method class Solution: def dfs(self, root, list_para): if root is None: return if root.left is None and root.right is None: list_para.append(root.val) // **Move** to the left, do it again, **until 'root is None'** self.dfs(root.left, list_para) // Left side finished // **Move** to the right, do it again, **until 'root is None'** self.dfs(root.right, list_para) // Right side finished, all required data is saved in the list_para def leafSimilar(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool: l1 = [] l2 = [] self.dfs(root1, l1) self.dfs(root2, l2) return l1 == l2

2026-09-10

Two Ways to Reverse a Singly Linked List

0. Structure of a Singly Linked List class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next // 1 -> 2 -> 3 -> 4 -> 5 -> NULL 1. Move pointers def reverseList(head: ListNode) -> ListNode: prev = None curr = head while curr: temp = curr.next # Save next node curr.next = prev # Reverse the pointer prev = curr # Move prev forward curr = temp # Move curr forward return prev # New head of the reversed list 0: 1 -> None 2 -> 3 -> 4 -> 5 -> NULL 1: 2 -> 1 -> None 3 -> 4 -> 5 -> NULL ...

2026-09-10

Rust Notes 4

Range Rather than using C style loop, in Rust, we use ..= to indicate a range: for i in 1..=5 { println!("{}",i); } Output: 1 2 3 4 5 Sequences are only allowed for numeric or character types because they can be consecutive. for i in 'a'..='z' { println!("{}",i); } Char Use '' . "" is for the string fn main() { let c = 'z'; let z = 'ℤ'; let cat= '😻'; } Accept Unicode, occupy 4 bytes. ...

2026-09-10

Lagrange Interpolation Method

🖋️ Starting from known points Given the task of constructing a function f(x) f(x) f(x)that passes through the points P1(x1,y1),P2(x2,y2),⋯ ,Pn(xn,yn) P_1(x_1, y_1), P_2(x_2, y_2), \cdots, P_n(x_n, y_n) P1​(x1​,y1​),P2​(x2​,y2​),⋯,Pn​(xn​,yn​), first let the projection of the i th point onto the x axis be ...

2026-09-10