DIY台式机

计划配置一台和笔记本相同(相近)型号配置的台式机

目前笔记本型号:Vivobook_ASUSLaptop M7600QE

MB (main board):ASUSTeK COMPUTER

制造商: ASUSTeK COMPUTER INC.
产品名称: Vivobook_ASUSLaptop M7600QE_M7600QE
版本: 1.0
序列号: N1N0CX03A800017
UUID: 9299a24f-4296-0d43-9578-44845ede2179
唤醒类型: 电源开关
SKU编号:
系列: Vivobook

句柄 0x0002, DMI类型 2, 15字节
主板信息
制造商: ASUSTeK COMPUTER INC.
产品名称: M7600QE
版本: 1.0
序列号: N101NBCX000766MB
资产标签: ATN12345678901234567

CPU:AMD® Ryzen 9 5900hx with radeon graphics × 16

架构:x86_64
CPU运行模式:32位,64位
地址大小:48位物理地址,48位虚拟地址
字节顺序:小端模式
CPU数量:16
在线CPU列表:0-15
厂商ID:AuthenticAMD
型号名称:AMD Ryzen 9 5900HX with Radeon Graphics
CPU系列:25
型号:80
每核心线程数:2
每个物理核心的核心数:8
插槽数量:1
步进:0
频率增强:已启用
CPU最大频率:4679.2959 MHz
CPU最小频率:1200.0000 MHz
BogoMIPS:6587.45
标志位:fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm
虚拟化功能:AMD-V
缓存:
L1d缓存:256 KiB(8个实例)
L1i缓存:256 KiB(8个实例)
L2缓存:4 MiB(8个实例)
L3缓存:16 MiB(1个实例)
NUMA(非一致性存储访问):
NUMA节点数:1
NUMA节点0的CPU:0-15
安全漏洞:
Itlb多重命中:不受影响
L1tf漏洞:不受影响
Mds漏洞:不受影响
Meltdown漏洞:不受影响
Mmio陈旧数据:不受影响
Retbleed漏洞:不受影响
Spec store bypass漏洞:通过prctl禁用了推测存储旁路
Spectre v1漏洞:通过用户空间拷贝/swapgs屏障和__user指针的清理来缓解
Spectre v2漏洞:通过Retpolines、IBPB条件、IBRS_FW、STIBP始终开启、RSB填充、PBRSB-eIBRS不受影响
Srbds漏洞:不受影响
Tsx async abort漏洞:不受影响

Disk:三星

Disk model: HFM512GD3JX013N                         
Disk model: SSD 970 EVO 500G

Mem: 美光科技 DDR4 8GB x 2

Set: 无
定位器: DIMM 0
插槽位置: P0 通道 A
类型: DDR4
类型详情: 同步非缓冲 (未注册)
速度: 3200 MT/s
制造商: Micron Technology
序列号: 00000000
资产标签: 未指定
零件编号: 4ATF1G64HZ-3G2E1
等级: 1
配置的内存速度: 3200 MT/s
最低电压: 1.2 V
最高电压: 1.2 V
配置的电压: 1.2 V
内存技术: DRAM
内存操作模式能力: 揮發性存储器
固件版本: 未知
模块制造商ID: 插槽 1,十六进制 0x2C
模块产品ID: 未知
内存子系统控制器制造商ID: 未知
内存子系统控制器产品ID: 未知
非易失性大小: 无
易失性大小: 8 GB

GPU: NVIDIA GeForce RTX 3050 Ti Mobile & Advanced Micro Devices, Inc.

*-独立显卡
描述: 3D 控制器
产品: GA107M [GeForce RTX 3050 Ti Mobile]
制造商: NVIDIA Corporation
物理标识: 0
总线信息: pci@0000:01:00.0
逻辑名称: /dev/fb0
版本: a1
宽度: 64 位
频率: 33MHz
功能: 电源管理、MSI、PCI Express、总线主控、ROM、帧缓冲
配置信息: 深度=32 驱动程序=nvidia 延迟=0 分辨率=2560x1600 可视颜色=truecolor 水平分辨率=2560 垂直分辨率=1600
资源: iomemory:fe0-fdf iomemory:ff0-fef IRQ:91 内存:fb000000-fbffffff 内存:fe00000000-feffffffff 内存:ff00000000-ff01ffffff I/O端口:e000(大小=128) 内存:fc000000-fc07ffff
*-CPU核显
描述: VGA 兼容控制器
产品: Cezanne
制造商: Advanced Micro Devices, Inc. [AMD/ATI]
物理标识: 0
总线信息: pci@0000:04:00.0
逻辑名称: /dev/fb0
版本: c4
宽度: 64 位
频率: 33MHz
功能: 电源管理、PCI Express、MSI-X、VGA 控制器、总线主控、帧缓冲
配置信息: 深度=32 驱动程序=amdgpu 延迟=0 分辨率=3840,2160
资源: iomemory:ff0-fef IRQ:50 内存:ff10000000-ff1fffffff 内存:ff20000000-ff201fffff I/O端口:d000(大小=256) 内存:fc500000-fc57ffff

