- 浏览: 930180 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (537)
- Java SE (114)
- Struts (18)
- Hibernate (25)
- Spring (3)
- Page_Tech (41)
- Others (87)
- Database (29)
- Server (24)
- OpenSource_Tools (15)
- IDE_Tool (22)
- Algorithm (28)
- Interview (22)
- Test (28)
- Hardware (1)
- Mainframe (25)
- Web application (4)
- Linux (3)
- PHP (17)
- Android (1)
- Perl (6)
- ubuntu (1)
- Java EE (9)
- Web Analysis (5)
- Node.js (2)
- javascript (2)
最新评论
-
一键注册:
request.getRequestURL()和request.getRequestURI() -
SuperCustomer:
...
SED的暂存空间和模式空间 -
juyo_ch:
讲得挺好理解的,学习了
java 死锁及解决 -
chinaalex:
最后一题答案正确,但是分析有误.按照如下过程,上一行为瓶,下一 ...
zz智力题 -
liaowuxukong:
多谢博主啦,弱弱的了解了一点。
C++/Java 实现多态的方法(C++)
Java在需要使用类的时候,才会将类加载,Java的类加载是由类加载器来完成的。当在命令行模式下执行java XXX.class指令后,java运行程序会尝试找到JRE安装的所在目录,然后寻找jvm.dll(默认是在JRE目录下bin\client目录中),接着启动JVM并进行初始化动作,产生Bootstrap Loader,Bootstrap Loader会加载Extended Loader,并设定Extende Loader的parent为Bootstrap Loader。接着Bootstrap Loader会加载System Loader,并将System Loader的parent设定为Extended Loader。 我们把test1文件放在D:\盘根目录下 如果我们把test1.java放在lib\ext\classes下,结果如图 Class.forName()和classloader.loadClass()的比较 测试代码: public class test { Main.java public class main { 可以看出Class.forName(String className)方法默认是加载静态代码块的,而它的另一个方法Class.forName(String className,boolean initialize,ClassLoader loader)则可以控制是否调用静态代码块。Class.forName只是让类加载,并没有把类初始化,只有当调用newInstance时才初始化类,调用构造方法等。 调用ClassLoader时: public class main { 可见,当我们用ClassLoader进行类加载时,不会调用静态代码块,相当于Class.forName的第二个方法,只有在newInstance时才调用静态代码块——》初始化变量——》调用构造方法——》生成类实例。 事实上,JVM在加载类时,需要经过如下几个步骤。 事实上,ClassLoader也有两种方法,只是第二个带参数的方法是受保护的。 例子:JDBC Driver的加载,网上都说JDBC驱动是通过DriverManager,必须在DriverMangaer中注册,如果驱动类没被初始化,则不能注册到DriverManager中,因此必须用forName而非loadClass。事实上这种说法是错误的,forName并没有把类初始化,类的初始化只能通过两种方式: LoadClass()方法加载类及初始化过程: newInstance(): 从上边的断点调试可以看出,静态代码块不是在初始化阶段完成的,它陷于类初始化,先于普通变量默认分配(整型分配为0,字符串分配为null),这也就是为什么我们不能在静态代码块中引用普通变量的原因之一,这与上面所谓的“分配”、“初始化”相违背。 所以我觉得JVM的类加载及初始化过程应该是这样的。 1. 类加载:Bootstrap Loader——》Extended Loader——》System Loader 因此ClassLoader.loadClass(String className)和Class.forName(String className)两者的区别就一目了然了。如下: 而loadClass直接就干“加载类“的这些事,不干多余的事儿。 注:整合了一些javaeye上兄弟们的心血,实际断点调试了一把,有可能我的结论是片面的,欢迎大家指正。(Ps:再次鄙视下百度的文本编辑功能,直接copyword,格式全乱,给大家造成不便,请原谅)
Bootstrap Loader通常由C编写而成,Extended Loader是由Java编写而成,实际是对应于sun.misc.Launcher$ExtClassLoader(Launcher中的内部类).System Loader是由java编写而成,实际对你关于 sun.misc.Launcher$AppClassLoader(Launcher中的内部类)。
Bootstrap Loader会搜索系统参数sun.boot.class.path中指定位置的类,默认是JRE所在目录的classes下的.class文件,或lib目录下.jar文件中(如tr.jar)的类并加载。可用System.getProperty(“sun.boot.class.path”)来显示sun.boot.class.path中指定的路径。
Extended Loader是由Java编写而成,会搜索系统参数java.ext.dirs中指定位置的类,默认是JRE目录下的lib\ext\classes目录下的.class文件,或lib\ext目录下的.jar文件中的类并加载。
System Loader是由java编写而成,会搜索系统参数java.class.path中指定位置的类,也就是Classpath所指定的路径,默认是当前工作路径下的.class文件。
在加载类时,每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。所以在加载类顺序为:Bootstrap Loader——》Extended Loader——》System Loader的顺序来寻找类,若都找不到,会抛出NoClassDefFoundError.
类加载器在Java中是以java.lang.ClassLoader类型存在,每一个类被加载后,都会有一个Class的实例来代表,而每个Class的实例都会记得自己是由哪个ClassLoader加载的。可以由Class的getClassLoader()取得加载该类的ClassLoader,而从ClassLoader的getParent()方法可以取得自己的parent。
例子:
public class test1 {
public static void main(String args[]){
test1 t=new test1();
Class c=t.getClass();
ClassLoader loader=c.getClassLoader();
System.out.println(loader);
System.out.println(loader.getParent());
System.out.println(loader.getParent().getParent());
}
}
结果
sun.misc.Launcher$AppClassLoader@197d257
sun.misc.Launcher$ExtClassLoader@7259da
null
依次以Bootstrap Loader——》ExtClass Loader——》AppClass Loader的顺序来寻找类,由于前两者都找不到,最后在Classpath中找到了类并加载。此时,它的Classloader就是AppClassLoader,而其parent为ExtClassLoader,再parent为BootstrapLoader,由于BootStrapLoader是C语言写的,所以此处为null。
因为此时的class可在ExtClassLoader的设定路径下找到,所以会由ExtClassLoader来加载test1类,而其parent肯定为null了,再取parent报错了。
Test.java
package ying;
static{
System.out.println("静态代码块运行");
int x=1;
}
public test(){
System.out.println("构造方法运行");
}
}
package ying;
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//ClassLoader loader=test.class.getClassLoader();
//可以用别的classloader来load其他类
ClassLoader loader=main.class.getClassLoader();
/*
System.out.println("before load");
Class c=loader.loadClass("ying.test");
System.out.println("after load");
System.out.println("------华丽的-----------------------分割线-----");
System.out.println("before load newInstance");
test t=(test) c.newInstance();
System.out.println("after load newInstance");*/
System.out.println("before forName");
Class c2=Class.forName("ying.test");
System.out.println("after forName");
c2.newInstance();
System.out.println("------华丽的-----------------------分割线-----");
System.out.println("before forName false");
Class c3=Class.forName("ying.test",false, loader);
System.out.println("after forName false");
c3.newInstance();
}
}
此时时调用Class.forName,结果如下:
before forName
静态代码块运行
after forName
构造方法运行
------华丽的-----------------------分割线-----
before forName false
after forName false
构造方法运行
package ying;
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//ClassLoader loader=test.class.getClassLoader();
//可以用别的classloader来load其他类
ClassLoader loader=main.class.getClassLoader();
System.out.println("before load");
Class c=loader.loadClass("ying.test");
System.out.println("after load");
System.out.println("------华丽的-----------------------分割线-----");
System.out.println("before load newInstance");
test t=(test) c.newInstance();
System.out.println("after load newInstance");
/* System.out.println("before forName");
Class c2=Class.forName("ying.test");
System.out.println("after forName");
c2.newInstance();
System.out.println("------华丽的-----------------------分割线-----");
System.out.println("before forName false");
Class c3=Class.forName("ying.test",false, loader);
System.out.println("after forName false");
c3.newInstance();*/
}
}
结果:
before load
after load
------华丽的-----------------------分割线-----
before load newInstance
静态代码块运行
构造方法运行
变量a初始化1
after load newInstance
1. 加载——找到相应的class字节码文件,读入JVM
2. 链接——包括进行验证,准备和解析
a) 验证:确信引入类型的正确性,即class是否符合java规范并且不会损害JVM的完整性。
b) 准备:为类变量分配内存同时设置默认初始值,如上例中加载test时,会初始化a=0;x=0;
c) 解析(可选):根据loadClass方法的第二个参数来判断是否需要解释。解析是把符号引用转为直接引用的过程,如原来JVM知道类test中有一个成员叫“a”,通过解析则知道了该成员的地址是0xBBEDF,以后使用这个成员时,就直接去这个内存地址去找了。同时这个阶段,类的其他方法也会被映射到某个内存地址以待调用。
3. 初始化——激活类变量的初始化java代码。利用类定义的java代码确定成员变量的初值(若没有相应的java代码对其进行初始赋值操作,则会沿用准备阶段获得的该类型默认值),在这个阶段,所有的静态代码都会被执行,事实上,类在编译时期编译器会把这些静态代码封装到一个<clinit>方法中去,在使用这个类的时候,初始化过程就会调用这个<clinit>方法。这个方法程序员不能调用,只能被JVM调用。
如下:
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// 首先检查该name指定的class是否有被加载
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
//如果parent不为null,则调用parent的loadClass进行加载
c = parent.loadClass(name, false);
} else {
//parent为null,则调用BootstrapClassLoader进行加载
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
//如果仍然无法加载成功,则调用自身的findClass进行加载
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
而用户使用的是一个参数的方法,而一个参数的方法实际调用了两个参数的方法,第二个,因此在这里可以看出通过loadClass加载类实际上就是加载的时候并不对该类进行解释,因此也不会初始化该类。而Class类的forName方法则是相反,使用forName加载的时候就会将Class进行解释。
a) 隐式:使用New关键字,new一个对象
b) 显示:通过class的New Instance方法。
事实上forName和loadClass的区别也就在于那个“解释”的过程是否调用。ForName调用了,loadClass没调用,如此而已。
大家可以看下DriverManger的源码:
private static void loadInitialDrivers() {
String drivers;
try {
drivers = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("jdbc.drivers"));
} catch (Exception ex) {
drivers = null;
}
println("DriverManager.initialize: jdbc.drivers = " + drivers);
if (drivers == null) {
return;
}
while (drivers.length() != 0) {
int x = drivers.indexOf(':');
String driver;
if (x < 0) {
driver = drivers;
drivers = "";
} else {
driver = drivers.substring(0, x);
drivers = drivers.substring(x+1);
}
if (driver.length() == 0) {
continue;
}
try {
println("DriverManager.Initialize: loading " + driver);
Class.forName(driver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}
}
我们发现,其内部其实也是调用了forName方法。
类加载(loadclass())(加载)——》newInstance()(链接+初始化)
newInstance():
(开始连接)静态代码块——》普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName(Stirng className)一个参数方法加载类及初始化过程:
类加载(Class.forName())(加载)——》静态代码块——》newInstance()(链接+初始化)
(开始连接)普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName()三个参数的加载类及初始化过程同classLoader一样。
2. 静态代码块初始化
3. 链接:
a) 验证:是否符合java规范
b) 准备:默认初始值
c) 解析:符号引用转为直接引用,解析地址
4. 初始化
a) 赋值:java代码中的初始值
b) 构造:构造函数
而class.forName默认是老好人,就把加载静态代码块的工作也一并做了。但是又有一个带3个参数的方法,用来决定静态代码块的位置变化,加载(true)的话就把的位置提到“类加载“部分,不加载(false)的话就把它的位置滞后到newInstance的时候。
发表评论
-
maven 在Mac OS下运行的问题总结
2014-05-16 17:24 858在maven下生成基本的项目结构。 生成eclipse项 ... -
【zz】 java函数参数类型后添加三点的用法
2012-07-02 09:48 1067今天看到一个没见过的函数参数列表test(int... a), ... -
【zz】Java编码的理解和Java加载器的理解
2012-06-08 15:59 775一,我对java中编码的理解1. 编码的产生 对电脑而言 ... -
类加载器入门级应用
2012-06-08 15:17 9551、类加载器负责加载 Ja ... -
ClassLoader详解
2012-06-08 14:23 1270Point One 将J2EE应用程序移植到W ... -
Java静态代理与动态代理
2012-05-29 10:32 968JAVA的静态代理与动态代 ... -
JDK的动态代理深入解析(Proxy,InvocationHandler)(转)
2012-05-29 10:31 5217调用处理器InvocationHandle ... -
zz 动态反射实现AOP的简单原理
2012-05-28 17:46 925其实AOP的意思就是面向切面编程. OO注重的是我们 ... -
理解Java枚举在单例模式的应用
2012-06-05 15:50 13035.3.9 单例和枚举 按照《高效Java 第二版》中的说 ... -
Java 枚举的介绍
2012-05-23 16:50 0一、使用简单程序完成枚举的功能 例:使用简单类完成枚举操作 ... -
枚举类型的用法
2012-06-05 15:50 1458DK1.5引入了新的类型——枚举。在 Java 中它虽然算 ... -
单例模式的七种写法 (包括1.5新特性)
2012-05-23 16:18 0第一种(懒汉,线程不安全): <!--<br / ... -
重写hashCode方法的意义
2012-05-23 16:01 1681Java中的很多对象都override了equ ... -
JDK Log的设计思想
2012-05-23 14:39 1340最近在看《Agile Java》,看到日志一节,收获颇多,所以 ... -
[zz] Synchronized和Static Synchronized区别
2012-05-23 14:07 810通过分析这两个用法的分析,我们可以理解java中锁的概念。一 ... -
双精度、单精度的有效位数
2012-05-22 17:25 5149浮点数7位有效数字。(应该是单精度数) 双精度数16位有效 ... -
DecimalFormat 使用方法
2012-05-22 16:44 1052我们经常要将数字进行格式化,比如取2位小数,这是最常见的。Ja ... -
Java Applet 无法运行的一个问题
2012-04-28 15:09 2564当你用JDK1.6开发出的新功能,在JDK1.6上re ... -
JDK1.5之中的Map相关的类
2012-04-26 10:14 1894java5的java.util包提供了大量集合类。其中最常用的 ... -
设计模式应用场景总结
2012-04-11 16:47 1299在J2EE的开发和测试中,其实不知不觉已经使用了许多设计模式。 ...
相关推荐
挤塑板生产用造型机sw18_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
轿厢式电梯sw12可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
1、文件说明: Centos8操作系统thai-scalable-waree-fonts-0.6.5-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf thai-scalable-waree-fonts-0.6.5-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
内容概要:本文详细探讨了永磁同步电机(PMSM)中二阶自抗扰控制(ADRC)的应用,特别是将速度环和电流环合并的设计。文中介绍了ADRC的核心组件,包括跟踪微分器(TD)、扩张状态观测器(ESO)和非线性状态误差反馈控制律(NLSEF),并通过具体的Python和Matlab代码展示了这些组件的工作原理。此外,文章讨论了线性和非线性ADRC在合并控制中的实现及其优缺点,并强调了在Simulink建模时需要注意的技术细节。通过这种方式,ADRC能够显著提高电机的动态性能和抗干扰能力,尤其在面对复杂工况时表现更为突出。 适合人群:从事电机控制系统设计的研究人员和技术工程师,尤其是对自抗扰控制感兴趣的读者。 使用场景及目标:适用于需要提高永磁同步电机控制精度和效率的实际工程项目,旨在帮助读者理解和掌握ADRC的基本原理及其在速度环和电流环合并控制中的应用。 其他说明:文章不仅提供了理论解释,还包括了大量的代码片段和仿真技巧,有助于读者在实践中验证和优化控制策略。
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
《毛毛虫的袜子》伴奏.mp3
内容概要:电子设计竞赛(电赛)是旨在培养学生创新能力、实践能力和团队合作精神的科技竞赛。文章详细介绍了电赛的目的、流程、参赛要求及常见问题解答。竞赛目的在于通过解决实际问题激发创新思维、提升实践技能、增强团队合作和促进学术交流。竞赛流程分为报名、准备、竞赛、评审和颁奖五个阶段。参赛要求包括团队组成(3-5名学生,可跨专业组队)、配备指导老师、选择符合规定的项目主题以及确保作品符合技术规范。常见问题解答涵盖参赛专业限制、所需准备材料、评审标准和培训指导等方面; 适合人群:对电子技术感兴趣并希望提升自身能力的大学生; 使用场景及目标:①为有意参赛的学生提供详细的参赛指南;②帮助学生了解竞赛流程和要求,提前做好充分准备; 阅读建议:本文为有意参加电赛的学生提供了全面的信息和指导,读者应重点关注竞赛流程、参赛要求及评审标准等内容,以便更好地准备竞赛。
NLTK 是一个广泛使用的 Python 库,专注于自然语言处理(NLP)。它提供了许多工具和算法来处理文本数据,例如分词、词性标注、句法分析等。然而,这些功能通常需要依赖大量的语言数据(如语料库、词典、预训练模型等),这些数据被统称为 NLTK 数据资源 。 主要内容: a. 语料库(Corpora) 这些是用于训练和测试 NLP 模型的文本数据集合。 示例:gutenberg(古登堡计划的书籍)、brown(布朗语料库)、reuters(路透社新闻语料库)等。 b. 词典与词汇资源(Lexical Resources) 包括词频表、同义词词典(如 WordNet)、停用词列表等。 示例:wordnet(WordNet 同义词数据库)、stopwords(多语言停用词列表)。 c. 预训练模型(Pre-trained Models) 包含一些常用的 NLP 模型,例如分词器、词性标注器、命名实体识别器等。 示例:punkt(用于句子分割的预训练模型)、averaged_perceptron_tagger(词性标注器)。 d. 其他资源 包括一些辅助工具和配置文件,用于支持 NLTK 的各种功能。
内容概要:本文介绍了Python爬虫的基础知识,包括定义、优势、基本流程、常用库以及注意事项。爬虫是一种自动抓取网页信息的程序,Python因其简洁的语法、强大的库支持和跨平台特性成为爬虫开发的理想选择。文章详细讲解了爬虫的基本流程:发送请求、解析内容、存储数据和异常处理,并列举了requests、BeautifulSoup、Scrapy、lxml等常用库的功能。最后给出一个简单示例演示爬取网页标题的过程,同时强调了遵守robots.txt协议、设置合理请求间隔、处理反爬虫机制等注意事项。; 适合人群:对Python爬虫感兴趣的初学者或有一定编程基础的技术人员。; 使用场景及目标:①了解爬虫的工作原理和应用场景;②掌握Python爬虫的基本开发流程和常用库的使用方法;③能够编写简单的爬虫程序,为后续的数据分析、机器学习等任务提供数据支持。; 阅读建议:读者应结合实际案例进行练习,在理解理论的同时注重实践操作,确保能灵活运用所学知识。
内容概要:本文详细介绍了基于西门子PLC博途V17和WinCC 7.5sp2的一套高效工程模板。博途部分利用多重背景技术和梯形图+SCL混合编程,极大提升了编程效率和维护简便性。WinCC部分通过结构变量和面板实例,简化了人机界面的组态工作。此外,模板还包括丰富的功能库如PID控制、语音报警、报表生成功能等,显著增强了系统的实用性和用户体验。 适合人群:自动化领域的工程师和技术人员,尤其是初学者和有一定经验但仍需提高效率的从业者。 使用场景及目标:适用于工业自动化项目的快速开发与部署,旨在减少重复劳动,提高开发效率,缩短项目周期。通过使用该模板,工程师能够更快地上手并掌握先进的编程技巧和组态方法。 其他说明:文中提供了具体的代码示例和实际应用场景,有助于读者更好地理解和应用这些技术。同时提醒用户注意版权和使用权限的问题。
工作簿7777.xlsx
立式插秧机sw16可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
稳压罐sw16_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
内容概要:文章详细介绍了拦截器(Interceptor)的工作机制及其在HTTP请求响应全流程中的作用,包括在请求到达目标处理器之前、处理器处理请求之后以及视图渲染之前执行特定操作。拦截器的应用广泛,如日志记录、权限控制、性能监控、请求参数处理和身份验证与授权等。文中还提供了创建拦截器的方法,可以通过实现`HandlerInterceptor`接口或继承`HandlerInterceptorAdapter`类来创建,并且展示了如何配置拦截器,将其添加到配置中以拦截所有请求,还可以通过`@Order`注解配置拦截器的执行顺序。多个拦截器按照配置顺序依次执行其`preHandler`、`postHandler`和`afterCompletion`方法,确保请求处理流程的有序性和灵活性。 适合人群:具有一定Java Web开发经验,尤其是熟悉Spring框架的开发者。 使用场景及目标:①理解拦截器在Web应用中的工作原理;②掌握如何创建和配置拦截器以实现特定功能;③学习如何利用拦截器实现如日志记录、权限控制等功能,提升Web应用的安全性和性能。 阅读建议:在学习过程中,应结合实际项目需求,理解每个拦截器方法的作用,并尝试在自己的项目中实现相应的拦截器,以加深对其工作机制的理解。
内容概要:本文详细介绍了如何使用Matlab进行预测不确定性的仿真,重点讲解了置信区间的计算方法及其可视化。文章通过具体的代码示例展示了如何计算区间覆盖率(PICP)和区间平均宽度百分比,并提供了多种优化技巧,如使用norminv函数计算正态分布分位数、动态计算标准差以及分位数回归等。此外,还分享了一些常见的错误和改进建议,帮助新手快速掌握这一技能。 适合人群:初学者和有一定编程基础的Matlab用户,特别是那些希望深入了解预测不确定性和置信区间计算的人。 使用场景及目标:① 学习如何使用Matlab进行预测不确定性的仿真;② 掌握置信区间的计算方法及其可视化;③ 提高预测模型的可靠性和准确性。 其他说明:文中提供的代码可以直接应用于实际数据,只需替换示例数据即可。同时,文中还提到了一些高级技巧,如动态标准差计算和分位数回归,可以帮助用户进一步优化预测模型。
内容概要:本文旨在帮助电子信息、自动化、通信等专业学生更好地理解和完成电子硬件课后习题。文章首先指出电子硬件课程的难度,特别是课后习题部分。接着详细介绍了四个主要方面的解题技巧:一是正确理解电路图,强调在分析电路时要先明确电路特性再进行计算;二是利用等效变换简化电路,通过戴维南定理等方法将复杂电路转化为简单结构;三是总结常考题型,如RC、RL电路分析、放大电路分析等,并给出解题关键词;四是强调动手实践与理论思考相结合,鼓励使用仿真软件和实际搭建电路来增强理解。最后提出学习建议,包括多画图、分类练习、与同学交流等,以提高学习效率。 适合人群:电子信息、自动化、通信等相关专业的学生,尤其是正在学习电子硬件课程的学生。 使用场景及目标:①帮助学生克服电子硬件课程中遇到的困难,特别是课后习题部分;②提高学生对电路分析、等效变换等基本概念的理解和应用能力;③培养学生的动手能力和解决实际问题的能力。 阅读建议:本文提供了丰富的解题技巧和学习建议,读者应结合自身学习情况,边读边思考,并尝试将文中提到的方法应用于实际练习中,以达到更好的学习效果。
内容概要:本文探讨了车载刷写架构中 ECU 收到相同 blockSequenceCounter 数据包的情况,基于 ISO14229 标准,详细解释了 UDS 诊断服务(特别是 34、36 和 37 服务)在 ECU 刷写过程中的作用。文章重点分析了 TransferData 服务(SID 0x36)的实现逻辑,包括 blockSequenceCounter 的状态管理和重复数据包处理机制,以确保数据传输的鲁棒性和协议合规性。通过合理的状态管理和计数器递增逻辑,避免了数据覆盖或丢失,并提高了 ECU 存储寿命。 适合人群:具有汽车电子相关背景的研发工程师和技术人员,尤其是从事 ECU 诊断刷写工作的专业人士。 使用场景及目标:①理解 UDS 诊断服务在 ECU 刷写中的具体应用,特别是 34、36 和 37 服务的作用;②掌握 blockSequenceCounter 的状态管理和重复数据包处理机制,确保数据传输的可靠性;③确保 ECU 刷写过程符合 ISO 14229 标准,提高系统鲁棒性和资源效率。 其他说明:文章提供了详细的测试用例设计,帮助开发者验证 ECU 对重复包的处理是否符合预期。同时强调了在重复包场景中确保无冗余写入操作的重要性,尤其是在 Flash 存储中避免擦写寿命损耗。此外,还提到了超时处理和错误恢复机制,以应对实际应用中的各种情况。
c语言奔跑的火柴人游戏源码.zip