使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式開發環境

目錄

  • 0.課程大綱
  • 1.為什么要使用QEMU學習嵌入式
    • QEMU簡介
    • 使用QEMU可以做哪些事情?
    • 當前嵌入式行業現狀
    • 如何適應這種變化
    • 使用QEMU學習嵌入式有哪些好處?
    • 驅動開發技能
    • 為什么要學習Linux
  • 2.搭建嵌入式開發基本環境
    • 2.1.安裝u-boot-tools
    • 2.2.安裝交叉編譯工具
      • 什么是ABI和EABI
  • 3.QEMU安裝及仿真開發板介紹
    • 自動安裝
    • 手動編譯安裝
    • QEMU使用
    • ARM express 開發板簡介
      • Vexpress系列開發板
      • Vexpress系列支持的CPU
      • 嵌入式最小系統
    • QEMU運行系統
  • 4.編譯Linux內核和dtb文件
    • 4.1.下載Linux內核
    • 4.2.修改Makefile
    • 4.3.編譯內核,模塊,dtb文件
  • 5.使用Busybox制作根文件系統
    • 5.1.什么是根文件系統?
      • 5.1.1.文件系統
      • 5.1.2.為什么要使用文件系統
      • 5.1.3.根文件系統
    • 5.2.使用busybox制作根文件系統
      • 5.2.1.什么是busybox
      • 5.2.2.編譯安裝
      • 5.2.3.制作根文件系統
      • 5.2.4.制作SD卡文件系統鏡像
  • 6.使用u-boot引導啟動Linux內核
    • 6.1.嵌入式啟動概述
      • 6.1.1.嵌入式bootloader
      • 6.1.2.常見的啟動方式
    • 6.2.u-boot編譯
    • 6.3.QEMU網絡功能設置
      • 6.3.1.配置QEMU與主機的網絡連接
      • 6.3.2.配置
    • 6.4.內核配置編譯
      • 6.4.1.使用u-boot引導內核鏡像
    • 6.5.主機TFTP工具安裝
    • 6.6.啟動測試
    • 6.7.自動化引導
  • 參考資料

0.課程大綱

  1. 為什么要使用QEMU學習嵌入式
  2. 搭建嵌入式開發基本環境
  3. QEMU安裝及A9開發板配置介紹
  4. 編譯,運行Linux內核
  5. 使用Busybox制作根文件系統
  6. 使用u-boot引導啟動Linux內核
  7. 掛載NFS文件系統
  8. 在虛擬開發板上開發應用程序,驅動

1.為什么要使用QEMU學習嵌入式

QEMU簡介

  • QEMU是一個模擬器,可以模擬CPU,ARM,X86,MIPS等架構
  • 可以仿真的ARM處理器:ARM926E,ARM1136,Cortex-A8/A9
  • 模擬真實的開發板,外設:串口,LCD,網卡,USB,SD卡…

使用QEMU可以做哪些事情?

  • 研究內核虛擬化
  • 模擬CPU,對于芯片公司,流片之前在QEMU上做驗證,仿真,軟硬件協同設計,開發BSP和驅動
  • 模擬開發板,在模擬平臺上進行系統軟件開發,驅動開發
  • 學生,工程師可以利用qemu-system-arm學習嵌入式開發,研究Bootloader,Linux內核,驅動開發,應用開發等.

當前嵌入式行業現狀

  • CPU廠家越來越多,各種開發板層出不窮
  • 物聯網芯片,AI芯片…
  • SOC越來越集成化,軟硬件分工越來越明顯

如何適應這種變化

  • 分工
  • 精專
  • 嵌入式80%的知識系統和技能,都可以脫離"開發板",在QEMU仿真平臺上學習和練習

使用QEMU學習嵌入式有哪些好處?

  • 節省學習成本
  • 跳過開發板,硬件的各種"坑",縮短學習曲線
  • 重構嵌入式知識體系和技能,跟硬件無關的放到QEMU上學習
  • 跟開發板相關的驅動,BSP針對具體開發板深入突破
  • 適應不同CPU,開發板的技術要求

驅動開發技能

  • 基本的硬件知識
  • Linux內核,系統架構的理解
  • 芯片手冊,開發板