台式装机注意事项

CPU选择

AMD R7 5800x3d

接口:AMD AM4|不支持核显|105W

京东 2099

主板选择

(ASUS)TUF GAMING B550M-PLUS WIFI II 重炮手

CPU接口 AMD AM4|DDR4 3800,4000 x4|wifi6 最大网络速度2500M|SATA x4|M.2(NVMe)x2|支持PCIE4.0 & 1个PCI Express x1 & 2个 PCI Express x16|电源接口24+8|版型M-ATX 24.4cm x 24.4cm

京东 829

显卡选择

微星(MSI)魔龙Z GeForce RTX 3060 GAMING Z TRIO 12G 超频版 

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 长324mm;宽140mm;高57mm|HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2299

七彩虹(Colorful) iGame GeForce RTX 3060 Advanced OC 12G L 1867MHz GDDR6

显存容量:12GB |电源接口8pin x 2 |三风扇| 尺寸 315.5 131 52 |HDMI,DP|建议电源 550W以上|Cuda 3584 1777MHz

京东 2399

微星(MSI)魔龙 GeForce RTX 4060 Ti GAMING X TRIO 8G 

显存GB| Cuda 4352 2670MHz|电源8pin x 1

三风扇,尺寸338 141 52|双风扇,尺寸247 130 42

京东 3598 3298

内存选择

美商海盗船(USCORSAIR)32GB(16G×2)套装 DDR4 3600 台式机内存条

京东 539

硬盘选择

三星(SAMSUNG)1TB SSD固态硬盘 M.2接口(NVMe协议PCIe 4.0 x4) 980 PRO (MZ-V8P1T0BW)

京东 549

散热器

水冷

利民(Thermalright)Frozen Magic 360冰封幻境一体式水冷散热器C12风扇多平台ARGB冷头 支持LGA1700|散热器尺寸397x120x27 |电源接口4pin|散热器高度52mm

京东 469

电源

硬件配置:首先要考虑你计划使用的硬件配置,包括主板、处理器、显卡、内存、存储设备等。不同的硬件配置对电源功率的需求有所不同。查阅各硬件组件的功耗规格,以了解它们的功率需求。主板(MB)功率+CPU功率+GPU功率+内存(Mem)功率+硬盘(Disk)功率+散热器功率

余量:为了确保电源的稳定性和可靠性,建议选择功率略高于实际需求的电源。保持一定的功率余量可以应对未来可能的升级或添加其他设备的情况。

80 PLUS认证:考虑选择具有80 PLUS认证的电源。80 PLUS认证是一项标准,用于衡量电源的能效水平。认证级别包括80 PLUS、80 PLUS Bronze、80 PLUS Silver、80 PLUS Gold、80 PLUS Platinum和80 PLUS Titanium,其中Titanium级别是效率最高的

品牌和质量:选择知名品牌的电源,这样更有保障质量和可靠性

先马(SAMA)ONCALL 750W 台式电脑主机箱电源 全模组/80PLUS金牌/台系电容/宽幅/节能温控/额定功率750W

支持3060 4060ti|长140mm;宽150mm;高86mm

京东 599

先马(SAMA)白金1200W 台式电脑机箱电源 80PLUS白金认证/全电压/固态电容/12cm风扇/全模组线材/额定1200W

支持4090,RX 6950 XT,更高功率显卡|长187.8mm;宽145.7mm;高86mm

京东 1099

机箱

主板型号要和机箱匹配,ATX,MATX, ITX三种,机箱尺寸

CPU散热器风扇高度

