2024年3月

前置工作

  • 导包(mysql-connector-java、mybatis)
  • 实体类

Mapper层

1.接口

public interface BookMapper {
    public Book getBookById(Integer bookID);
}

2.创建Mapper的映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ylzl.mapper.BookMapper">
    <select id="getBookById" resultType="com.ylzl.pojo.Book">
        select * from books where bookID=#{bookID}
    </select>
</mapper>

Service层

可以不使用Service层,使用其他方式包含以下核心代码也可以。

核心代码

static {
  String resource = "mybatis-config.xml";
  try {
    InputStream inputStream = Resources.getResourceAsStream(resource);
  } catch (IOException e) {
    e.printStackTrace();
  }
}

//1.读取xml配置文件,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//2.通过创建SqlSessionFactory对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.通过SqlSession对象获取代理对象mapper,传入接口class对象
BookMapper mapper=sqlSession.getMapper(BookMapper.class);
//4.通过mapper调用接口对应方法
mapper.getBookById(bookID);

以下为使用Service层实现的方式

1.接口

public interface BookService {
    Book getBookById(Integer bookID);
}

2.接口实现类
(重点关注)

public class BookServiceImpl implements BookService{
    static InputStream inputStream = null;
    static {
        String resource = "mybatis-config.xml";
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //1.读取xml配置文件,创建SqlSessionFactory对象
    private final SqlSessionFactory sqlSessionFactory
            = new SqlSessionFactoryBuilder().build(inputStream);

    @Override
    public Book getBookById(Integer bookID) {
        //2.通过创建SqlSessionFactory对象获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.通过SqlSession对象获取代理对象mapper,传入接口class对象,
        BookMapper mapper = sqlSession.getMapper(BookMapper.class);
        //4.通过mapper调用接口对应方法
        return  mapper.getBookById(bookID);
    }
}

Mybatis配置文件mybatis-config.xml
(重点关注)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssmbuild"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--配置映射文件-->
    <mappers>
        <mapper resource="com/ylzl/mapper/BookMapper.xml"/>
    </mappers>
</configuration>

测试

BookService bookServicelmpl = new BookServiceImpl();
System.out.println(bookServicelmpl.getBookById(2));

遇到的问题

1.BookMapper.xml不放在resources下,加过滤

