Linux- DWARF调试文件格式
基本概念
DWARF
是一个用于在可执行程序和其源代码之间进行关联的调试文件格式。当开发者使用调试编译选项(例如,使用gcc时的-g
标志)编译程序时,编译器会生成这种格式的调试信息。这些信息在后续的调试过程中非常有用,例如,使用gdb
(GNU调试器)。
以下是DWARF
的一些主要特点和相关的详细信息:
-
历史:
DWARF
起初是为了满足UNIX系统上的高效、紧凑和跨平台的调试需求而设计的。自那时起,它已经经历了多个版本,每个版本都增加了新的特性。 -
版本:从
DWARF 1
到DWARF 5
,每个版本都引入了新的特性和改进,以支持新的编程语言特性、编译器优化等。 -
数据结构:
DWARF
信息由一系列的记录组成,这些记录描述了源代码的结构、变量、数据类型等。它们以所谓的"Debugging Information Entries" (DIEs)的形式存储。 -
查看工具:有一些工具可以查看和处理
DWARF
调试信息。例如,readelf
(与binutils
套件一起提供)可以使用-wi
选项来查看DWARF
信息。 -
优势:
- 跨平台:
DWARF
是一个可扩展的格式,可以支持多种不同的架构和操作系统。 - 紧凑:尽管包含大量的调试信息,但
DWARF
的设计使其尽可能紧凑,避免浪费存储空间。 - 灵活性:
DWARF
可以描述各种编程语言构造和复杂的数据类型。
- 跨平台:
-
与其他格式的比较:除了
DWARF
,还有其他的调试格式,例如stabs
和PE/COFF
。但DWARF
因其丰富的特性和跨平台支持而受到许多现代系统的青睐。
总之,DWARF
是一个强大的调试信息格式,允许开发者在程序的执行过程中访问源代码级别的详细信息。对于开发者或者正在学习调试技术的读者来说,了解DWARF
和如何使用它将非常有益。
示例
下面,我们用一个简单的C语言程序,展示它如何与DWARF调试信息交互。
假设我们有一个简单的C程序example.c
:
#include <stdio.h>int add(int a, int b) {return a + b;
}int main() {int sum = add(5, 7);printf("The sum is: %d\n", sum);return 0;
}
我们使用GCC编译器编译这个程序,并使用-g
选项来生成DWARF调试信息:
$ gcc -g -o example example.c
现在,可以使用readelf
命令来查看生成的DWARF信息。例如,查看DWARF头部信息:
$ readelf --debug-dump=info example
这会列出关于源代码结构的很多信息,比如变量、函数等,并与其在源代码中的位置进行关联。
为了进一步调试程序,可以使用gdb
:
$ gdb ./example
在GDB中,可以进行各种操作,如设置断点、查看变量值等。所有这些操作都是基于DWARF调试信息的。
例如,可以在add
函数上设置断点:
(gdb) b add
然后运行程序:
(gdb) run
程序将在add
函数处暂停执行,此时,可以查看和修改变量值、单步执行等。
总的来说,DWARF调试信息提供了程序的详细视图,使得像gdb
这样的调试器可以与源代码进行交互。
DWARF调试信息
下面,我们来详细了解DWARF调试信息。
$ readelf --debug-dump=info exampleContents of the .debug_info section:Compilation Unit @ offset 0x0:Length: 0xf4 (32-bit)Version: 5Unit Type: DW_UT_compile (1)Abbrev Offset: 0x0Pointer Size: 8<0><c>: Abbrev Number: 3 (DW_TAG_compile_unit)<d> DW_AT_producer : (indirect string, offset: 0x0): GNU C17 11.4.0 -mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection<11> DW_AT_language : 29 (C11)<12> DW_AT_name : (indirect line string, offset: 0x29): example.c<16> DW_AT_comp_dir : (indirect line string, offset: 0x0): /home/majn/python_project/socket_project<1a> DW_AT_low_pc : 0x1149<22> DW_AT_high_pc : 0x56<2a> DW_AT_stmt_list : 0x0<1><2e>: Abbrev Number: 1 (DW_TAG_base_type)<2f> DW_AT_byte_size : 8<30> DW_AT_encoding : 7 (unsigned)<31> DW_AT_name : (indirect string, offset: 0x8e): long unsigned int<1><35>: Abbrev Number: 1 (DW_TAG_base_type)<36> DW_AT_byte_size : 4<37> DW_AT_encoding : 7 (unsigned)<38> DW_AT_name : (indirect string, offset: 0x93): unsigned int<1><3c>: Abbrev Number: 1 (DW_TAG_base_type)<3d> DW_AT_byte_size : 1<3e> DW_AT_encoding : 8 (unsigned char)<3f> DW_AT_name : (indirect string, offset: 0xa0): unsigned char<1><43>: Abbrev Number: 1 (DW_TAG_base_type)<44> DW_AT_byte_size : 2<45> DW_AT_encoding : 7 (unsigned)<46> DW_AT_name : (indirect string, offset: 0xbc): short unsigned int<1><4a>: Abbrev Number: 1 (DW_TAG_base_type)<4b> DW_AT_byte_size : 1<4c> DW_AT_encoding : 6 (signed char)<4d> DW_AT_name : (indirect string, offset: 0xa2): signed char<1><51>: Abbrev Number: 1 (DW_TAG_base_type)<52> DW_AT_byte_size : 2<53> DW_AT_encoding : 5 (signed)<54> DW_AT_name : (indirect string, offset: 0xd6): short int<1><58>: Abbrev Number: 4 (DW_TAG_base_type)<59> DW_AT_byte_size : 4<5a> DW_AT_encoding : 5 (signed)<5b> DW_AT_name : int<1><5f>: Abbrev Number: 1 (DW_TAG_base_type)<60> DW_AT_byte_size : 8<61> DW_AT_encoding : 5 (signed)<62> DW_AT_name : (indirect string, offset: 0xb3): long int<1><66>: Abbrev Number: 1 (DW_TAG_base_type)<67> DW_AT_byte_size : 1<68> DW_AT_encoding : 6 (signed char)<69> DW_AT_name : (indirect string, offset: 0xa9): char<1><6d>: Abbrev Number: 5 (DW_TAG_const_type)<6e> DW_AT_type : <0x66><1><72>: Abbrev Number: 6 (DW_TAG_subprogram)<73> DW_AT_external : 1<73> DW_AT_name : (indirect string, offset: 0xcf): printf<77> DW_AT_decl_file : 2<78> DW_AT_decl_line : 356<7a> DW_AT_decl_column : 12<7b> DW_AT_prototyped : 1<7b> DW_AT_type : <0x58><7f> DW_AT_declaration : 1<7f> DW_AT_sibling : <0x8a><2><83>: Abbrev Number: 7 (DW_TAG_formal_parameter)<84> DW_AT_type : <0x8a><2><88>: Abbrev Number: 8 (DW_TAG_unspecified_parameters)<2><89>: Abbrev Number: 0<1><8a>: Abbrev Number: 9 (DW_TAG_pointer_type)<8b> DW_AT_byte_size : 8<8c> DW_AT_type : <0x6d><1><90>: Abbrev Number: 10 (DW_TAG_subprogram)<91> DW_AT_external : 1<91> DW_AT_name : (indirect string, offset: 0xae): main<95> DW_AT_decl_file : 1<96> DW_AT_decl_line : 7<97> DW_AT_decl_column : 5<98> DW_AT_type : <0x58><9c> DW_AT_low_pc : 0x1161<a4> DW_AT_high_pc : 0x3e<ac> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)<ae> DW_AT_call_all_tail_calls: 1<ae> DW_AT_sibling : <0xc2><2><b2>: Abbrev Number: 11 (DW_TAG_variable)<b3> DW_AT_name : sum<b7> DW_AT_decl_file : 1<b8> DW_AT_decl_line : 8<b9> DW_AT_decl_column : 9<ba> DW_AT_type : <0x58><be> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)<2><c1>: Abbrev Number: 0<1><c2>: Abbrev Number: 12 (DW_TAG_subprogram)<c3> DW_AT_external : 1<c3> DW_AT_name : add<c7> DW_AT_decl_file : 1<c8> DW_AT_decl_line : 3<c9> DW_AT_decl_column : 5<ca> DW_AT_prototyped : 1<ca> DW_AT_type : <0x58><ce> DW_AT_low_pc : 0x1149<d6> DW_AT_high_pc : 0x18<de> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)<e0> DW_AT_call_all_calls: 1<2><e0>: Abbrev Number: 2 (DW_TAG_formal_parameter)<e1> DW_AT_name : a<e3> DW_AT_decl_file : 1<e3> DW_AT_decl_line : 3<e3> DW_AT_decl_column : 13<e4> DW_AT_type : <0x58><e8> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)<2><eb>: Abbrev Number: 2 (DW_TAG_formal_parameter)<ec> DW_AT_name : b<ee> DW_AT_decl_file : 1<ee> DW_AT_decl_line : 3<ee> DW_AT_decl_column : 20<ef> DW_AT_type : <0x58><f3> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)<2><f6>: Abbrev Number: 0<1><f7>: Abbrev Number: 0
这是一个.debug_info
节的内容,该节是由readelf
从ELF文件中提取的。这个节包含了程序的DWARF调试信息。以下是这些输出信息的简要说明:
-
Compilation Unit: 表示源文件的一个编译单位。这里是
example.c
。- DW_AT_producer: 编译器和其版本信息。
- DW_AT_language: 源代码的编程语言。
- DW_AT_name: 源文件名。
- DW_AT_comp_dir: 源文件的编译目录。
- DW_AT_low_pc 和 DW_AT_high_pc: 表示程序地址范围。
-
DW_TAG_base_type: 这是基础类型的定义,例如
unsigned int
,unsigned char
等。- DW_AT_byte_size: 数据类型的大小。
- DW_AT_encoding: 数据类型的编码,例如signed、unsigned等。
- DW_AT_name: 数据类型的名称。
-
DW_TAG_subprogram: 代表一个函数或子程序。
- DW_AT_external: 表明这个函数是否是外部的。
- DW_AT_name: 函数名。
- DW_AT_decl_file、DW_AT_decl_line、DW_AT_decl_column: 声明函数的文件、行号和列号。
- DW_AT_prototyped: 表明该函数是否有原型。
- DW_AT_type: 函数返回的数据类型。
-
DW_TAG_formal_parameter: 表示函数的一个形式参数。
- DW_AT_name: 参数名称。
- DW_AT_decl_file、DW_AT_decl_line、DW_AT_decl_column: 参数在源文件中的位置。
- DW_AT_type: 参数的数据类型。
- DW_AT_location: 参数在堆栈上的位置。
-
DW_TAG_pointer_type: 表示指针类型。
- DW_AT_byte_size: 指针的大小,通常为地址大小。
- DW_AT_type: 指针所指向的数据类型。
-
DW_TAG_const_type: 表示常量类型。
-
DW_TAG_unspecified_parameters: 表示函数可能有不确定数量的参数。
-
DW_TAG_variable: 表示一个变量。
- DW_AT_name: 变量名。
- DW_AT_type: 变量的数据类型。
- DW_AT_location: 变量的位置,可能是寄存器或堆栈上的位置。
上述内容只是一个粗略的说明,DWARF格式包含了大量的复杂信息,用于在不运行程序的情况下,对其进行详细的分析和调试。
在DWARF调试信息中,DW_AT_type: <0x58>
表示一个引用或指针,它指向另一个DWARF条目。具体来说,这是一个偏移量,它从当前编译单元的开始处计算,指向描述该类型的DWARF条目。
在给定的输出中,DW_AT_type: <0x58>
意味着该属性引用了偏移量为0x58
的条目以获取其类型信息。
为了理解这代表什么,我们应该查找偏移量为0x58
的条目。在提供的输出中,可以看到以下条目:
<1><58>: Abbrev Number: 4 (DW_TAG_base_type)<59> DW_AT_byte_size : 4<5a> DW_AT_encoding : 5 (signed)<5b> DW_AT_name : int
这意味着DW_AT_type: <0x58>
引用的是一个基础类型,它是一个带符号的整数int
,大小为4字节。
DW_AT_stmt_list
DW_AT_stmt_list
是一个属性,用于在DWARF调试信息中引用一个行号信息表的偏移量。这个属性关联了源代码的行号和生成的机器代码之间的映射,使得调试工具能够准确地确定执行的源代码行。
具体来说,当我们在调试器中设置断点或在运行时遇到错误时,DW_AT_stmt_list
使得调试器可以准确地显示源代码中的相关行。
值得注意的是,DW_AT_stmt_list
的值是一个偏移量,指向 .debug_line
节区中的一个位置,该位置包含与编译单元关联的行号程序。
这允许开发者和调试工具从机器代码位置回溯到源代码位置,从而可以进行更有效的调试。
Abbrev Number
Abbrev Number
在 DWARF 调试信息中是一个非常重要的概念,用于表示一个 “abbreviation” 的唯一标识符。它与一个特定的 “abbreviation” 对象关联,该对象定义了一个特定的 DIE(Debugging Information Entry)的结构和属性。简单地说,它是一个用于描述 DIE 结构的模板。
让我们详细解析一下:
-
DIE (Debugging Information Entry): 在 DWARF 中,调试信息由许多的 DIEs 组成。每个 DIE 描述了编译单位中的某个实体,如变量、类型、函数等。每个 DIE 都有一个 “tag”(如
DW_TAG_base_type
),用于描述其表示的实体类型。 -
Abbreviations: 由于调试信息可能会很大,DWARF 使用一种缩写机制来减少所需的空间。这种机制通过定义一组 “abbreviations” 来工作,每个 “abbreviation” 描述了一种特定的 DIE 结构(包括其标签和属性)。这些 “abbreviations” 存储在
.debug_abbrev
节区中。 -
Abbrev Number: 每个 “abbreviation” 都有一个唯一的编号,称为
Abbrev Number
。这允许.debug_info
节区中的 DIEs 通过简单地引用这个编号来描述其结构,而不是重复每个属性和标签。
因此,当我们在 .debug_info
节区中看到 Abbrev Number: 1
,这意味着可以查找 .debug_abbrev
节区中的编号为 1 的 “abbreviation”,从而知道该 DIE 的结构和属性。
DW_AT_low_pc 和 DW_AT_high_pc
在DWARF调试信息中,DW_AT_low_pc
和 DW_AT_high_pc
是两个非常重要的属性,它们定义了一个代码范围的开始和结束地址。
-
DW_AT_low_pc: 这是代码段的起始地址。在上面给出的例子中,
DW_AT_low_pc: 0x1149
表示相关的代码段(可能是一个函数或其他代码块)从地址0x1149
开始。 -
DW_AT_high_pc: 在早期的DWARF版本中,这是代码段的结束地址。但在后来的版本中(尤其是DWARF4之后),这的含义发生了变化,它代表与
DW_AT_low_pc
的偏移量,而不是实际的结束地址。在上面给出的例子中,DW_AT_high_pc: 0x56
很可能表示代码段的长度是0x56
字节。因此,真正的结束地址将是0x1149 + 0x56
。
为了确定 DW_AT_high_pc
的确切含义(是否是结束地址还是偏移量),需要查看DWARF版本以及可能存在的其他属性,如DW_AT_ranges
。但在大多数情况下,考虑到新版本的DWARF,可以假设DW_AT_high_pc
表示从DW_AT_low_pc
的偏移量。
DW_AT_decl_file
在DWARF调试信息中,DW_AT_decl_file
属性表示源文件的索引,它指向文件名列表(通常存储在 .debug_line
节中的文件名表中)。
在上面的例子中,DW_AT_decl_file : 1
表示这个特定的实体(可能是一个变量、函数等)是在文件名列表中索引为1的文件中声明的。
为了找出索引1
真正代表的文件名,需要查看 .debug_line
节,并找到对应的文件名表。这个表通常会列出编译单元中用到的所有文件,每个文件都有一个唯一的索引号,从1开始。这样,DWARF信息可以通过简单地引用索引号来指代一个特定的文件,而不是多次重复文件的完整路径名,从而节省空间。
相关文章:
Linux- DWARF调试文件格式
基本概念 DWARF是一个用于在可执行程序和其源代码之间进行关联的调试文件格式。当开发者使用调试编译选项(例如,使用gcc时的-g标志)编译程序时,编译器会生成这种格式的调试信息。这些信息在后续的调试过程中非常有用,…...
软件工程第六周
软件体系结构概述 体系结构:一种思想,而框架就是思想的实现,设计模式就是根据某一特殊问题实现的框架。 体系结构:体系结构是软件系统的高级结构。它定义了系统的主要组成部分,以及这些部分之间的关系和交互方式。 框…...
node+pm2安装部署
1、安装node 下载node安装包: wget https://nodejs.org/dist/v16.14.0/node-v16.14.0-linux-x64.tar.xz 解压: tar -xvJf node-v14.17.0-linux-x64.tar.xz 配置环境变量,在/etc/profile文件最后添加以下脚本: export PATH$P…...
大数据学习(11)-hive on mapreduce详解
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博>主哦&#x…...
MyBatis基础之自动映射、映射类型、文件注解双配置
文章目录 自动映射原理jdbcType同时启用配置文件和注解两种配置方式 自动映射原理 在 MyBatis 的配置文件(settings 元素部分)中,有一个 autoMappingBehavior 配置,其默认值为 PARTIAL ,表示 MyBatis 会自动映射&…...
8、docker 安装 nginx
1、下载镜像 docker pull nginx 2、本机创建目录 1)创建nginx挂载目录 mkdir /usr/local/nginx 2)进入nginx目录 cd /usr/local/nginx 3)创建 www和logs目录 mkdir -p www logs 3、创建nginx容器 此容器用于复制配置文件,复…...
关于Skywalking Agent customize-enhance-trace对应用复杂参数类型取值
对于Skywalking Agent customize-enhance-trace 大家应该不陌生了,主要支持以非入侵的方式按用户自定义的Span跟踪对应的应用方法,并获取数据。 参考https://skywalking.apache.org/docs/skywalking-java/v9.0.0/en/setup/service-agent/java-agent/cust…...
手机路径、Windows路径知识及delphiXE跨设备APP自动下载和升级
手机路径、Windows路径知识 及delphiXE跨设备APP自动下载和升级 一、APP安装程序文件版本和权限信息 1、运行时动态调用Android apk的AndroidManifest.xml获取versionName 2、运行时动态调用IOS ipa的info.plist获取CFBundleVersion (和entitlements)…...
GitLab 502问题解决方案
由于最近 gitlab 切换到另一台服务器上部署的 gitlab 后,经常出现 502。平时重启 gitlab 后都能解决,今天突然重启多次后都还是 502(重启日志是正常的),遂通过 gitlab-ctl tail 查看日志进行排查。 gitlab-ctl tail通…...
selenium打开火狐浏览器
项目上需求为:甲方OA 系统是IE系统,需要从IE系统点个按钮打开火狐浏览器单点登录跳转到我们的系统 前期解决方案为:打开浏览器就行了,然后就用的是打开本地浏览器,但是由于B/S架构,有别人远程访问我的ip来…...
多标签分类论文笔记 | ML-Decoder: Scalable and Versatile Classification Head
个人论文精读笔记,主要是翻译心得,欢迎旁观,如果有兴趣可以在评论区留言,我们一起探讨。 Paper: https://arxiv.org/pdf/2111.12933.pdf Code: https://github.com/Alibaba-MIIL/ML_Decoder 文章目录 0. 摘要1. 介绍2. 方法2.1 Ba…...
修改http_charfinder.py使能在python311环境中运行
需要修改两个函数,第一个是init函数,修改如下: async def init(loop, address, port): # <1> # app web.Application(looploop) # <2> # app.router.add_route(GET, /, home) # <3> app web.Application(…...
蓝桥杯(跳跃 C++)
思路: 1、根据题目很容易知道可以用深度搜索、广度搜索、动态规划的思想解题。 2、这里利用深度搜素,由题目可知,可以往九个方向走。 3、这里的判断边界就是走到终点。 #include<iostream> using namespace std; int max1 0; int …...
08 | Jackson 注解在实体里面如何应用?常见的死循环问题如何解决?
我们用 Spring Boot 里面默认集成的 fasterxml.jackson 加以说明,这看似和 JPA 没什么关系,但是一旦我们和 Entity 一起使用的时候,就会遇到一些问题,特别是新手同学,我们这一课时详细介绍一下用法。先来跟着我了解一下…...
JavaScript—获取当前时间 并转化为yyyy-MM-dd hh:mm:ss格式
JavaScript—获取当前时间 并转化为yyyy-MM-dd hh:mm:ss格式 每次项目都需要用到时间戳格式,可以封装成一个方法 下次直接CV过去 const timestampPadStart=(str)=>{str=String(str);return str.padStart(2,0)...
OpenHarmony创新赛丨报名倒计时,超强秘籍带你直通大奖!
OpenHarmony创新赛报名倒计时开始啦! 设于开放原子全球开源大赛下的OpenHarmony创新赛,目前正在如火如荼地进行赛事招募中!这次大赛围绕创新应用、商显行业、金融行业三大赛题,邀请来自企业、个人、高校师生等各界群体的优秀开发者…...
Linux高性能服务器编程 学习笔记 第十四章 进程池和线程池
动态创建子进程或子线程的缺点: 1.动态创建进程或线程比较耗时,这将导致较慢的客户响应。 2.动态创建的子进程或子线程通常只用来为一个客户服务(除非我们做特殊处理),这将导致系统上产生大量的进程或线程,…...
微信小程序/vue3/uview-plus form兜底校验
效果图 代码 <template><u-form :model"form" ref"formRole" :rules"rules"><u-form-item prop"nickname"><u-input v-model"form.nickname" placeholder"姓名" border"none" /&…...
Photoshop 2024正式发布!内置最新PS AI,创意填充等功能无限制使用!
PS正式版目前更新到了2024,版本为25.0。 安装教程 1、下载得到安装包后,先解压。鼠标右键,【解压到当前文件夹】 2、双击 Set-up 开始安装 3、这里可以更改安装位置。如果C盘空间不够大,可以把它安装到C盘以外。更改好后&#x…...
芯片学习记录TLP184
TLP184 芯片介绍 TLP184是一款光耦隔离器,它的主要特点包括:高电压耐受能力、高传输速度、高共模隔离能力、低功耗等。它可以用于工业自动化、通信设备、家用电器等领域的电气隔离应用。由一个光电晶体管组成,光学耦合到两个红外发射二极管…...
C++ 重载运算符和重载函数
前言 C 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。 当您调用一个…...
Linux:mongodb数据库基础操作(3.4版本)
安装 3.*版本和4.*版本安装都是一样的 Linux:mongodb数据库源码包安装(4.4.25版本)_鲍海超-GNUBHCkalitarro的博客-CSDN博客https://blog.csdn.net/w14768855/article/details/133826626?spm1001.2014.3001.5501 mysql和mongodb对比 登录…...
nginx实现灰度上线(InsCode AI 创作助手)
要基于Nginx实现灰度上线,有以下三种方法: 权重分发:使用Nginx的upstream模块来设置不同服务器的权重。将一部分请求分发给新版本服务器,另一部分请求分发给旧版本服务器。这可以通过以下方式实现: http {upstream bac…...
记:apifox 返回 invalid header token 的问题排查思路
背景: 某接口服务使用 springboot 2.x 开发, RestController 、ReqeustBody 在本地(localhost)调用的时候正常、chrome (.cn域名访问)浏览器访问正常。 换成 apifox (.cn域名访问)、postman (.cn域名访问)调用异常返回:invalid header t…...
【00】神经网络之初始化参数
问题描述 #随机初始化权重 w12 np.random.randn(100, 784)/np.sqrt(784) 为什么除以28 回答 这里的代码是初始化一个深度学习模型中的权重矩阵w12。权重矩阵的形状是(100, 784),这是一个从784个输入节点到100个隐藏节点的全连接层。 除以np.sqrt(784)是权重初始…...
代码随想录Day20 回溯算法 LeetCode77 组合问题
以下内容更详细解释来自于:代码随想录 (programmercarl.com) 1.回溯算法理论基础 回溯法也叫回溯搜索法,是搜索法的一种,我们之前在二叉树中也经常使用到回溯来解决问题,其实有递归就有回溯,有的时候回溯隐藏在递归之下,我们不容易发觉,今天我们来详细介绍一下什么是回溯,它能…...
免费获取天气预报的API接口(Json格式)
免费获取天气预报的API接口(Json格式) 1、接口地址2、城市代码 1、接口地址 当需要获取某个城市天气数据json时候,需要传入一个城市代码编码作为入参,地址: http://t.weather.itboy.net/api/weather/city/xxxxx &…...
安卓程序执行入口
Android程序执行入口 Android应用程序的执行入口是在一个特定的 Java 类中,通常是 MainActivity 或 SplashActivity,具体取决于应用的设计和结构。 Android应用程序的执行入口通常通过以下方式进行定义: 在 AndroidManifest.xml 文件中&am…...
消息队列(中间件)
通信协议: 为了实现客户端和服务器之间的通信来完成的逻辑,基于TCP实现的自定义应用层协议。通过这个协议,完成客户端–服务器远程方法调用。 序列化/反序列化: 通过网络传输对象把对象存储到硬盘上。 序列化:把对象转化为二进制的…...
Java|学习|异常
1.异常 1.1 异常 1.1.1 概述 异常:就是程序出现了不正常的情况。 Error:严重问题,不需要处理。 Exception:称为异常类,它表示程序本身可以处理的问题。 RuntimeException:在编译器不检查,出…...
手机网站生成app软件/媒介
前言:我个人觉得aptana3.2 for eclipse依然不够强大,有很多提示依然出不来,相比而言,我现在最强的应该是spket。 这里简单说下思路吧: 1、http://www.cnblogs.com/chang290/archive/2013/02/17/2913936.html 这个帖子基…...
怎么导入文章到wordpress/谷歌浏览器直接打开
NEW关注Tech逆向思维视频号最新视频→【摆脱焦虑告别烦恼,家装变局让消费者更从容】出品|连线Insight文|张霏编辑|李信从闪购到美团优选再到团好货,美团进军电商的野心从未停止。据连线Insight近期获悉,原网…...
php 怎么做视频网站/宁波seo高级方法
Winform-Controls 0.General 属性名描述TextAlign文本对其方式Enabled是否可用visible是否可见Anchor自适应窗体实现注意事项: 当自动生成控件时候,需要设置Autozie属性为true,要不然Text显示不全。 1.Form 1.1常用属性 // 1.启动位置this.StartPosition…...
网站的模板演示怎么做/南宁百度快速优化
C语言经典算法 - 老鼠走迷官(一)2020-02-10编程之家https://www.jb51.cc编程之家收集整理的这篇文章主要介绍了C语言经典算法 - 老鼠走迷官(一),编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。下面是编程之家 jb51.cc 通过网络…...
五指山网站开发价格/百度做广告推广怎么样
可以使用 read 命令读取输入的内容,然后用 if 语句判断输入内容是否是回车。 例如: # 读取输入 read -r input# 判断输入是否是回车 if [[ "$input" $\n ]]; then# 输入是回车echo "输入是回车" else# 输入不是回车echo "输入…...
金乡县住房与城乡建设局网站/优化大师怎么下载
pip install pyyaml...