是否支持水冷位,128/240/280/360,水冷风扇厚度限制(冷排体积),水冷头高度(冷头体积)

电源体积限制,有电源仓的机箱,要注意,一般选择标准ATX电源 140 ,150,86

显卡体积限制,一般限制长度

硬盘位数量

理想价位300~700

品牌 乔思伯, 先马

主板+CPU 3000, 先开2000左右,内存+固态 1000左右 电源+机箱 1500左右 ,散热器500左右

Web音视频开发

Web音视频入门系列——音视频基础知识

Web 视频播放的那些事儿

音视频播放过程中的问题解决(播放质量优化)

Media container formats

HDR和SDR的区别

关于H.264的码率,720P、1080P输出比特率设置

mp4视频转换格式,使用H.264编码,比特率512-1024可以比较好的在大小和画面质量上取得平衡。其他编码或使用自动比特率,将导致mp4视频在页面中只有声音,没有画面。

文件的扩展名

MIME类型

容器格式

编码方式

视频基础概念

分辨率

1280×720 (720p) 1920×1080 (1080p) 2560×1440(2k) 3840×2160 (4k)

帧率

25fps,30fps,60fps

比特率(码率)

比特率是单位时间播放连续的媒体如压缩后的音频或视频的比特数量。

在这个意义上讲,它相当于术语数字带宽消耗量,或吞吐量。比特率规定使用“比特每秒”(bit/s或bps)为单位,经常和国际单位制词头关联在一起,如“千”(kbit/s或kbps),“兆”(百万)(Mbit/s或Mbps),“吉”(Gbit/s或Gbps)和“太”(Tbit/s或Tbps)
虽然经常作为“速度”的参考,比特率并不测量“‘距离’/时间”,而是被传输或者被处理的“‘二进制码数量’/时间”,所以应该把它和传播速度区分开来,传播速度依赖于传输的介质并且有通常的物理意义

视频格式&编码格式

MP4、AVI、WebM、MOV、WMV、RMVB、FLV

AVCH.264,H.265 VP8,VP9

音频基础概念

采样率

比特率(码率)

音频编码&&音频格式

MP3 AAC WAV FLAC

PHP XML操作FAQ

加载h5标签报错

Tag xxx invalid in Entity

$html_dom = new DOMDocument();
//关闭h5标签可能的报错
libxml_use_internal_errors(true);
$html_dom->loadHTML($html5);

DOMDocument 保存 xml时中文出现乱码

$html_dom = new DOMDocument();
$html_dom->loadHTML('<?xml encoding="UTF-8">'.$html);

PHP的DOM内部是utf8机制的,在loadHTML时,是通过检查字符中meta的charset来设置编码的,如果没有charset,就当iso8859进行处理了,而这种情况下进行saveXML时,输出来的却是utf8,所以就看到乱码了.

对不包含<meta>标签和<body>标签的富文本字符串处理特别有用

Go开发生态 常用笔记

环境搭建

gvm 开发环境推荐使用版本管理脚本

你有同时使用多版本 Go 语言的需求吗,那就快使用多版本管理利器 GVM 吧!

环境准备:如何安装和配置一个基本的 Go 开发环境?

 工作区和GOPATH

软件生态

Go中文文档

开发工具

awesome-go

go的一些常用包

参考文章

为什么很多公司都转型go语言开发?Go语言能做什么

Go 语言的整洁架构之道 —— 一个使用 gRPC 的 Go 项目整洁架构例子

jemalloc 内存分配管理

相关文章

jemalloc 内存分配管理

内存优化总结:ptmalloc、tcmalloc和jemalloc

他山之石:高性能内存分配器 jemalloc 基本原理

jemalloc内存分配浅析

使用jemalloc优化Mysql、PHP内存占用

支持的软件

Redis,默认使用jemalloc

Mysql

LD_PRELOAD=/usr/local/lib/libjemalloc.so@

MariaDB

LD_PRELOAD=/usr/local/lib/libjemalloc.so@

Jemalloc

LD_PRELOAD=/usr/local/lib/libjemalloc.so@

Nginx

--with-ld-opt='-ljemalloc'

Openrestry

--with-ld-opt='-ljemalloc -Wl,-u,pcre_version'

Tengine

--with-jemalloc

常用防火墙指南

iptables