為什么要學習Linux

  • 開源,免費

  • 持續更新,強大的BSP支持

  • Android,YunOS,Tizen,ubuntu等操作系統的內核

  • 應用領域廣:嵌入式,服務器,桌面PC,云…

  • 示例

2.搭建嵌入式開發基本環境

2.1.安裝u-boot-tools

  • 用來生成適應U-boot引導的鏡像文件格式
sudo apt install -y u-boot-tools

2.2.安裝交叉編譯工具

什么是ABI和EABI

  • ABI:二進制應用程序接口(Application Binary Interface(ABI) for the ARM Architecture),在計算機中,應用二進制接口描述了應用程序(或者其他類型)和操作系統之間或其他應用程序的低級接口,涵蓋了數據類型的大小,布局和對齊,調用約定.
  • EABI:嵌入式ABI 嵌入式應用二進制接口指定了文件格式,數據類型,寄存器使用,堆積組織優化和在一個嵌入式軟件中的參數的標準約定.
  • Arm-none-gnueabi-linux比arm-linux-gcc要好,在可一致性,兼容性上面
  • 早期u-boot和Linux編譯可能使用的都不是一個arm-linux-gcc版本
sudo apt install -y gcc-arm-linux-gnueabi
sudo apt install -y g++-arm-linux-gnueabi
#區別
gcc-arm-linux-gnueabi    
gcc-arm-linux-gnueabihf
gcc-arm-none-eabi
arm-linux-gnueabi-gcc -v
arm-linux-gnueabi-gcc -o hello main.c
readelf -h hello

3.QEMU安裝及仿真開發板介紹

自動安裝

# For full system emulation
sudo apt install qemu-system#For emulating Linux binaries
sudo apt install qemu-user-static

手動編譯安裝

https://www.qemu.org/
https://wiki.qemu.org/Hosts/Linuxgit clone https://gitlab.com/qemu-project/qemu.git
git checkout remotes/origin/stable-8.2 -b stable-8.2sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-buildsudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev sudo apt-get install libnfs-dev libiscsi-dev./configure --target-list=arm-softmmu --audio-drv-list=
make 
sudo make install

QEMU使用

qemu-system-arm --version#查看支持的開發板
qemu-system-arm -M help
#vexpress-a9

ARM express 開發板簡介

Vexpress系列開發板

  • 全稱versatile express family, ARM公司自己推出的開發板
  • 主要用于SOC廠商設計,驗證和測試自己的SOC芯片
  • 采用主板+子板設計,主板提供各種外圍接口,子板提供CPU運算

Vexpress系列支持的CPU

  • Cortex-A9: 處理器子板 Express A9x4 (V2P-CA9x4)
  • Cortex-A5: 處理器子板 Express A5x2 (V2P-CA5x2s)
  • Cortex-R5:
  • Cortex-A15: 處理器子板 Express A15x2 (V2P-CA15x2)
    在這里插入圖片描述
    在這里插入圖片描述
    在這里插入圖片描述
    在這里插入圖片描述
    在這里插入圖片描述
DDR
外圍
DUI0448I_v2p_ca9_trm.pdf

嵌入式最小系統

CPU+DDR/SDRAM
FLASH/SD
串口+LCD

QEMU運行系統

#-M vexpress-a : 指定具體開發板
#-m 512M : 指定內存大小
#-kernel ./zImage : 指定內核
#-dtb ./vexpress-v2p-ca9.dtb : 指定設備樹
#-nographic : 不使用圖像界面
#-append "console=ttyAMA0" : 指定串口控制臺
qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"

4.編譯Linux內核和dtb文件

4.1.下載Linux內核

https://www.kernel.org/
longterm

4.2.修改Makefile

vim Makefile
ARCH        ?= arm
CROSS_COMPILE ?=arm-linux-gnueabi-

4.3.編譯內核,模塊,dtb文件

make vexpress_defconfig
make zImage
make modules
make dtbs

5.使用Busybox制作根文件系統

5.1.什么是根文件系統?

5.1.1.文件系統

對存儲設備上的數據進行組織的機制