  <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

2.解决xml编码问题:1 字节的 UTF-8 序列的字节 1 无效:
https://www.cnblogs.com/thetree/p/12991403.html

一、  智能文档处理介绍

智能文档处理(Intelligent Document Processing, IDP)是利用人工智能(AI)、机器学习(ML)、计算机视觉(CV)、自然语言处理(NLP)等技术自动化地捕获、理解、处理和分析文档内容的过程。不同于传统的文档管理系统,IDP能够处理结构化、半结构化和非结构化的文档,从而提取有用信息并将其转换为可操作的数据。在数字化转型的大背景下,企业和组织面临着处理大量文档数据的挑战。传统的方法依赖于人工输入,不仅效率低下,而且容易出错。智能文档处理技术的出现,标志着从手动到自动化处理文档的重要转变,它通过将AI技术应用于文档管理过程,极大地提高了处理速度和准确性,同时降低了成本。

智能文档处理的发展离不开机器学习、深度学习、OCR(光学字符识别)和自然语言处理等关键技术的进步。早期的文档处理主要依赖于模板匹配和规则-based的方法,这些方法在处理结构化文档时效果不错,但面对复杂的非结构化文档时则显得力不从心。随着深度学习技术的突破,尤其是卷积神经网络(CNN)和循环神经网络(RNN)在图像识别和文本处理领域的应用,使得IDP技术能够更加精准地识别和理解文档内容。此外,BERT、GPT等预训练语言模型的出现,进一步推动了IDP技术在理解复杂语言结构和语义上的能力。

智能文档处理技术的应用意义广泛,涵盖了金融、医疗、法律、教育等多个领域。在金融领域,IDP可以帮助银行和保险公司自动化处理贷款申请、保险理赔等大量的文档工作,提高审批速度和服务质量。在医疗领域,IDP能够自动化处理病历记录、实验报告等,提高医疗记录的准确性和可访问性。在法律领域,IDP可以辅助律师和法官快速查找和分析大量的法律文件和案件记录,提高工作效率。智能文档处理技术正处于快速发展之中,它不仅为企业带来了高效率和成本节约,也为AI技术的应用开辟了新的领域。通过不断的技术创新和应用实践,IDP有望解决更多行业的痛点问题,为数字化转型提供强有力的支持。

<合合TextIn textin.com - 合合信息旗下OCR云服务产品 智能文档处理云台,提供一站式智能文档处理产品服务,提供领先的智能文档处理技术>

file

file

二、文档格式解析

文档格式解析是智能文档处理(IDP)流程中的首要步骤,它涉及对文档的结构和内容进行理解,为后续的图像预处理、文字识别和信息提取等环节打下基础。这一过程要求系统能够处理和解析各种文档格式,包括但不限于PDF、DOCX、XLSX、图片格式(如JPG、PNG)等。

文档格式解析指的是将各种格式的文档转换为机器可读和可处理的数据结构的过程。这一过程涉及识别文档的编码格式、提取文本和元数据、理解文档结构(如标题、段落、列表、表格等)以及处理嵌入的元素(如图像、链接等)。

文档格式解析在IDP流程中占据着至关重要的地位。首先,它直接影响到后续处理步骤的效率和准确性。正确解析文档结构和内容能够为文字识别和信息提取提供准确的输入,减少错误传递。其次,文档格式解析的灵活性和广泛性决定了IDP系统能够处理的文档种类,进而影响系统的应用范围和用户体验。

文档格式解析技术主要由以下几部分组成:

1.  格式识别与转换:通过分析文件头信息或使用文件扩展名,确定文档的格式。针对特定格式的解析器将文档转换为统一的数据结构,以便进一步处理。

2.  结构分析:识别和提取文档的逻辑结构,如章节、标题、段落、列表等。这一步骤通常需要利用机器学习或规则-based的方法来实现。

3.  元数据提取:从文档中提取作者、创建日期、修改日期等元数据信息,这些信息在某些应用场景下非常重要。

4.  嵌入元素处理:对文档中嵌入的图像、链接、表格等元素进行识别和提取。对于图像,可能需要调用OCR技术进行文字识别。

<合合TextIn textin.com - 合合信息旗下OCR云服务产品 智能文档处理云台,提供一站式智能文档处理产品服务,提供领先的智能文档处理技术>

三、图像增强技术解析

图像增强技术是智能文档处理(IDP)中的一个关键步骤,它通过改善图像质量来提高后续文字识别(OCR)的准确率。这一技术不仅应用于传统的文档扫描图像,也适用于数字摄影和视频中的图像处理。图像增强技术指的是通过各种算法和处理技术改善图像质量的一系列方法。目标是通过提高图像的可视性或转换图像的形式,使其更适合特定的应用,如提高OCR的识别准确率。图像增强可以包括对比度增强、噪声去除、锐化处理、去模糊等多种技术。

在IDP流程中,图像增强的意义主要体现在以下几个方面:

● 提高准确率:清晰的图像可以显著提高文字识别的准确率,尤其是对于低质量或受损图像。

● 降低处理难度:增强后的图像简化了后续处理步骤,如版面分析和信息提取,因为图像噪声和失真等问题已经得到了解决。

● 增强可用性:某些情况下,原始文档可能因为年代久远、存储条件不佳等原因变得难以阅读,图像增强技术可以恢复这些文档的可用性。

图像增强技术主要包括以下几个方面:

1. 切边增强:切边增强是一种图像处理技术,通过增强图像中的边缘信息来提高图像的清晰度和对比度。该技术会突出显示图像中物体的边缘轮廓,使其更加清晰鲜明,从而改善图像的质量和可视效果。

2. 去摩尔纹:去摩尔纹技术是一种用于消除图像中出现的摩尔纹现象的方法。摩尔纹是由于图像采样频率与被拍摄物体纹理之间的相互作用而产生的干扰,常见于数字图像和扫描图像中。去摩尔纹技术通过数学算法或滤波器处理来减少或消除这种干扰,从而提高图像的质量和清晰度。

3. 弯曲矫正:弯曲矫正技术是一种用于修正图像中出现的弯曲或畸变现象的方法。在图像采集或传输过程中,由于设备或介质的问题,图像可能会发生弯曲或失真,影响图像的观感和应用效果。弯曲矫正技术通过数学模型或几何校正算法来对图像进行修正,使其恢复到原始状态或更接近真实场景,提高图像的可用性和可视化效果。

4. 去模糊:去模糊技术是一种用于消除图像中模糊或不清晰部分的方法。图像模糊可能是由于摄像机晃动、焦点不准或运动模糊等因素引起的。去模糊技术通过分析图像模糊的原因并应用相应的算法或滤波器来恢复图像的清晰度和细节,使其更具可读性和观赏性。
<合合TextIn textin.com - 合合信息旗下OCR云服务产品 智能文档处理云台,提供一站式智能文档处理产品服务,提供领先的智能文档处理技术>
file

四、传统文字识别OCR技术解析

文字识别技术,通常称为光学字符识别(OCR),是智能文档处理(IDP)中的核心环节。OCR技术使计算机能够从图像中识别和转录打印或手写文本,将图像文件转换为可编辑和可搜索的文本数据。OCR技术通过分析图像中的文字区域,识别出其中的字符,并将这些字符转换为电子文本格式。这项技术能够处理各种来源的文档图像,包括扫描文档、照片中的文字以及屏幕截图等。

传统OCR技术的实现主要依赖以下几个步骤:

1. 文字定位:通过检测图像中的文字区域,确定文字的位置和边界。这一步骤通常采用边缘检测、连通区域分析等技术,以识别出图像中的文字部分,并对其进行标记或边界框定位。

2. 文字分割:将定位到的文字区域进行分割,将每个文字字符分离出来,为后续的文字识别做准备。文字分割通常使用投影分割、连通区域分割等方法,将文字区域划分为单个字符或单词。

3. 特征提取:对分割后的文字字符进行特征提取,将文字字符转换成计算机可识别的特征向量或特征描述子。常用的特征提取方法包括形状特征、结构特征、灰度特征等,用于描述文字字符的形态和结构特征。

4. 文字识别:利用模式识别算法,对提取到的文字特征进行分类和识别,将文字字符转换成对应的文本信息。

<合合TextIn textin.com - 合合信息旗下OCR云服务产品 智能文档处理云台,提供一站式智能文档处理产品服务,提供领先的智能文档处理技术>
file

五、深度学习OCR技术解析

光学字符识别(Optical Character Recognition, OCR)技术,特别是基于深度学习的OCR,已成为智能文档处理(IDP)领域的核心技术之一。深度学习OCR利用复杂的神经网络模型来识别和转换图像中的文字为机器可读的形式。 深度学习OCR技术是指使用深度学习模型,特别是卷积神经网络(CNN)和循环神经网络(RNN),来识别图像中的文字的技术。不同于传统OCR技术,深度学习OCR能够更好地处理字体变化、布局复杂、背景嘈杂等问题,显著提高了文字识别的准确率和鲁棒性。

在IDP流程中,文字识别是将扫描的纸质文档或数字图像中的文字内容转换为电子文本的关键步骤。深度学习OCR的应用不仅提高了识别精度,还极大地扩展了OCR技术的应用范围,包括复杂文档的处理、多语言识别、手写文字识别等。此外,它还为后续的信息提取、内容理解提供了高质量的输入。

深度学习OCR技术的实现主要依赖以下几个步骤:

1. 数据收集与标注:收集大规模的带有标注的图像数据集,包括不同字体、大小、颜色和背景的文字图像。这些图像需要经过手工标注,标注每个字符的位置和对应的文本内容,以用于深度学习模型的训练。

2. 数据预处理:对收集到的图像数据进行预处理,包括图像去噪声、尺度归一化、灰度化、裁剪等操作,以减少数据的噪声和干扰,提高深度学习模型的训练效果。

3. 模型选择与训练:选择合适的深度学习模型架构,如卷积神经网络(CNN)、循环神经网络(RNN)、长短期记忆网络(LSTM)、转录者(Transformer)等,进行模型的训练和优化。在训练过程中,使用标注好的图像数据集,通过反向传播算法和梯度下降优化算法,不断调整模型参数,使其能够准确地识别文字。

4. 模型评估与调优:通过验证集或测试集对训练好的深度学习模型进行评估,包括识别准确率、召回率、精确率等指标的评估。根据评估结果,对模型进行调优和改进,以提高模型的识别准确性和泛化能力。

<合合TextIn textin.com - 合合信息旗下OCR云服务产品 智能文档处理云台,提供一站式智能文档处理产品服务,提供领先的智能文档处理技术>
file

六、深度学习版面分析技术解析
版面分析是智能文档处理(IDP)中的关键环节,它涉及对文档页面的结构和布局进行分析,以识别和分类文档中的各种元素,如文本块、图像、表格等。随着深度学习技术的发展,版面分析的能力得到了显著提升,使得处理复杂文档布局成为可能。 深度学习版面分析技术利用深度神经网络,尤其是卷积神经网络(CNN)和循环神经网络(RNN),对文档页面的布局和结构进行自动分析和理解。这项技术能够识别页面上的不同元素类型,并理解它们之间的空间关系和逻辑结构,为后续的文本识别、内容提取和信息理解提供基础。

在IDP流程中,版面分析的意义主要体现在以下几个方面:

支持复杂文档处理:深度学习技术使版面分析能够处理多样化和复杂的文档布局,提高了系统的适用范围。

● 自动化内容提取:准确的版面分析为提取特定信息(如表格数据、标题、摘要等)提供了可能,进一步促进了文档自动化处理的实现。

深度学习版面分析技术主要包括以下几个关键步骤:

1.  元素检测:利用深度学习模型,如目标检测模型(如Faster R-CNN、YOLO、SSD等),对文档图像中的各种元素进行检测和定位。这些元素可以包括文字、图像、表格、标题等。通过元素检测,可以确定文档中不同元素的位置和边界框,为后续的分析和处理提供基础。

2.  元素分类:对检测到的元素进行分类,区分文字、图像、表格等不同类型的元素。这一步骤可以采用深度学习中的图像分类模型或目标分类模型,对每个元素进行识别和分类,以便后续的结构解析和语义理解。

3.  结构解析:在元素检测和分类的基础上,进行文档的结构解析,识别文档中不同元素之间的关系和层次结构。这包括文本段落与标题的对应关系、表格中不同字段的关系等。深度学习模型可以通过对文档布局和语义信息的分析,实现对文档结构的自动解析和理解。

4.  版面校正:对检测到的文档元素进行版面校正,使其在整体文档中的位置和排布更加合理和统一。这一步骤可以包括文本对齐、图像矫正、表格对齐等操作,以提高文档的可读性和美观性。版面校正也可以通过深度学习模型来实现,例如基于生成对抗网络(GAN)的版面重构方法。

<合合TextIn - 合合信息旗下OCR云服务产品 智能文档处理云平台提供一站式智能文档处理产品服务,提供领先的版面分析技术产品>
file

七、文档分类
文档分类是智能文档处理(IDP)中的一个关键环节,它涉及自动将文档按照其内容、用途或结构分类到预定义的类别中。随着人工智能和机器学习技术的发展,文档分类的方法和效率都有了显著的提升。本章节将从定义、流程中的意义、技术组成、技术发展等多个维度全面介绍文档分类技术。文档分类指的是利用计算机程序自动识别和归类文档的过程。这涉及到理解文档的内容和结构,并将其分配到一个或多个预设的类别中。分类的依据可以是文档的主题、风格、作者、发布日期等多个维度。

文档分类技术主要包括:

1.  使用图片特征分类:图片特征的分类主要依赖于从文档中提取的视觉信息。这通常涉及到图像处理和计算机视觉技术,用于识别文档中的图形、布局和其他视觉元素。其中步骤包含特征提取、特征表示和降维、分类模型构建等步骤。

2.  使用文本特征分类:文本特征的分类依赖于文档中的文字内容,涉及自然语言处理(NLP)技术,用于理解和分类文档的语义内容。其中步骤包含文本预处理、特征提取、模型构建、模型评估等步骤。

<合合TextIn - 合合信息旗下OCR云服务产品 智能文档处理云平台提供一站式智能文档处理产品服务,提供领先的文档分类技术>
file

八、信息抽取
信息抽取(Information Extraction, IE)是智能文档处理(IDP)中的关键技术之一,它涉及从非结构化或半结构化文档中自动识别和提取出有价值的信息,如实体、关系、事件等。随着自然语言处理(NLP)和机器学习技术的发展,信息抽取的能力和应用范围不断扩大。

信息抽取技术指的是利用计算机算法从文本中自动识别和提取预定义类型的信息的过程。这些信息通常包括但不限于人名、地点、组织、时间表达、专有名词、事件和实体之间的关系等。

意义
在IDP流程中,信息抽取的意义主要体现在:

● 支持决策和分析:通过从大量文档中抽取关键信息,可以为决策制定和数据分析提供有价值的输入。

● 提高自动化程度:自动化的信息抽取减少了人工审核和录入的需要,提高了处理效率和准确性。

● 促进知识管理:信息抽取有助于构建知识库,支持知识检索和管理。

技术
信息抽取技术主要包括以下几个关键组成部分:

1.  实体识别(Named Entity Recognition, NER):识别文本中的具名实体,如人名、地点和组织。

2.  关系抽取:识别文本中实体之间的关系,如“公司-CEO”或“人物-出生地”等。

3.  事件抽取:识别文本中的事件及其相关属性和参与实体,如事件类型、时间、地点和参与者等。

4.  观点抽取(Opinion Mining):从文本中抽取观点、情感和评价,通常用于产品评论、市场分析等领域。

5.  术语抽取:从专业文档中识别和提取关键术语和定义,用于构建术语库或知识图谱。

发展
信息抽取技术的发展经历了以下几个阶段:

● 规则基础方法:早期的信息抽取系统主要依赖于手工编写的规则。这种方法在特定领域内效果明显,但缺乏通用性和扩展性。

● 机器学习方法:随着机器学习技术的发展,信息抽取开始采用监督学习、半监督学习和无监督学习方法。通过训练模型识别文本模式,提高了抽取的准确率和灵活性。

● 深度学习方法:近年来,基于深度学习的信息抽取方法成为研究热点,尤其是利用CNN、RNN和Transformer等神经网络模型。这些模型能够更好地理解文本的深层次语义,显著提高了信息抽取的性能。

● 端到端信息抽取:最新的研究趋势是开发端到端的信息抽取系统,这些系统能够直接从原始文本中抽取出结构化信息,无需复杂流程。

<合合TextIn - 合合信息旗下OCR云服务产品 智能文档处理云平台提供一站式智能文档处理产品服务,提供领先的信息抽取技术>

file

九、系统集成:将IDP处理后的数据集成到企业系统
系统集成在智能文档处理(IDP)完成之后,将处理得到的结构化数据有效地集成到企业的业务系统中,对于提升企业的业务流程效率和推进企业信息化建设至关重要。这一过程需要将IDP系统与企业内部的各种业务系统(如CRM、ERP、CMS等)以及全球主流的企业软件平台进行有效对接。本章节将详细介绍IDP处理后的数据如何通过多种方式集成到中国及全球的主流各种业务系统里,服务于企业业务流程和企业信息化。

数据集成的方式
API集成
● 定义:应用程序接口(API)提供了一种让不同软件系统彼此通信的方法。通过开发和使用API,IDP系统可以将结构化数据直接发送到目标业务系统。

● 应用场景:实时数据传输、需要高度定制化集成的场景。

文件导入/导出
● 定义:一种基础但广泛使用的数据集成方法,涉及将数据导出为通用格式(如CSV、XML、JSON等),然后导入到目标系统。

● 应用场景:批量数据处理、非实时数据更新需求。

数据库集成
● 定义:直接通过数据库级别的操作,将IDP处理后的数据存储到企业的数据库系统中,再由各业务系统从数据库中读取所需数据。

● 应用场景:数据量大、需要长期存储和复用的场景。

集成到全球主流业务系统的示例
集成到CRM系统
● 场景:将客户相关的文档(如合同、通信记录)处理后的数据自动更新到客户关系管理(CRM)系统,以提供更准确的客户视图和服务。

● 技术方式:API集成、数据库集成。

集成到ERP系统
● 场景:将发票、订单等财务文档处理后的数据自动录入企业资源计划(ERP)系统,简化财务流程,提高财务处理速度和准确性。

● 技术方式:文件导入/导出、API集成。

集成到CMS系统
● 场景:将新闻、报告等内容文档处理后的数据自动归档和分类到内容管理系统(CMS),加速内容的发布流程。

● 技术方式:API集成、中间件技术。

集成到全球云平台
● 场景:将处理后的数据集成到阿里云、百度云、AWS、Azure、Google Cloud等全球云平台提供的数据库和应用服务中,利用云平台的强大计算和存储能力支持企业的大数据分析和应用开发。

● 技术方式:API集成、中间件技术。

<合合TextIn - 合合信息旗下OCR云服务产品 智能文档处理云平台提供一站式智能文档处理产品服务,提供API集成文档、全语言示例代码>
file

Uploading file...

如有帮助,请多关注
TeahLead KrisChang,10+年的互联网和人工智能从业经验,10年+技术和业务团队管理经验,同济软件工程本科,复旦工程管理硕士,阿里云认证云服务资深架构师,上亿营收AI产品业务负责人。

前言:

在之前的文章中,我们完成了前面五个部分的内容学习,包括:

第二部分:构建动态程序集

第三部分:构建模块(
Module

第四部分:构建类型(
Type

从今天开始,将进入本系列的难点与核心,IL 指令相关的教程。

为了更详细的介绍 IL 指令相关内容,第六部分:IL 指令 内容,将分为多个章节进行介绍:

1、概述(本篇):概要性的介绍 IL 的相关内容。

2、后续(多篇):对 IL 指令进行详细和分类别的介绍。

1、IL 语言介绍

在.NET平台上,IL(Intermediate Language)是一种中间语言,也称为MSIL(Microsoft Intermediate Language)或CIL(Common Intermediate Language)。

它是由高级语言(如C#、VB.NET等)编译而成的一种低级语言表示形式。

IL 代码被保存在 .net 程序集中,并由公共语言运行时(CLR)执行。

A、IL语言的作用和特点

IL 语言在.NET开发中起着至关重要的作用,它具有以下特点:

  • 跨平台性:IL代码是与特定平台无关的中间代码,可以在任何支持CLR的平台上执行。
  • 中间语言:IL代码处于源代码和机器码之间的中间层,充当了源代码和特定硬件架构之间的桥梁。
  • 安全性:IL代码受到CLR的严格管理,包括类型安全检查、内存管理等,提高了程序的安全性。
  • 可移植性:由于IL代码的跨平台性,使得.NET程序具有较强的可移植性,可以在不同平台上运行。

B、 IL代码与源代码之间的关系

IL 代码是由高级语言编译而成的,它与源代码之间存在着一一对应的关系。

在编译过程中,高级语言编译器将源代码转换为对应的IL代码,并将其存储在 .net 程序集中。

当程序需要执行时,CLR会将IL代码转换为特定平台的本地机器码,然后执行。

IL 代码承载了程序的逻辑结构和计算过程,通过学习和理解IL代码,可以更深入地了解.NET程序的内部工作原理,为程序的优化和调试提供帮助。

2、IL 指令基础

在.NET平台上,IL(Intermediate Language)指令是构成IL代码的基本单元,它们用于执行各种操作,包括加载和存储数据、执行算术和逻辑运算、控制程序流程等。

IL指令的理解对于深入理解.NET程序的内部工作原理至关重要。

A、IL 指令的结构和格式

IL 指令由操作码(OpCode)和操作数(Operand)两部分组成。

  • 操作码:表示要执行的操作,如加载数据、执行算术运算、跳转等。
  • 操作数:提供给操作码的参数,用于指定要操作的数据或执行的具体行为。

IL指令通常以字节形式存储在 .net 程序集中,CLR在执行时会逐条解释和执行这些指令。

B、 IL 指令集概述

.NET平台定义了一套丰富的IL指令集,涵盖了各种常见的操作和计算需求。这些指令可以分为多个类别,包括但不限于:

  • 加载和存储指令:用于加载和存储数据到计算堆栈或本地变量表中。
  • 算术和逻辑指令:执行加减乘除、位运算、逻辑运算等操作。
  • 控制流指令:用于实现条件判断、循环、跳转等控制程序流程的操作。
  • 对象模型指令:进行对象的创建、字段操作、方法调用等操作。
  • 方法调用指令:用于调用其他方法或函数。

掌握这些指令的含义和用法,对于编写高效的IL代码、理解程序的执行过程以及进行代码优化都至关重要。

C、 常见的IL指令分类

IL 指令根据其功能可以分为多个类别,例如:

  • 栈操作指令:包括将数据推入栈、从栈中弹出数据等操作。
  • 流控制指令:用于实现条件分支、循环和跳转等控制流程的操作。
  • 类型转换指令:用于进行不同类型数据之间的转换。
  • 异常处理指令:用于实现异常捕获和处理。

通过学习和掌握这些IL指令,可以更好地理解.NET程序的内部执行过程,为程序的优化和调试提供帮助。

3、IL 指令示例和说明

在前面的章节中,有一些示例中,曾出现过 IL 的相关代码,如:

 DynamicMethod dynamicMethod = new DynamicMethod("MyMethod", typeof(void), null);
ILGenerator
il =dynamicMethod.GetILGenerator();
il.EmitWriteLine(
"hello world!");
il.Emit(OpCodes.Ret);

在上述代码中,我们通过 DynamicMethod(或 MethodBuilder)获得 ILGenerator 这个用于编写 IL 指令的类,之后用它来编写 IL 指令。

IL 指令的固定结尾:

il.Emit(OpCodes.Ret);

指令 Ret 是 Return 的简写,代表 IL 指令结束并返回。

下面再举几个示例,可以更好地理解IL指令的使用和功能。

A、 加载和存储指令示例

  1. ldarg.0:将第一个参数加载到栈顶。
  2. ldloc.1:将第二个本地变量加载到栈顶。
  3. stloc.2:将栈顶的值存储到第三个本地变量中。

B、 算术和逻辑指令示例

  1. add:将栈顶两个值相加。
  2. mul:将栈顶两个值相乘。
  3. and:对栈顶两个值执行按位与操作。

C、 控制流指令示例

  1. br label:无条件跳转到标记为label的位置。
  2. beq label:如果相等则跳转到标记为label的位置。
  3. call method:调用指定的方法。

D、 对象模型指令示例

  1. newobj:创建一个新对象实例。
  2. ldfld:将对象字段的值加载到栈顶。
  3. callvirt method:调用虚方法。

E、 方法调用指令示例

  1. call method:调用静态方法。
  2. callvirt method:调用实例方法或虚方法。
  3. ret:从当前方法返回。

通过这些示例,你可以看到不同类型的IL指令以及它们在程序中的应用场景。

深入理解这些指令对于编写高效的IL代码和理解.NET程序的执行过程都具有重要意义。

4、IL 代码查看工具

在前面的教程中,我们在示例中都提供C#代码和对应的反编绎示例代码,

借助于反编绎工具,可以帮助我们查看生成的代码是否符合我们的设定。

反编绎的所有工具,都带有查看 IL 的功能,但有一些是收费的,免费的如:

VS 安装包自带的(注意:ilasm 是汇编工具,ildasm 是反汇编工具,不要弄错了):

IL Disassembler (ildasm.exe):IL Disassembler 是一个反汇编工具,可以将.NET程序集中的IL代码反编译成人类可读的形式。通过IL Disassembler,我们可以查看编译后的程序集包含的IL指令及其对应的源代码行号。

我们可以在VS的安装目录下直接搜:ildasm.exe,即可找到,通常在:C:\Program Files (x86)\Microsoft SDKs\Windows\vXXX\bin\ 目录下。

第三方的:

1、ILSpy:ILSpy 是一个开源且免费 .NET 程序集反编译工具,可以查看和编辑.NET程序集、IL代码。它提供了直观的用户界面,方便我们查看和分析IL代码。
2、dnSpy:dnSpy 是一个强大的.NET程序集反编译工具,可以查看和编辑.NET程序集、IL代码以及调试程序。它提供了直观的用户界面,方便我们查看和分析IL代码。

ILSpy 在 Windows 商店中可以直接搜索安装,或者在开源地址下载:
Github 地址

dnSpy 在开源处下载:
GitHub 地址

通过使用这些工具,我们可以更好地理解.NET程序的内部结构和执行过程,帮助我们优化代码、调试问题并提高程序性能。

5、总结:

本篇主要介绍了 IL 指令,包括IL指令的基本结构、常见指令类型和示例应用。

IL 指令是构成IL代码的基本单位,通过不同指令的组合实现对数据的操作和流程控制。

在学习 IL 指令时,需要理解指令的作用、操作码和操作数的含义,以及如何正确使用IL指令构建有效的IL代码。

通过本教程,可以更深入地了解IL指令的功能和用法,为.NET应用程序的动态生成和优化提供基础支持。

同时,本篇做为 IL 指令的开篇部分,主要介绍一些概述内容。

后续,我们会针对具体的指令,进行更详细的介绍。

何为原型链呢

就是实例对象和原型对象之间的链接,每一个对象都有原型,原型本身又是对象,原型又有原型,以此类推形成一个链式结构.称为原型链。

这里又扯到了另外两个概念了。

实例对象>>> 先往下看实例对象

原型对象>>> 先往下看 原型对象

实例对象

说到这里。我们另外再来提一提 另一个东西: 构造函数。那既然提到了构造函数 由不得不提普通函数了。

先来讲一下构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值。

例如:

let Num = function Num() {
    this.add = function (a, b) {
        return a + b
    }
}

let n = new Num()
console.log(n.add(1, 2));

这里实例对象已经出来了。就是在你new 这个 构造函数的时候。就已经创建了实例对象 在本文中 n就是一个实例对象

**这里简单说一下实例对象在创建成功时会发生什么变化。

  1. 在内存中创建一个新的空对象;
  2. 让this指向这个新的对象。这里this指向问题 我只用一句话就能总结:
    谁调用this就指向谁
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法;
  4. 返回这个新对象(所以构造函数里面不需要return)。


再来讲一下普通函数

普通函数就是.... 就是最普通的函数 例如

function add(a, b) { return a+b };
add(1,2)

虽然上述两种方式。都能得到结果
3

但是两种声明以及使用的方式都不一样。


那这里总结下区别

  1. 构造函数首字母要大写,类似于python中的类
  2. 构造函数是通过new操作符来创建实例对象的,而普通函数则不需要。


这里还有个点。

实例对象创建成功后 已经有了一个__proto__的内置属性了。

而构造函数本身有个属性是prototype 称之为对象原型

原型对象

原型对象是构造函数上的一个属性,用来创建公共的方法。也就是prototype

举个例子。

直接创建个构造函数。然后赋值个方法。

//语法: 构造函数.prototype.方法名 = function() {}
function Animal(name) {
    this.name = name
}

// 赋值公共方法
Animal.prototype.eat = function () {
    console.log(`${this.name}在吃饭`)
}

let dog = new Animal("狗")
let cat = new Animal("猫")
dog.eat()
cat.eat()
console.log(dog.eat === cat.eat)    // true

结果

狗在吃饭
猫在吃饭
true

这里扯到了 原型对象 那就再讲讲另一个概念 对象原型。其实这个概念可以忽略不计。

对象原型

**对象原型是实例对象(对象)身上的一个属性, 该属性为 _
proto
_ **

//语法: 构造函数.prototype.方法名 = function() {}
function Animal(name) {
    this.name = name
}

// 赋值公共方法
Animal.prototype.eat = function () {
    console.log(`${this.name}在吃饭`)
}

let dog = new Animal("狗");

console.log(dog.__proto__);
console.log(dog.__proto__ === Animal.prototype);

结果

{ eat: [Function (anonymous)] }
true

短暂总结一下

这里捋一下关系

  1. 每个构造函数都有一个原型对象 原型对象的(
    prototype
    )
  2. __proto__
    等于其构造函数的
    prototype
    ,即每个
    __proto__
    都指向其构造函数的
    prototype
  3. 原型对象(prototype)
    ==
    对象原型(__proto__)

constructor

construct是原型对象(prototype) 和 对象原型(__proto__)身上的一个属性

而 constructor会记录当前对象属于哪个构造函数。

这里举个例子吧、

//语法: 构造函数.prototype.方法名 = function() {}
function Animal(name) {
    this.name = name
}

// 赋值公共方法
Animal.prototype.eat = function () {
    console.log(`${this.name}在吃饭`)
}

let dog = new Animal("狗");

dog.constructor.prototype
console.log(dog.constructor.prototype)

结果 这里在node中看不出来。我们直接看浏览器中的

这里就很好理解了。

其实
constructor
的出现原本就是用来进行对象类型判断。任何对象都有
constructor
属性。

那你说这个有啥用???

因为我们是搞爬虫的吗。肯定是很有用的。

constructor 本来就是用来找到其上层构造函数的。那我们在设置补环境框架。或者是在补环境的时候不就能容易找到最外层的构造环境了吗?

原型链

很好现在基础概念都懂了。那我们是不是可以重新梳理了一下呢?

我的理解是原型链的构成包含了上文我讲的的这些部分。

所谓原型链的流程(仅本人在补环境中的理解):

当你在寻找一个方法或者属性。如果该对象自身没有这个属性 或者方法。

那这个引擎(JS)就会沿着原型链向上去找。直到找到这个属性 或者方法。

直到到达原型链的最顶层也就是我们上文说的Prototype

那话说到这里。

说白了 原型链其实就是JavaScript中用于实现对象继承的一种机制。

好了 此文完结。懂各种概念就行

有时候也是命运一样,遇到好的人、好的事情、一切都会很顺利;遇到一些不顺利、可能会各种被折磨、否极泰来、在低谷是需要有足够的耐心隐忍,放弃是最容易的、往往坚持都是最艰难的。

能不给你批准的费用预算、一分钱也不给批准、就当你没提交预算,绝对不会跟你商量理由,就是删除掉了完事儿,公司要降本,自己就是干技术的,为什么还需要购买?那是技术水平能力不行?

拼命督促项目进展、要求项目验收、要求阶段性成果展示、要求系统全面上线、要求拿出完美的项目后续计划、人员配置计划、系统建设未来路线以及核心里程碑、从管理的角度是完全正确的、也是应该要提供的;一方面人员流动大、一方面项目人手紧张、一方面项目问题多、一方面组织在调整、一方面项目熟悉没多久,其实很难拿出完美的PPT成果规划等等。

其次就是能不让你管理的项目绝对不会让你管理、给年轻人更多机会、让更能干的人去干、让更有经验的人去干、让更熟悉团队人员情况的人去管理,让更有干劲儿的人去干,公平竞聘上岗,可以用各种合法的理由借口把这个项目的管理权限转给其他人。

制定相对高的工作任务目标、让你拼命干都可能无法完成、完不成就给底绩效。打底绩效、不管解决了什么难题,都是底绩效,否定产出,达不到领导的预期,各种不认可不认同,让你精神崩溃,因为定目标时就不能定过于、理由是需要挑战极限。

要你发工作邮件前都需要进行内部审核,防止有工作内容错误,防止管理失控、防止没沟通好就发出去了,防止你性子急,防止你引起各种麻烦,虽然管理上也没什么大问题,束缚住你手脚,工作积极性给你打击一下。
各种反驳、你干得都不对、不管怎么干都是错、各种挑错误、没大错误就找小错误、发证你的设计都是垃圾,反正无底线的反驳你,你干的就是全错,首先需要把你彻底饱和打击。

晨会上在大家面前攻击你、因为是领导,领导说了就算,因为很多事情没绝对的对与错的差别,解释权在领导,所以你说A就说A错,要按B来,你说B就说B错,要按A来,大家也不是傻子,领导那么明显的攻击你,大家也自觉的会跟你保持距离,无形中就会孤立你。
开会不带你、拉大家独立开会、只要能不带你的全不带你,让你无法了解完整的信息,无法了解部门动态,超级明显彻底的孤立你。

在各种工作群里,找你没及时答复、答复有缺陷的有瑕疵的回答、公司足够大,早晚会发现一些问题点,然后把小问题放大,哪怕小小的问题都上纲上线,让你必须承认错误,让你必须改正错误,各种训斥教训,打击工作热情,打击自尊心。

各种重要的工作群、对接群,能不加你的都不加你,能把你剔除的都剔除,能解散的都解散;群主必须是自己,自己掌控完全主动权,有问题时随时可以把你剔除;若你独立建立了工作对接群,没把领导加上,领导就说你开展工作不透明、干事情绕过领导、信息不透明等等,各种打击你。若你以前对接的工作群,就全部拉到新建设的新的工作群里。把以前的群慢慢的冷处理,变成僵尸群,里面提的问题不处理,只有在新群里的问题才处理。

不让对接业务,整理的需求不给开发、不进行优先级排序,更不排期、你做的事情只要有一点点疏忽,只要有BUG,就狂殴狂批,上纲上线,打击自尊心、打击自信、让你怀疑人生;丧失对公司价值观文化的信念。不接受你的好建议好意见,就当没听见、根本不当回事情,不打招呼,不联系你,把你当空气。
你整理的需求就当空气,看都不看,就当不存在,安排人重新设计、重新整理、重新排期、重新开发;根本不管你投入的精力、细心分析的劳动成果。

与业务联合一起孤立,一起为难,只要你有任何风吹草动让其他人都需要及时汇报到领导那边,然后盯着你,防着你,你干任何事情都安排人盯着,让其他人有任何动作都及时汇报。
找业务部门的人,收集投诉意见,引导对口业务部门,提出投诉,哪怕一点点儿不满意的,都可以成立投诉,受理投诉,然后扣上被业务部门投诉的帽子。

能不给的权限全不给、有些核心操作权限更是不给、让你无法独立处理业务问题,必须要找他才可以给解决,否则死活不给解决,不给对接,硬刚到底,让你无法对接任何业务问题。

交接抢夺你手上的工作成果,你艰难开拓的供应商给你抢走,不让你参与各项与供应商相关的工作;艰难开拓的全国性的维修渠道给你抢走;各种奔波折腾后开拓的各省的政府备案资质、备案平台账户等给你抢走;就是可以按各种理由,例如公司统一管理对外的系统、统一管理政府对接系统、统一管理外部资源账户,哪个说法都可以正规成立,反正解释权在领导,领导有权限分配资源,进行调整,几下就给你的劳动成果调整没了;收回后能否管理好不好先不管,反正有足够时间可以折腾;哪怕有各种损失也是公司损失而已;目标就是先把你打倒了再说。

哪怕交接你手上的工作量,有难度,有波折,有空白窗口期,都不管,先强制交接、人手不足就加人,技术能力不行就寻求外部支援、因为购买专业的技术支持,只要领导愿意也可以成立,专业的事情让专业的人干,符合社会分工原则,效率更高。

平时要温和、能不得罪人的,都不得罪人;不是自己管辖范围的,不是自己分工内的,能不管的不要管;防止引起矛盾;与上级保持良好沟通、上级再烂能当上级领导也是有过人之处、有普通员工无法发现的优点、有一技之长。
平时低调的人一般不会引起别人的反感、保持低调、废话少说、能不说的都不要说,哪些应该是要说的,哪些应该是不要讲的多思考,祸从口出;随便说话其实就是没敬畏之心、没尊重其他人,多听别人怎么讲。

静悄悄的、不生不响的、抓重点、好好干活、时间长了、自然领导都赏识喜欢重用;需要有足够的耐心、毅力、当个经得起折磨的皮实的员工、很多都需要用足够的间来证明实力。在低谷时是就少说一些话,哪怕说出来也没什么分量。