运行在用户空间的应用软件,通过控制Linux内核netfilter模块,来管理网络数据包的处理和转发。iptables 支持内核2.4以上版本,旧版内核环境下则使用ipchains(于2.2版内核)或 ipwadm(于2.0版内核)完成类似的功能。2014年1月19日起发行的Linux内核3.13版则使用nftables取而代之,但仍然提供 iptables 命令做为兼容接口

CentOS 7.0默认使用的是firewall作为防火墙,启用iptable,

iptable需要先关闭firewall并禁止开启自启
service firewalld stop
systemctl disable firewalld.service #禁止firewall开机启动

#安装iptable
yum install iptables-services 
service iptables start #开启
systemctl enable iptables.service #设置防火墙开机启动




开放指定端口

删除已添加规则

查看已添加规则

应用场景


指令选项
iptables -L -F -A -D # list flush append delete

场景一
开放 tcp 10-22/80 端口 开放 icmp 其他未被允许的端口禁止访问
iptables -I INPUT -p tcp --dport 80 -j ACCEPT # 允许 tcp 80 端口
iptables -I INPUT -p tcp --dport 10:22 -j ACCEPT # 允许 tcp 10-22 端口
iptables -I INPUT -p icmp -j ACCEPT # 允许 icmp
iptables -A INPUT -j REJECT # 添加一条规则, 不允许所有

场景二
ftp: 默认被动模式(服务器产生随机端口告诉客户端, 客户端主动连接这个端口拉取数据) vsftpd: 使 ftp 支持主动模式(客户端产生随机端口通知服务器, 服务器主动连接这个端口发送数据)
iptables -I INPUT -i lo -j ACCEPT # 允许本机访问
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许访问外网
iptables -I INPUT -p tcp --dport 80 -s 10.10.188.233 -j ACCEPT # 只允许固定ip访问80

场景三
允许外网访问: web http -> 80/tcp; https -> 443/tcp mail smtp -> 25/tcp; smtps -> 465/tcp pop3 -> 110/tcp; pop3s -> 995/tcp imap -> 143/tcp
iptables -I INPUT -i lo -j ACCEPT # 允许本机访问
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许访问外网
iptables -I INPUT -s 10.10.155.0/24 -j ACCEPT # 允许内网访问
iptables -I INPUT -p tcp -m multiport --dports 80,1723 -j ACCEPT # 允许端口, 80 -> http, 1723 -> vpn
iptables -A INPUT -j REJECT # 添加一条规则, 不允许所有
iptables-save # 保存设置到配置文件

场景四
nat 转发
iptables -t nat -L # 查看 nat 配置
iptables -t nat -A POST_ROUTING -s 10.10.177.0/24 -j SNAT --to 10.10.188.232 # SNAT
vi /etc/sysconfig/network # 配置网关
iptables -t nat -A POST_ROUTING -d 10.10.188.232 -p tcp --dport 80 -j DNAT --to 10.10.177.232:80 # DNAT

场景五
防CC攻击
iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 100 -j REJECT # 限制并发连接访问数
iptables -I INPUT -m limit --limit 3/hour --limit-burst 10 -j ACCEPT # limit模块; --limit-burst 默认为5

相关文章

维基百科

iptables 详解

iptables命令

firewall

官方网站 维基百科

众所周知,在RHEL7系统中,firewalld防火墙取代了iptables防火墙。我们都知道iptables的防火墙策略是交由内核层面的netfilter网络过滤器来处理的,而firewalld则是交由内核层面的nftables包过滤框架来处理。

下面一张图,让大家明确的了解防火墙 Firewall 与 iptables 之间的关系与区别。

相较于iptables防火墙而言,firewalld支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。

firewalld跟iptables比起来至少有两大好处:

  1. firewalld可以动态修改单条规则,而不需要像iptables那样,在修改了规则后必须得全部刷新才可以生效。
  2. firewalld在使用上要比iptables人性化很多,即使不明白“五张表五条链”而且对TCP/IP协议也不理解也可以实现大部分功能。

相关文章

firewalld防火墙详解
firewall-cmd

ufw

相关文章

UFW – Uncomplicated Firewall

簡易的防火牆 – UFW & GUFW

Linux编译安装程序操作篇

编译工具准备

GCC编译器 官网

通过apt yum dnf 等包管理工具安装

GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection) [1] 

Make 文档

通过apt yum dnf 等包管理工具安装