5.1.2.為什么要使用文件系統

  • Linux的哲學: 一切皆文件
  • 用戶與操作系統進行交互的主要工具: 文件系統調用
  • 用戶和底層存儲的接口

5.1.3.根文件系統

  • Linux內核啟動后第一個掛載的文件系統
  • 主要由基本的shell命令,各種庫,字符設備,配置腳本組成
  • 提供了根目錄/
  • RFS可以放在: nor/nand flash, SD卡, 磁盤, 網絡空間上

5.2.使用busybox制作根文件系統

5.2.1.什么是busybox

  • 一個集成100多個Linux常用命令和工具的軟件
  • 一個適合制作嵌入式文件系統的軟件工具

5.2.2.編譯安裝

#1.下載源代碼
https://busybox.net/
#2.修改Makefile
ARCH ?= arm
CROSS_COMPILE ?=arm-linux-gnueabi-
#3.配置
make defconfig
make menuconfigSettings  --->  [*] Build static binary (no shared libs)
#4.編譯
make -j2
#5.安裝
make install
#安裝生成目錄"_install"

5.2.3.制作根文件系統

mkdir rootfs
cd rootfs/
mkdir lib
cp -avf busybox-1.36.1/_install/* rootfs/
cp -avf /usr/arm-linux-gnueabi/lib/* rootfs/lib/
mkdir dev
cd dev/#mknod: 創建塊或字符設備節點
#-m 666: 權限讀寫
#tty1: 節點名稱
#c: 字符設備
#4: 主設備號
#1: 次設備號
sudo mknod -m 666 tty1 c 4 1
sudo mknod -m 666 tty2 c 4 2
sudo mknod -m 666 tty3 c 4 3
sudo mknod -m 666 tty4 c 4 4sudo mknod -m 666 console c 5 1sudo mknod -m 666 null c 1 3

5.2.4.制作SD卡文件系統鏡像

#1.生成鏡像
#bs: 緩沖區塊的大小
#count: 塊的個數
dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
#2.格式化為ext3文件系統
mkfs.ext3 rootfs.ext3
#3.將各種文件copy到文件系統鏡像中
sudo mount -t ext3 rootfs.ext3 /mnt -o loop
sudo cp -avf rootfs/* /mnt
sudo umount /mnt

6.使用u-boot引導啟動Linux內核

6.1.嵌入式啟動概述

6.1.1.嵌入式bootloader

  • 功能類似于PC的BIOS,硬件檢測是否正常
  • 加載操作系統鏡像到RAM
  • 設置不同的啟動方式

6.1.2.常見的啟動方式

  • NOR/NAND FLASH啟動
  • 從SD卡啟動
  • Bootloader從網絡加載Linux內核啟動

6.2.u-boot編譯

#1.下載u-boot
git clone https://gitee.com/naonano/u-boot.git
git checkout --track origin/u-boot-2023.07.y#2.修改 Makefile
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
CROSS_COMPILE ?=arm-linux-gnueabi-#3.修改 config.mk
#ARCH := $(CONFIG_SYS_ARCH:"%"=%)
ARCH := arm#4.配置
make vexpress_ca9x4_defconfig#5.編譯
make -j2#6.運行u-boot
qemu-system-arm -M vexpress-a9 -m 512M -nographic -kernel ../test/u-boot/u-boot

6.3.QEMU網絡功能設置

6.3.1.配置QEMU與主機的網絡連接

  • 采用橋接(bridge)的網絡連接與Host通信
  • 需要主機內核tun/tap模塊支持

6.3.2.配置

參考:ubuntu 22.04 設置網橋 - netplan

#1.主機安裝工具包
sudo apt install -y uml-utilities bridge-utils
#2.創建tun設備文件
ls -al /dev/net/tun
#3.編輯文件
sudo touch /etc/netplan/br0.yaml
#使用ipv4 dhcp

ipv4 dhcp:

network:version: 2ethernets:enp0s8: #替換為實際網卡dhcp4: falsedhcp6: falsebridges:br0:interfaces: [enp0s8] #替換為實際網卡dhcp4: trueparameters:stp: falsedhcp6: false

ipv4 靜態分配:

network:version: 2ethernets:enp0s8:#替換為實際網卡dhcp4: falsedhcp6: falsebridges:br0:interfaces: [enp0s8] #替換為實際網卡dhcp4: falseaddresses: [192.168.1.250/24]routes:- to: defaultvia: 192.168.1.1nameservers:addresses: [114.114.114.114]parameters:stp: falsedhcp6: true
sudo netplan apply

ifconfig

br0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500inet 192.168.1.25  netmask 255.255.255.0  broadcast 192.168.1.255inet6 fe80::3027:2dff:fe41:8595  prefixlen 64  scopeid 0x20<link>ether 32:27:2d:41:85:95  txqueuelen 1000  (Ethernet)RX packets 55  bytes 9272 (9.2 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 89  bytes 12062 (12.0 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.1.3  netmask 255.255.255.0  broadcast 192.168.1.255inet6 fe80::c8ff:ec6f:253e:ad4e  prefixlen 64  scopeid 0x20<link>inet6 2409:8a1e:d52:a9b0:39df:8d80:83d3:9e  prefixlen 64  scopeid 0x0<global>inet6 2409:8a1e:d52:a9b0:3292:9a45:5481:28ad  prefixlen 64  scopeid 0x0<global>ether 08:00:27:05:ef:4f  txqueuelen 1000  (Ethernet)RX packets 962  bytes 156528 (156.5 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 836  bytes 88212 (88.2 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::1  prefixlen 128  scopeid 0x10<host>loop  txqueuelen 1000  (Local Loopback)RX packets 318  bytes 29095 (29.0 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 318  bytes 29095 (29.0 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

6.4.內核配置編譯

6.4.1.使用u-boot引導內核鏡像

#需要將內核編譯為uImage格式
#需要指定uImage的加載地址
#編譯時指定: 
make LOADADDR=0x60003000 uImage -j2

6.5.主機TFTP工具安裝

#1.安裝
sudo apt-get install -y tftpd-hpa tftp-hpa xinetd
#2.配置ftp服務器工作目錄為"/home/tftp"
sudo vim /etc/default/tftpd-hpaTFTP_USERNAME="tftp"TFTP_DIRECTORY="/home/tftp"TFTP_ADDRESS=":69"TFTP_OPTIONS="-l -c -s"
#3.建立目錄
sudo mkdir -p /home/tftp
sudo chown lei:lei /home/tftp
chmod 777 -R /home/tftp
#4.啟動服務
sudo service tftpd-hpa restart
#5.測試
#5.1測試下載
cd /home/tftp/
touch readme.txt
#在readme.txt中輸入一些內容
#運行開發板,進入控制臺
tftp -g -r readme.txt 192.168.10.107
#可以看出在開發板當前目錄下下載了readme.txt
#5.2測試上傳
#在開發板上,進入控制臺運行命令
tftp -p -l uvc_app 192.168.10.107
#uvc_app為開發板當前目錄下的文件
#在ubuntu上可以看到開發板上傳上來的文件uvc_app

6.6.啟動測試

#1.復制u-boot鏡像到tftp服務器目錄下
cp /home/qemu/test/u-boot/u-boot /home/tftp/
#2.復制uImage鏡像到tftp服務器目錄下
cp /home/qemu/test/linux-6.6.18/arch/arm/boot/uImage /home/tftp/
#3.復制設備樹二進制編譯結果到tftp服務器目錄下
cp /home/qemu/test/linux-6.6.18/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb /home/tftp/
#4.uboot引導kernel啟動
qemu-system-arm \-M vexpress-a9 \-m 512M \-nographic \-kernel /home/tftp/u-boot \-net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \-sd /home/qemu/test/rootfs.ext3

6.7.自動化引導

u-boot/include/configs/vexpress_common.h

#define CONFIG_BOOTCOMMAND \"tftp 0x60003000 uImage; tftp 0x60500000 vexpress-v2p-ca9.dtb; \setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0'; \bootm 0x60003000 - 0x60500000; "#define CONFIG_IPADDR 192.168.244.128
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.244.129

參考資料

B站

QEMU系列文章: https://blog.csdn.net/phmatthaus/category_12072874.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三、基準時鐘、生成時鐘、虛擬時鐘的約束和意義

**前言&#xff1a;**前面從理論角度出發學習了時序分析的基本原理&#xff0c;本篇從設計的角度學習如何合理添加時鐘約束。 文章目錄 一、基準時鐘&#xff08;base clock&#xff09;和生成時鐘(generate clock)二、基準時鐘的約束1.完成綜合&#xff08;run implementatio…

linux的通信方案(SYSTEM V)

文章目錄 共享內存(Share Memory)信號隊列&#xff08;Message Queue&#xff09;信號量(semaphore) 進程間通信的核心理念&#xff1a;讓不同的進程看見同一塊資源 linux下的通信方案&#xff1a; SYSTEM V 共享內存(Share Memory) 特點&#xff1a;1.共享內存是進程見通信最…

排序(4)——堆排序

目錄 堆排序&#xff08;回顧&#xff09; 基本思路 代碼實現 向下調整排序 AdjustDown 建堆排序 時間復雜度 特性總結 堆排序&#xff08;回顧&#xff09; 重點回顧戳&#x1f449;堆排序 基本思路 堆排序(Heapsort)是指利用堆積樹&#xff08;堆&#xff09;這種數…

SOCKS5代理、代理IP與網絡安全的奇妙旅程

在數字時代&#xff0c;互聯網安全和隱私成為了熱門話題。從個人瀏覽習慣到企業數據保護&#xff0c;每個人都希望他們的在線活動既安全又私密。在這個背景下&#xff0c;了解SOCKS5代理、代理IP、HTTP協議和網絡安全的基礎知識變得尤為重要。 什么是SOCKS5代理&#xff1f; SO…

鴻蒙系統開發適配注意事項

鴻蒙操作系統&#xff08;HarmonyOS&#xff09;的軟件適配涉及到一些特定的注意事項&#xff0c;以確保應用程序在該操作系統上的正常運行和最佳性能。以下是適配鴻蒙軟件時需要注意的一些關鍵問題&#xff0c;希望對大家有所幫助。北京木奇移動技術有限公司&#xff0c;專業的…

MySQL篇—執行計劃介紹(第二篇,總共三篇)

??博主介紹??&#xff1a; ?又是一天沒白過&#xff0c;我是奈斯&#xff0c;DBA一名? ???擅長Oracle、MySQL、SQLserver、Linux&#xff0c;也在積極的擴展IT方向的其他知識面??? ??????大佬們都喜歡靜靜的看文章&#xff0c;并且也會默默的點贊收藏加關注?…

Python 編輯工具 Jupyter notebook

Jupyter notebook Jupyter Notebook是基于網頁的用于交互計算的應用程序。其可被應用于全過程計算&#xff1a;開發、文檔編寫、運行代碼和展示結果。——Jupyter Notebook官方介紹 官網&#xff1a;Project Jupyter | Home Jupyter Notebook 是一個開源的交互式計算環境&#…

dockerdocker-copose_限制容器cpu和內存

本文目錄 docker的限制方式限制CPU占用限制內存占用 docker-compose docker的限制方式 限制CPU占用 Docker使用--cpus參數來限制容器的CPU資源。該參數指定了分配給容器的CPU核心數量或百分比。 例子&#xff1a;限制CPU使用個數 docker run --cpus2 <imageName>以上…

網頁版圖像處理軟件開發服務:助您項目在市場競爭中脫穎而出

在當今數字化時代&#xff0c;圖像處理在各個行業中扮演著重要的角色&#xff0c;虎克專注于提供定制化的網頁版圖像處理軟件開發服務&#xff0c;為您的項目保駕護航。 1.網頁版圖像處理軟件的定制化需求 1.1行業特定功能 針對不同的業務需求&#xff0c;深入了解行業特點&…

springboot基于web的酒店客房管理系統論文

基于web的酒店客房管理系統 摘要 隨著信息技術在管理上越來越深入而廣泛的應用&#xff0c;管理信息系統的實施在技術上已逐步成熟。本文介紹了酒店客房管理系統的開發全過程。通過分析酒店客房管理系統管理的不足&#xff0c;創建了一個計算機管理酒店客房管理系統的方案。文…

Redis 之八:Jdeis API 的使用(Java 操作 Redis)

Jedis API 使用 Jedis 是 Redis 官方推薦的 Java 客戶端&#xff0c;它提供了一套豐富的 API 來操作 Redis 服務器。通過 Jedis API&#xff0c;開發者可以方便地在 Java 應用程序中執行 Redis 的命令來實現數據的增刪查改以及各種復雜的數據結構操作。 以下是一些基本的 Jedis…

springboot網站開發-idea開發環境下無法開啟調試Debug模式

springboot網站開發-idea開發環境下無法開啟調試Debug模式的解決辦法。 近期在寫后端代碼的時候&#xff0c;發現&#xff0c;無法開啟調試模式。網上查詢了一下資料&#xff0c;發現需要做如下修改即可開啟調試模式。 如圖所示&#xff0c;把里面的選項&#xff0c;都放棄勾選…

SQLPro Studio:數據庫管理的革命性工具 mac版

SQLPro Studio是一款強大的數據庫管理和開發工具&#xff0c;它旨在提供高效、便捷和安全的數據庫操作體驗。無論是數據庫管理員、開發人員還是數據分析師&#xff0c;SQLPro Studio都能滿足他們在數據庫管理、查詢、設計和維護方面的需求。 SQLPro Studio mac版軟件獲取 首先…

B樹系列(詳解)

目錄 一、B-樹 二、B樹 三、B*樹 四、時間復雜度 五、Mysql與B樹系列 一、B-樹 首先再說B樹的性質以及其他的之前&#xff0c;先要說一聲&#xff0c;好多人都把這個樹叫B減樹&#xff0c;其實不是&#xff0c;他就叫B樹&#xff0c;至于原因我覺的沒必要再這個名字上糾結…

docker 轉為docker-compose(composerize 命令)

可以使用Composerize將Docker命令轉換為Docker Compose文件。 例如&#xff1a;將docker run命令轉換為Docker Compose格式&#xff0c;只需用Composerize運行它&#xff0c;如下所示&#xff1a; composerize docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/…

【JavaSE】異常

異常概述 異常指的是程序在執行的過程中&#xff0c;出現的非正常情況&#xff0c;如果不處理最終會導致JVM的非正常停止。 在Java中&#xff0c;使用不同的類來表示不同的異常&#xff08;正所謂萬物皆對象&#xff0c;因此異常也使用類來表示&#xff09;。一旦程序出現某種…

【HTML】HTML基礎5(特殊字符)

目錄 特殊字符的作用 常用的特殊字符 使用效果 特殊字符的作用 例如 當我在兩個文字間打出空格時 <p>“銀河護衛隊”系列 在漫威電影宇宙中一直是異數般的存在&#xff0c;不僅因為影片主角是一群反英雄&#xff0c;<strong>與超級英雄相比顯得格格不入<…

讀書筆記-三國演義-三英戰呂布

三英戰呂布是《三國演義》中的一段著名戰役&#xff0c;張飛、關羽和劉備三兄弟聯手擊敗了當時的霸主呂布&#xff0c;展現了他們的武藝和忠義。 介紹 "三英戰呂布"是《三國演義》中的一個著名戰役&#xff0c;發生在三國時期&#xff0c;講述了三位蜀漢名將——劉…

LeetCode 刷題 [C++] 第347題.前 K 個高頻元素

題目描述 給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回其中出現頻率前 k 高的元素。你可以按 任意順序 返回答案。 題目分析 據題意可知&#xff0c;我們需要先遍歷整個數組&#xff0c;并統計每個數字出現的次數&#xff0c;保存在哈希表中&#xff1b;對元素…

synchrosized 的可重入特性、死鎖、哲學家就餐問題以及解決死鎖的方法等干貨

文章目錄 &#x1f490;synchrosized的可重入特性關于死鎖&#xff1a;哲學家就餐問題&#x1f4a1;如何避免/解決死鎖 &#x1f490;synchrosized的可重入特性 可重入特性&#xff1a;當一個線程針對一個對象同時加鎖多次&#xff0c;不會構成死鎖&#xff0c;這樣的特性稱為…