`

《Jakarta commons cookbook》学习笔记

    博客分类:
  • Book
阅读更多

关于Jakarta 摘抄维基百科:
引用
Jakarta是Apache组织下的一套Java解决方案的开源软件的名称,它包括了很多子项目。Tomcat、Ant、Struts等等現在是Apache下的开源项目,也曾是Jakarta的关联项目。
Jakarta的名称是想把与Jakarta关系非常深的爪哇岛关联起来。编程语言Java的命名源自这个岛的名字(印尼語:Jawa、英語:Java),而城市雅加达(Jakarta)正是这个岛上的第一大城市,也是印度尼西亚的首府。


Jakarta工具包可谓java开发中的必备神器, 熟悉里面各种工具类的用法, 可以让我们少重复发明一些轮子.它里面的一些commons包也成了很多开源项目的必备依赖. 比如spring, hibernate之流.

这本书讲到了Jakarta中几个比较重要的包的用法, 由于Jakarta中很多工具类的JavaDoc写的非常棒, 因此, 里面大部分工具类我们通过阅读其JavaDoc都应用的得心应手. 而这本书给我的最大体会, 就是发现了Jakarta中更多的宝贝, 而且熟悉了更多的用法. 缺点就是此书有点老了, 而Jakarta发展的太快, 书里面的很多内容在实际的工具包中都对不上号了

Commons Lang
ToStringBuilder, HashCodeBuilder, EqualsBuilder, CompareToBuilder这些东西做过java的几乎人人都知道了吧
介绍几个很少用的:

ArrayUtils.toString()
将数组用大括号括起来, 用逗号分隔输出.如果碰到null元素, 将输出unkown字符串. 如果是collection要输出, 可以先toArray()

ArrayUtils.contains()
检查数组中是否包含指定的元素, indexOf(), lastIndexOf()可以指定元素所在数组的下标

ArrayUtils.toMap()
将一个二维数组转换成一个map对象.

FastDateFormat
可以线程安全的实现对日期进行格式化.

DateUtils.round()
可以将日期时间舍入到最近的日期, 比如DateUtils.round(new Date(), Calendar.Month);将对当前日期中月后面的内容舍弃.DateUtils.SEMI_MONTH, 将日期舍入到一个月的中间和开头.

DateUtils.truncate()
则类似Math.floor()对指定域(如Calendar.MONTH)之后的内容进行截取处理.

Validate
用来对方法参数进行验证, 当遇到无效的参数时, 将抛出IllegalArgumentException异常

StopWatch
用来度量某段代码的执行耗时, 和现实中的秒表有一样的功能, 你可以启动, 停止, 展厅, 恢复计时, 重置以及拆分它. 其中split()/unsplit()方法类似于秒表中的分圈计时.

文本处理

StringUtils.abbreviate()
用于将指定的字符串进行缩减处理, 而且还可以从指定的位置开始缩减.
比如StringUtils.abbreviate("this is a test", 10) 得到的是"this is..."字符串

StringUtils.substringBetween()
返回被两个指定参数包围起来的字符串内容. 比如将<html>标签包围的内容返回, StringUtils.substringBetween(htmlString, "<html>", "</html>");

StirngUitls.strip()
可以将字符串中首尾含有指定的内容清除之
比如
StirngUtils.strip("-------****------ABCDE!-------*******-----------", "-*")
得到的是"ABCDE!"

StringUtils.chomp()
取出字符串末尾的回车换行符, 当然可以指定删除最后的那个字符

String stars = StringUtils.repeat("*", 40); 
String center = StringUtils.center("TEST", 40, "*"); 
String heading = StringUtils.join(new Object(){stars, center, stars}, "\n"); 

得到如下字符串
引用
*****************************
************TEST************
*****************************


StringUtils.countMatches()
返回一段文本在另一段字符串中出现的次数.

StringUtils.deference()
输出两个字符串之间的差别, indexOfDeference()指出两个字符串之间开始出现差别的位置, getLevenshteinDistance(), 指出从一个字符串转换到另一个字符串需要执行的插入, 删除和替换的次数.

JavaBean

PropertyUtils.getSimpleProperty()
通过属性名返回bean属性值

getNestedProperty()
返回嵌套属性值, 比如getNestedProperty(book, "name.firstName");

getIndexedProperty()
从数组或List型Bean属性中返回指定的下标元素, 比如getIndexedProperty(book, "chapters[1]");

getMappedProperty()
从指定map类型的bean属性中返回值, 比如getMappedProperty(apartment, "rooms(dining)");

getProperty()
可以返回任何属性, 比如 getProperty(country, "regions[0].cities(richmond).population");

BeanComparator

用来根据bean属性来排列和比较bean
比如:
Collections.sort(countryList, new BeanComparator("bean"))// 根据国家名称对国家列表进行排序

PropertyUtils.describe()
可创建一个包含bean实例中所有可读属性的map对象

BeanMap
可以将一个bean封装成一个通过Map接口来对bean属性进行访问.

DynaBean
用来在运行时动态创建一个bean.
DynaProperty[] props = new DynaProperty[] { 
new DynaProperty("name", String.class), 
}; 
BasicDynaClass clazz = new BasicDynaClass("book", BasicDynaClass.class, props); 
DynaBean bean = clazz.newInstance(); 
bean.set("name", "macro"); 


BeanUtils
以字符串的形式读取和设置bean属性.

函数对象
用来提供更高级的代码重用性和更简洁的设计, 它用来将功能逻辑从面向特性数据结构的算法中抽象并提取出来.
我们最常用的就是Comparator和Iterator.

ReverseComparator
用来将Comparator的功能反转, 比如顺序改成倒序

ComparatorChain
会把连接中的每一个Comparator进行比较, 如果当前Comparator返回值为0, 则调用下一个, 直到连接中没有其他的Comparator.

NullComparator
对null元素进行排序, 还可以控制null出现在排序的开始还是结尾, 一般NullComparator用来对其他的Comparator进行装饰.

当数组和Collection含有预定顺序关系时, 可使用FixedOrderComparator进行排序, 这种顺序关系包括一周里面星期几的顺序, 太阳系中行星的顺序, 光谱中的颜色顺序.
String[] medalOrder = new String[] {"tin", "bronze", "siliver", "gold"}; 
Comparator medalComparator = new FixedOrderComparator(medalOrder); 
Comparator beanComparator = new BeanComparator("medal", medalComparator); 
beanComparator.compare(medal1, medal2); 


Predicates
使用Predicate用来评估某个判别式或者条件, Predicate是一种可判别其他对象并返回true或false的对象. 整个Commons Collection都用它来进行筛选, 选择以及验证工作.可以将其理解为对if条件的一种封装, 该接口的唯一方法evaluate()返回true和false.

UniquePredicate
当对象首次被evaluate时返回true, 该predicate内部维护了一个evaluate对象的HashSet对象, 如果对象已经存在其中, 将返回false. 用来从collection中不重复的获取对象.

Predicate可以用于任何场合, 比如验证用户输入, 筛选collection内容或者用于替换负责的逻辑条件

Transformer
用来将一个对象为参数, 返回一个经过转换处理后的新的对象

ChainedTransformer
用来将多个Transformer连接起来.

SwitchTransformer
实施一个依赖于某Predicate的Transformer. 他能对一个switch进行建模, 并接受三个参数, 一个Predicate数组, 一个Transformer数组, 一个默认的Transformer.两个数组是一一对应的关系, 如果Predicate都不满足则执行默认的Transformer.

Closure
用来将对某个对象的一段代码进行封装. 比如对某件商品进行打折处理, 可以将打折处理过程封装成一个Closure.

ChainedClosure
用来将多个Closure进行链接, 与Transformer不同在于, 每个Transformer处理完之后的结果传给下一个Transformer, 而Closure链传递的是同一个对象. 好像轿车通过工厂的流水线一样.

IfClosure
提供一个Predicate和两个Closure, 如果Predicate判定为true, 执行第一个Closure, 否则执行第二个.

WhileClosure
用来模拟循环处理, 它需要传递一个Predicate和一个Closure, 如果条件为true, 那么不断执行Closure, 知道条件为false为止.

ForClosure用来执行指定次数的Closure.

Collection

LoopIterator
用来重复的便利Collection, 该遍历将永不停止, 因为其HasNext()返回值永远是true, 当用while进行遍历的时候,不要忘记添加退出条件.
对于需要不停的判断一系列取值或者反复执行一组命令时, 使用LoopingIterator就非常合适. 同时它还实现了ResettableIterator接口, 在执行的过程中, 通过执行reset()方法可以跳回到Collection的起始位置.
从只有三项的List中循环取出5项
LoopingIterator itor = new LoopingIterator(list); 
for(int i = 0; i < 5; i++) { 
String element = (String)itor.next(); 
} 


ArrayListIterator
用来遍历ArrayList中指定的部分内容.通过nextIndex()可以获取某个元素的下标.

FilterIterator
包含了一个Predicate, 如果Predicate为true则该元素将包含在迭代器中. 从来达到遍历某个Collection中合乎特定条件的元素, 或者删除不符合条件的元素.它实际上对指定Iterator的一个装饰而已.

Collections.filter()
方法用来将不符合条件的元素从Collection中移除, 因此具有破坏性.如果不想破坏原有的Collection, 可以使用CollectionUtils.select()和

CollectionsUtils.selectRejected()
创建一个含有所有符合或者不符合条件元素的新的Collection.

UniqueFilterIterator
可以在遍历Collection时跳过重复元素.

Bag
容器用来对同一个对象存储多次, 并跟踪对象有多少份拷贝.比如某个Bag包含20份A对象的拷贝, 50份B对象的拷贝. Bag有两种, 使用HashMap的HashBag, 具有更高的性能, 还有一种是TreeBag, 它需要维护对象元素加入的顺序.将以加入的顺序返回它们.

Buffer
分为两种:UnboundedFifoBuffer 无大小限制, BoundFifoBuffer 有大小限制.该容器类似JDK中的Queue, queue中的offer和peek功能与add和remove方法具有相同的功能, 唯一的区别是想Queue中添加数据遇到问题时会抛异常.
还有一种具有优先级的Buffer:PriorityBuffer, 对象会根据Comparator生成的优先级来决定是否被移除. 移除对象的逻辑类似于医院的急诊室工作流程.病情严重的病人将得到优先治疗的权利.这个与PriorityQueue.
BlockingBuffer为阻塞式Buffer.如果系统需要在某段数据就绪时进行处理的话, 就应该使用这种Buffer. 或者系统中有多个进行同时侦听流水线主键缓冲区时, 该数据结构也很管用.JDK5中也有与之对应的BlockingQueue.

MultiMap
用于给指定的键维护一组值. 当需要一个对象关联多个对象的时候, 使用MultiMap是个好主意.

BidMap
是这样一种Map实现:当键值都唯一的时候, 可以根据值来查对应的键
DualHashBidMap 把键和值存在两个HashMap中, 其中一个存key-value, 一个存value-key

CaseInsensitiveMap
key为大小写不敏感String类型的map

PredicateMap
增加了验证功能的map, 在put一个entry的时候, 如果验证显示为false的话, 将抛出IllegalArgumentException异常.

CollectionUtils.transform()
该方法接收两个参数, 用来通过Transformer, 将制定的Collection进行转换, 得到一个新的经过转换后的Collection

LRUMap
一种固定尺寸的Map, 当达到最大容量时会借助最近最少使用算法社区相应的项.

LazyMap
当根据某个键检索某个值的时候, 将通过指定Transformer, 创建该值.
		Transformer t = new Transformer() {

			public Object transform(Object arg0) {
				return StringUtils.reverse((String) arg0);
			}
		};

		Map names = new HashMap();

		Map lazyMap = LazyMap.decorate(names, t);

		Object value = lazyMap.get("MacroChen");
		System.out.println(value);

LazyMap的另一个应用场景是通过给定的值从数据库中检索相应的记录.用LazyMap将LRUMap进行包装是一个不错的注意.

CollectionUtils.countMatches(), cardinality()
用来统计某个对象出现的次数, countMatches()根据Predicate从指定的Collection中返回满足条件的元素数目. 而后者从collection中返回指定对象的数目.

CollectionUtils.union(), intersection(), disjunction(), subtract()
分别对两个集合进行并集, 交集, 联集和差集.

PropertiesConfiguration
对Properties的适度增强, 能直接将对应的value转换成相应的类型, 比如以逗号分割的字符串转换成List, 数字字面值转换成数字值.而不是字符串.

Commons Logging
能在运行时, 通过检测, 能调用相应的日志框架. 比如jdk自带的日志框架和Log4J等.
比如默认情况下, 下面的代码:
public class LoggingTest {
	static Log log = LogFactory.getLog("mylog.LogginTest");
	public static void main(String[] args) {
		log.info(log);
	}
}

将返回
引用
信息: org.apache.commons.logging.impl.Jdk14Logger@83cc67

当LogFactory.getInstance()被调用的时候, CommonLogging将通过检测一些系统属性和类路径中库的情况来定位和管理合适的日志框架.
所以如果将log4j加入到类路径之后输出将变成这样:
引用
log4j:WARN Please initialize the log4j system properly.

如果配置了log4j.properties, 那么输出结果可能变成:
引用
DEBUG (LoggingTest.java:14) org.apache.commons.logging.impl.Log4JLogger@758fc9


要显示的将logging设置为使用log4j来做日志输出, 可以通过下面的设置满足要求
System.setProperty("org.apache.commons.logging.Log", "org.apache.commcons.logging.impl.Log4JLogger");


Commons IO

CopyUtils
用来将某个InputStream, Reader, byte[]的内容copy到OutputStream或者Writer.

IOUtils.toString()
用来将信息从Reader或者InputStream中copy到字符串中.

IOUtils.closeQuietly()
用来只有的关闭某个InputStream, OutputStream, Reader或Writer, 而不用担心null或者IOException, 这个一般放在finally中执行.

FileUtils.byteCountToDisplaySize()
以KB, MB, GB的形式显示某个文件大小, 该工具类有三个静态变量, ONE_KB, ONE_GB, ONE_MB, 不用大家应该也知道了.另外他不会对文件大小进行四舍五入操作, 比如一个2.9MB的文件, 得到是2MB, 也就是说余数被统统舍弃了.

FileUtils.copyFile(), copyFileToDirectory(), writeStringToFile()
分别是拷贝文件, 拷贝文件到指定的文件夹, 拷贝字符串内容到文件.

FileUtils.deleteDirectory(), cleanDirectory(), sizeOfDirectory()
递归删除目录和清空目录下的所有文件, 获取指定目录下所有内容的总大小.

FileUtils.touch()
类似unix下的touch命令, 如果文件不存在将创建一个新的文件.如果文件存在, 则更新文件的时间戳为当前时间.

IOFileFilter
关于文件的过滤, 包括FileFilter, FilenameFilter, PrefixFileFilter, SuffixFileFilter, DirectoryFileFilter, 以及AndFileFilter等逻辑过滤器.

CountingInputStream和CountingOutputStream
用来跟踪进入某个Stream的byte数量.它可以视为是各种Stream的一种装饰器类

TeeOutputStream
用来将相同的数据发送到两个OutputStream.





分享到:
评论
2 楼 cectsky 2011-04-08  
commons
nisen 写道
,我是这本书的审校,commons还有更多的好玩的东东,而且现在不叫jakarta commons 了而是commons了,并且成了apache的顶层项目。

BeanUtils,Lang,Collections,logging 应该是commons中最核心的组件。我这里有一个分类

Core:BeanUtils,Lang,Collections,logging
Db:DbUtils,DBCP,Pool
IO: IO,
XML vs Bean:betwixt,Digester,JXPath,Jelly
模版:EL, JEXL
通用:Codec,Id
Web:FileUpload,httpClient
文件系统:VFS

其他的可以暂时不考虑,当然有一些已经过时的,比如Attributes,跟jdk1.5中的注解差不多,不在使用了,比如Lang中的枚举


请问,现在有得卖吗??
1 楼 nisen 2009-12-08  
,我是这本书的审校,commons还有更多的好玩的东东,而且现在不叫jakarta commons 了而是commons了,并且成了apache的顶层项目。

BeanUtils,Lang,Collections,logging 应该是commons中最核心的组件。我这里有一个分类

Core:BeanUtils,Lang,Collections,logging
Db:DbUtils,DBCP,Pool
IO: IO,
XML vs Bean:betwixt,Digester,JXPath,Jelly
模版:EL, JEXL
通用:Codec,Id
Web:FileUpload,httpClient
文件系统:VFS

其他的可以暂时不考虑,当然有一些已经过时的,比如Attributes,跟jdk1.5中的注解差不多,不在使用了,比如Lang中的枚举

相关推荐

    Jakarta Commons CookBook学习笔记

    ### Jakarta Commons CookBook 学习笔记 #### 一、Commons Lang: EqualsBuilder and HashCodeBuilder **1.1 概述** `EqualsBuilder` 和 `HashCodeBuilder` 是 Apache Commons Lang 包中提供的两个工具类,用于...

    Jakarta Commons cookbook.chm与中文版的笔记

    在阅读《Jakarta Commons Cookbook》时,你可以学习如何有效地利用这些组件来提升你的Java项目。例如,了解如何使用` FileUtils.copyFile()`方法复制文件,或通过` StringUtils.join()`将数组元素连接成字符串。此外...

    安川MP7系列工控系统源码解析:关键算法与硬件交互揭秘

    内容概要:本文深入剖析了安川MP7系列工业控制系统的关键源码,重点介绍了运动轨迹规划、通信协议处理以及故障处理机制等方面的技术细节。通过对实际代码片段的解读,揭示了该系统在硬件寄存器直接访问、特殊功能码处理等方面的独特之处。同时,文中还分享了一些基于实践经验得出的重要参数设置及其背后的故事,如特定摩擦补偿系数的选择原因等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对安川产品有一定了解并希望深入了解其内部工作机制的专业人士。 使用场景及目标:帮助读者掌握安川MP7系列控制器的工作原理,提高对类似系统的维护能力和故障排查效率。对于想要进一步研究或二次开发该系统的开发者来说,也能提供宝贵的参考资料。 其他说明:文章不仅限于理论讲解,还包括了许多来自一线的实际案例和经验教训,使读者能够更好地理解和应用所学知识。

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_.zip

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    风储直流微电网母线电压控制策略与双闭环MPPT技术研究

    内容概要:本文详细探讨了风储直流微电网中母线电压控制的关键技术。首先介绍了风储直流微电网的背景和发展现状,强调了母线电压控制的重要性。接着阐述了永磁风机储能并网技术,解释了永磁风机如何通过直接驱动发电机将风能转化为电能,并确保与电网的同步性和稳定性。然后深入讨论了双闭环控制MPPT技术,这是一种通过内外两个闭环控制系统来实现实时调整发电机运行参数的技术,确保风机始终处于最大功率点附近。最后,文章探讨了储能控制母线电压平衡的方法,即通过储能系统的充放电操作来维持母线电压的稳定。结论部分指出,通过这些技术的有机结合,可以实现对风储直流微电网的有效管理和优化控制。 适合人群:从事新能源技术研发的专业人士、电气工程研究人员、风电系统工程师。 使用场景及目标:适用于希望深入了解风储直流微电网母线电压控制策略的研究人员和技术人员,旨在帮助他们掌握最新的控制技术和方法,以提高系统的稳定性和效率。 其他说明:文章还对未来风储直流微电网的发展进行了展望,指出了智能化和自动化的趋势,以及储能技术的进步对系统性能的影响。

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    【操作系统开发】HarmonyOS目录结构详解:构建高效开发环境与跨设备协同应用

    内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。

    飞轮储能充放电控制Simulink仿真模型:基于永磁同步电机的矢量控制与dq轴解耦

    内容概要:本文详细介绍了飞轮储能充放电控制的Simulink仿真模型,重点在于采用永磁同步电机的矢量控制和dq轴解耦控制策略。充电时,外环控制转速,内环控制dq轴电流;放电时,外环控制直流母线电压,内环同样控制dq轴电流。文中还讨论了硬件与软件环境的选择,以及仿真模型的调试与运行情况,最终得出该模型具有良好的跟随性能和波形完美度。 适用人群:从事电力电子系统、储能技术和Simulink仿真的研究人员和技术人员。 使用场景及目标:适用于需要对飞轮储能系统进行深入研究和仿真的场合,旨在提高充放电效率和稳定性,满足不同应用场景的需求。 其他说明:该仿真模型已调试完成,可以直接用于进一步的研究和实际应用,为未来的飞轮储能技术研发提供了有价值的参考。

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    1_15套python PDF格式.zip

    1_15套python PDF格式.zip

    三相三电平整流器仿真:基于电压电流双闭环控制与SPWM调制的性能分析

    内容概要:本文详细介绍了三相三电平整流器的仿真过程及其性能分析。文中首先概述了三相三电平整流器的基本概念及其在电力系统中的重要作用,接着重点探讨了电压电流双闭环控制方式的工作原理和优势,以及SPWM调制技术的具体应用。通过仿真文件展示了整流器在不同条件下的响应情况,验证了这两种技术的有效性和优越性。最后,作者表达了对未来实际应用的期望。 适合人群:从事电力电子研究的技术人员、高校相关专业师生、对电力控制系统感兴趣的工程爱好者。 使用场景及目标:适用于希望深入了解三相三电平整流器工作原理和技术细节的研究人员;目标是在理论基础上掌握电压电流双闭环控制和SPWM调制的实际应用方法。 其他说明:本文提供的仅为仿真文件,未涉及实物实验数据。

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    Arduino UART实验例程【正点原子EPS32S3】

    Arduino UART实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

Global site tag (gtag.js) - Google Analytics