GNU Make是一个可以自动运行shell命令并帮助执行重复任务的程序。它通常用于将文件转换成其他形式,例如将源代码文件编译成程序或库。

Make适用于构建小型C/ c++项目或库,这些项目或库将包含在另一个项目的构建系统中。大多数构建系统都有办法集成基于make的子项目。

对于较大的项目,您会发现更现代的构建系统更易于使用。

在以下情况下,我建议使用非Make的构建系统:

当正在构建的目标(或文件)数量为(或最终将为)数百时。 需要一个“配置”步骤,它设置和保存变量、目标定义和环境配置。 该项目将保持内部或私有,将不需要由终端用户构建。 您会发现调试是一项令人沮丧的工作。 您需要构建的是跨平台的,可以在macOS、Linux和Windows上构建。 在这些情况下,您可能会发现使用CMake、Bazel、Meson或其他现代构建系统是一种更愉快的体验。

一般情况下发布的linux源码包中包含了makefile文件

Autoconf 官网

帮助我软件开发者通过使用GNU m4语言在configure.ac中写出限定配置脚本行为的列表。Autoconf将configure.ac中的命令转化为对应特定平台的配置脚本。Autoconf本身并不具备编译能力,它仅仅用于产生通常附带在软件包中的配置脚本。生成configure脚本。

Automake

是一种编程工具,可以产生供make程序使用的Makefile,用来编译程序。它是自由软件基金会发起的GNU计划的其中一项,作为GNU构建系统的一部分。automake所产生的Makefile符合GNU编程标准。

automake是由Perl语言所写的,必须和GNU autoconf一并使用。

具体使用参考相关文章automake,autoconf使用详解

CMake 官网

跨平台的编译工具 ,一般情况下不用(c语言的程序),因为服务器软件大多跑在linux上。

可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。

安装流程

tar命令查询

configure配置

通过 –help可以查看命令选项

默认的通用参数 --prefix安装目录,不指定则安装到默认目录
./configure --prefix=/xxx/xxx/
其他配置项,需要看具体软件编译安装文档说明

make命令查询

make -j 线程数  加速编译  

参考文章 让Make编译速度加快(Make -j解析)

如何解决依赖问题

一下两个命令可以查看已安装程序的依赖

ldd 二进制程序文件 可以查看静态的二进制文件依赖的共享库

lsof -p PID 显示Linux系统当前已打开的所有文件列表,PID为进程数字

执行./configure 根据依赖报错来确定需要的依赖

更新动态链接库

安装后提示xxx.so.7: cannot open shared object file: No such file or directory

执行 ldconfig /usr/local/lib/ 更新动态库缓存

实战练习

编译安装php

Unix 系统下的安装 核心配置选项列表

编译安装ffmpeg

CompilationGuide

相关文章

Linux中编译安装软件的基本流程

Linux下源代码的编译安装入门

在Linux系统中编译安装软件的基本流程

GUN make 入门到精通

GUN Make指南

CMake 入门实战

automake,autoconf使用详解 

Linux编译安装基础理论知识

为什么需要编译

我们平常写的高级语言和汇编语言是个人看的CPU无法直接运行,需要编译成机器码给CPU执行。

从软件工程师的角度来讲,CPU 就是一个执行各种计算机指令(Instruction Code)的逻辑机器。这里的计算机指令,就好比一门 CPU 能够听得懂的语言,我们也可以把它叫作机器语言(Machine Language)。

不同的 CPU 能够听懂的语言不太一样。比如,我们的个人电脑用的是 Intel 的 CPU,苹果手机用的是 ARM 的 CPU。这两者能听懂的语言就不太一样。类似这样两种 CPU 各自支持的语言,就是两组不同的计算机指令集,英文叫 Instruction Set。这里面的“Set”,其实就是数学上的集合,代表不同的单词、语法。

复杂指令集计算机包含许多应用程序中很少使用的特定指令,由此产生的缺陷是指令长度不固定。

目前x86架构微处理器如IntelPentium/Celeron/XeonAMDAthlon/Duron/Sempron;以及其64位扩展系统的x86-64架构的Intel 64的Intel Core/Core 2/Celeron/Pentium/Xeon与AMD64的Phenom II/Phenom/Athlon 64/Athlon II/Opteron/AMD APU/Ryzen/EPYC都属于复杂指令集。主要针对的操作系统是微软Windows苹果公司macOS。另外Linux,一些UNIX等,都可以运行在x86(复杂指令集)架构的微处理器。

精简指令集计算机通过只执行在程序中经常使用的指令来简化处理器的结构,而特殊操作则以子程序的方式实现,它们的特殊使用通过处理器额外的执行时间来弥补。

这种指令集运算包括惠普的PA-RISC,国际商业机器PowerPC康柏(后被惠普收购)的Alpha,美普思科技公司的MIPS,SUN公司的SPARC,ARM公司的ARM架构等。目前有UNIX、Linux以及包括iOS、Android、Windows Phone等在内的大多数移动操作系统运行在精简指令集的处理器上。

除了 C 这样的编译型的语言之外,不管是 Python 这样的解释型语言,还是 Java 这样使用虚拟机的语言,其实最终都是由不同形式的程序,把我们写好的代码,转换成 CPU 能够理解的机器码来执行的。只是解释型语言,是通过解释器在程序运行的时候逐句翻译,而 Java 这样使用虚拟机的语言,则是由虚拟机对编译出来的中间代码进行解释,或者即时编译成为机器码来最终执行。

为什么同一个程序,在同一台计算机上(可是我们的 CPU 并没有换掉指令集是同一个),在 Linux 下可以运行,而在 Windows 下却不行呢?反过来,Windows 上的程序在 Linux 上也是一样不能执行的

C 语言代码 – 汇编代码 – 机器码” 这个过程,在我们的计算机上进行的时候是由两部分组成的。

第一个部分由编译(Compile)、汇编(Assemble)以及链接(Link)三个阶段组成。在这三个阶段完成之后,我们就生成了一个可执行文件。

第二部分,我们通过装载器(Loader)把可执行文件装载(Load)到内存中。CPU 从内存中读取指令和数据,来开始真正执行程序。

在 Linux 下,可执行文件和目标文件所使用的都是一种叫 ELF(Execuatable and Linkable File Format)的文件格式,中文名字叫可执行与可链接文件格式,这里面不仅存放了编译成的汇编指令,还保留了很多别的数据,包含所有的代码,都存放在这个 ELF 格式文件里。这些名字和它们对应的地址,在 ELF 文件里面,存储在一个叫作符号表(Symbols Table)的位置里。符号表相当于一个地址簿,把名字和地址关联了起来

链接器会扫描所有输入的目标文件,然后把所有符号表里的信息收集起来,构成一个全局的符号表。然后再根据重定位表,把所有不确定要跳转地址的代码,根据符号表里面存储的地址,进行一次修正。最后,把所有的目标文件的对应段进行一次合并,变成了最终的可执行代码。这也是为什么,可执行文件里面的函数调用的地址都是正确的。

在链接器把程序变成可执行文件之后,要装载器去执行程序就容易多了。装载器不再需要考虑地址跳转的问题,只需要解析 ELF 文件,把对应的指令和数据,加载到内存里面供 CPU 执行就可以了。

Linux 下的 ELF 文件格式,而 Windows 的可执行文件格式是一种叫作 PE(Portable Executable Format)的文件格式。Linux 下的装载器只能解析 ELF 格式而不能解析 PE 格式。

Linux 下著名的开源项目 Wine,就是通过兼容 PE 格式的装载器,使得我们能直接在 Linux 下运行 Windows 程序的。而现在微软的 Windows 里面也提供了 WSL,也就是 Windows Subsystem for Linux,可以解析和加载 ELF 格式的文件。

推荐阅读想要更深入了解程序的链接过程和 ELF 格式,我推荐你阅读《程序员的自我修养——链接、装载和库》的 1~4 章。这是一本难得的讲解程序的链接、装载和运行的好书。

本地编译和交叉编译

本地编译可以理解为,在当前编译平台下,编译出来的程序只能放到当前平台下运行。平时我们常见的软件开发,都是属于本地编译:

比如,我们在 x86 平台上,编写程序并编译成可执行程序。这种方式下,我们使用 x86 平台上的工具,开发针对 x86 平台本身的可执行程序,这个编译过程称为本地编译。

交叉编译可以理解为,在当前编译平台下,编译出来的程序能运行在体系结构不同的另一种目标平台上,但是编译平台本身却不能运行该程序:

比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM 平台的程序,编译得到的程序在 x86 平台上是不能运行的,必须放到 ARM 平台上才能运行。

编译安装和软件包安装的区别

二级制安装包,是厂商预先在对应的cpu架构的电脑上编译好的二进制安装包,然后通过包管理工具分发,yum,rpm,apt,dpkg.优点是安装快。缺点是一些特殊的软件无法进行定制安装,目录和相关配置无法指定都是预先编译好的。

编译安装比较耗费时间,可以对模块进行定制,安装到指定目录。升级时需要重新编译

举例说明,比如php语言这种模块形式的服务软件,有很多扩展用不到,用软件包完全安装之后占用更多的系统资源,而有的第三方的模块,系统分发的软件包里没有,需要自己重新编译

动态库

从操作系统的角度来说,它仅仅提供最原始的系统调用是不够的,有很多业务逻辑的封装,在用户态来做更合适。但是,它也无法去穷举所有的编程语言,然后一一为它们开发各种语言的基础库。那怎么办?

聪明的操作系统设计者们想了一个好办法:动态库。几乎所有主流操作系统都有自己的动态库设计,包括:

  • Windows 的 dll(Dynamic Link Library);
  • Linux/Android 的 so(shared object);
  • Mac/iOS 的 dylib(Mach-O Dynamic Library)。

动态库本质上是实现了一个语言无关的代码复用机制。它是二进制级别的复用,而不是代码级别的。这很有用,大大降低了编程语言标准库的工作量。

动态库的原理其实很简单,核心考虑两个东西。

  • 浮动地址。动态库本质上是在一个进程地址空间中动态加载程序片段,这个程序片段的地址显然在编译阶段是没法确定的,需要在加载动态库的过程把浮动地址固定下来。这块的技术非常成熟,我们在实模式下加载进程就已经在使用这样的技术了。
  • 导出函数表。动态库需要记录有哪些函数被导出(export),这样用户就可以通过函数的名字来取得对应的函数地址。

有了动态库,编程语言的设计者实现其标准库来说就多了一个选择:直接调用动态库的函数并进行适度的语义包装。大部分语言会选择这条路,而不是直接用系统调用。

例如php的各种扩展,调用系统的动态库

程序运行是加载动态库的几种方法:

通过ldconfig命令

命令手册详细解释 演示案例

通过LD_LIBRARY_PATH环境变量

可以通过在.bashrc或者.cshrc中配置该环境变量,LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库. 可以设置多个搜索目录, 这些目录之间用冒号分隔开.
同样是上面的例子,可以通过以上的方法来实现
在.bashrc或.cshrc中增加一行,export LD_LIBRARY_PATH = ~/exe:$LD_LIBRARY_PATH即可。

通过编译选项-Wl

通过编译选项-Wl, -rpath指定动态搜索的路径
    -Wl选项告诉编译器将后面的参数传递给链接器

pkg-config

pkg-config 是一个用于检索安装在Linux系统上的库文件信息和编译选项的工具。 而 pkgconfig 目录则是默认的包含了许多库文件信息和编译选项的目录之一。当我们想要使用被安装在系统上的某个库文件时,我们需要指定它的头文件路径、链接库路径和其他编译选项等信息,而这些信息通常会存储在 /usr/local/lib/pkgconfig/ 或者 /usr/lib/pkgconfig/(根据不同的发行版,目录可能有所不同)等目录下的对应库文件的 .pc 文件中。使用 pkg-config 工具可以方便地读取这些信息,并将它们传递给编译器来编译我们自己的程序,以便正确地链接和运行所需的库文件

在某些情况下,我们需要根据需要手动指定pkgconfig的目录

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH

常见的pkg config 目录,ubuntu系统

/usr/lib/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/local/lib/pkgconfig

通俗易懂的讲解

编译器的工作过程——阮一峰

相关文章

软件的安装: 编译安装和包管理器安装有什么优势和劣势?

深入浅出计算机组成原理-05计算机指令集

ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?

什么是交叉编译

操作系统内核与编程接口

软件工程中的开发方法

瀑布开发

维基百科 百度百科

迭代式开发

维基百科 百度百科

敏捷开发

维基百科 百度百科

精益软件开发

维基百科 百度百科

由此衍生出的产品低代码平台,通过少量代码或图形界面操作来快速制作软件,无法解决定制需求

全面解析瀑布式开发和敏捷式开发

瀑布式开发和敏捷开发有什么关系?