作????者 | 朱福喜 | 出版社 | 第1版 (2005年10月1日) |
---|---|---|---|
出版時間 | 2005年10月 | 頁????數(shù) | 314 頁 |
定????價 | 38.0 | 裝????幀 | 平裝 |
ISBN | 9787121016141 |
內(nèi)容介紹
既保證有一定的實用性,同時也要確保一定的廣度和深度。在應用這些技術的同時,還涉及到Access、MySQL等數(shù)據(jù)庫系統(tǒng)、Tomcat應用服務器,以及Intemet的相關技術。
2100433B
秸稈煤炭成型機是指以農(nóng)村的玉米秸稈、小麥秸稈、棉花桿、稻草、稻殼、花生殼、玉米芯、樹枝、樹葉、鋸末等農(nóng)作物、固體廢棄物為原料,經(jīng)過粉碎后加壓、增密成型的秸稈炭的全套機械化生產(chǎn)設備。秸稈煤炭成型機性能好...
根據(jù)相關法律規(guī)定,這設計費都是有公式計算的,你可以上網(wǎng)查一下或咨詢相關人員。 工程勘察設計收費管理規(guī)定 計價格[2002]10號? ?第一條?為了規(guī)范工程勘察設計收費行為,維護發(fā)包人和勘察人、設計人的...
為了更好地定制廈門地標,世茂攜手的設計單位是中國第一高樓、上海中心的建筑設計團隊——— GENSLER事務所美國。他們把兩幢250米 的高樓設計成美麗的“風帆”,融入了廈門市花“三角梅”的視覺元素,想...
格式:pdf
大?。?span id="9jeb4s1" class="single-tag-height">101KB
頁數(shù): 未知
評分: 4.5
\"男裝項目設計開發(fā)\"是一門綜合性實踐課程,它強調(diào)知識、能力、素質(zhì)之間的相互轉(zhuǎn)化,突出藝工結(jié)合的專業(yè)特點,開設這門課程的目的是促進學生設計、工程技術等綜合實踐能力的提高。通過優(yōu)化教學內(nèi)容、實施多樣化的教學方法以及改革考核評價體系,對\"男裝項目設計開發(fā)\"課的教學進行有益的探索與實踐。
格式:pdf
大?。?span id="jrkk4n1" class="single-tag-height">101KB
頁數(shù): 2頁
評分: 4.5
我國房地產(chǎn)開發(fā)建設項目設計過程一般可分為兩個大階段:方案設計階段和施工圖設計階段。這兩個階段的成果必須報政府部門審批通過,方可進行工程項目施工??梢哉J為建設項目設計過程的項目管理是圍繞著這兩個最終成果而展開的。由于這兩個設計階段所承擔的目標和任務的不同,其項目設計管理在執(zhí)行組織的結(jié)構(gòu)、項目不同形式的管理及質(zhì)量管理等方面存在著較大差異。對于房地產(chǎn)開發(fā)實施階段的變更管理,設計變更是由兩方面因素造成的:一方面是由設計團隊整體的水平、能力、素質(zhì)決定的,所以選擇設計團隊是控制設計變更最有效的方法之一;另一方面是房地產(chǎn)公司管理團隊的水平、能力、素質(zhì)決定的,如公司相關管理部門編制的策劃書、設計委托書科學、準確,具有一定的前瞻性,那么就能非常好的控制設計變更的數(shù)量,從而達到控制工期和造價。
JavaWeb應用開發(fā)框架實例
一、 概述
Web 應用架構(gòu)可以劃分為兩大子系統(tǒng):前端子系統(tǒng)和后臺子系統(tǒng)。
前端子系統(tǒng):
1. 基礎技術: Html/Java/CSS / Flash
2. 開發(fā)框架: jQuery, Extjs , Flex 等;
后臺子系統(tǒng):
1. 基礎技術: Java Servlet;
2. 開發(fā)框架: Struts, Spring, Hibernate, ibatis 等;
3. 應用服務器: Tomcat / Jetty
編程模型: B/S 模型。 客戶端向服務器端發(fā)送請求, 服務器經(jīng)過處理后返回響應, 然后客戶端根據(jù)響應及需求繪制前端展現(xiàn)。
在用戶客戶端和實際提供功能的Web 服務器之間還可能存在著代理服務器, 負載均衡服務器, 不過那些屬于錦上添花的事物,暫時不在考慮范圍內(nèi)。
客戶端應用理念: 客戶端承擔大量的交互邏輯及渲染工作,服務器端主要是處理請求和返回數(shù)據(jù)。
前后端系統(tǒng)耦合: 客戶端和服務器端各自處理自己內(nèi)部的子系統(tǒng)耦合;而客戶端與服務器端的耦合簡化為一個通信與數(shù)據(jù)通道。該通道用來傳輸通信請求和返回數(shù)據(jù)。
請求通信: 采用 Http / Tcp 協(xié)議
數(shù)據(jù)通道: 采用 Json, xml , 文本字符串,字節(jié)。 內(nèi)部系統(tǒng)一般采用 Json 作為數(shù)據(jù)交換格式;系統(tǒng)間的互操作則采用XML 來規(guī)范;文本字符串是最一般的形式, 字節(jié)是最底層的形式。
JavaWeb應用開發(fā)框架實例
二、 架構(gòu)演變
最輕的架構(gòu): jQuery + Servlet + ajax 在客戶端使用 jQuery發(fā)送 ajax 請求給Java 服務端的 Servlet 進行處理, Servlet 僅僅返回數(shù)據(jù)給客戶端進行渲染。
該架構(gòu)有效地分離了前端展示和后臺請求處理,同時又保持了最輕的復雜性, 只需要學會編寫 Servlet 及使用 jQuery , 就能構(gòu)建簡單的應用。
如果只是做個人創(chuàng)意演示, 可以采用該架構(gòu), 快速實現(xiàn)自己的創(chuàng)意功能。 Servlet 是Java web 應用的基礎技術,jQuery 則是前端開發(fā)的簡單易用的利器。
后臺架構(gòu)演變:
1. 邏輯與頁面的分離: JSP/Servlet
JSP 實現(xiàn)了頁面邏輯與外觀的分離,但是, 前端子系統(tǒng)與后臺子系統(tǒng)仍然是緊密耦合的; 前端設計人員實際上只需要服務端返回的數(shù)據(jù), 就可設計出非常專業(yè)的界面顯示。
2. MVC 架構(gòu):Struts2(含Servlet,MVC) + JDBC
用Servlet 來添加服務器功能是基本的選擇,但在web.xml中配置大量的 Servlet 卻不是最佳的選擇。
Struts2 在服務端實現(xiàn)了更豐富的MVC 模式, 將本來由應用決定的控制器從web容器中分離。
3. SSH 架構(gòu): Struts2(含Servlet, MVC) + Spring (Ioc) + Hibernate (ORM,對象-關系映射)
通常, 應用系統(tǒng)中需要預先創(chuàng)建一些單例對象, 比如 Controller, Service, Dao, 線程池等, 可以引入 Spring Ioc 來有效地創(chuàng)建、管理和推送這些對象;使用 Hibernate 來實現(xiàn)關系數(shù)據(jù)庫的行與面向?qū)ο蟮膶傩灾g的映射與聯(lián)接,以更好地簡化和管理應用系統(tǒng)的數(shù)據(jù)庫操作。SSH 可以說是 JavaWeb應用系統(tǒng)開發(fā)的三劍客。
4. SI 架構(gòu): SpringMVC(含Servlet, Ioc, MVC, Rest) + iBatis (Semi-ORM)
過于復雜的架構(gòu)會將人搞暈。因此,在適應需求的情況下, 盡量選擇簡單的架構(gòu),是明智之選。 這種架構(gòu)使用面向資源的理念,著重使用Spring作為MVC及應用基礎服務設施, 同時使用 iBatis 來實現(xiàn)更簡單靈活的ORM映射, 使之在可以理解和維護的范圍內(nèi)。
前端架構(gòu):
1. Flash 架構(gòu): Flex + jQuery + JSP
這是一種比較傳統(tǒng)的前端架構(gòu),采用同步模式, Flex 承擔大量的頁面渲染工作, 并采用AMF協(xié)議與Java端進行通信, 而JSP 則可以用于更快速的頁面顯示。優(yōu)點是: 經(jīng)過考驗的結(jié)構(gòu), 通常是值得信賴的; 缺點是, 由于采用同步模式, 在交互效果上可能不夠流暢, 需要進行比較耗時的編譯過程;此外, Flex 基于瀏覽器插件運行,在調(diào)試方面有些麻煩。
2. MVC 架構(gòu): Extjs + jQuery
這是一種比較現(xiàn)代的前端架構(gòu), 采用異步模式, Extjs4 可以實現(xiàn)前端子系統(tǒng)的MVC 分離, 對于可維護性是非常不錯的支持;此外, jQuery 可以作為有效的補充。
優(yōu)點: 異步, 快速, 對于企業(yè)內(nèi)部的后臺管理系統(tǒng)是非常好的選擇。
缺點: Extjs4 的可定制性、可適應性可能難以適應各種特殊的需求,需要用其它組件來補充, 比如大數(shù)據(jù)量的繪制。對于互聯(lián)網(wǎng)應用, 速度可能是致命傷。
三、 架構(gòu)的選擇
不要去詢問哪種架構(gòu)更好,更需要做的是清晰地定位項目目標,根據(jù)自己的具體情況來選擇和定制架構(gòu)。反復地嘗試、觀察和改進,反復磨煉技藝,這樣才有助于設計水平的提升。
架構(gòu)的選擇通常有四種關注點:
1. 適用性: 是否適合你的項目需求。 架構(gòu)有大有小, 小項目用小架構(gòu), 大項目用大架構(gòu)。
2. 可擴展性: 該架構(gòu)在需要添加新功能時,是否能夠以常量的成本添加到現(xiàn)有系統(tǒng)中, 所做的改動在多大程度上會影響現(xiàn)有功能的實現(xiàn)(基本不影響,還是要大面積波及)。
3. 便利性: 使用該架構(gòu)是否易于開發(fā)功能和擴展功能, 學習、開發(fā)和測試成本有多大。
4. 復雜性: 使用該架構(gòu)后,維護起來的成本有多大。你自然希望能夠?qū)懸粭l語句做很多事,使用各種成熟的組件是正確的方式,同時,在項目中混雜各種組件,也會提升理解和維護系統(tǒng)的復雜度。便利性和復雜性需要達到較好的平衡。
特殊的關注點:
譬如,應用需要支持高并發(fā)的情況, 需要建立一個底層的并發(fā)基礎設施, 并向上層提供簡單易用的接口,屏蔽其復雜性。
四、 架構(gòu)演進的基本手段
架構(gòu)并不是一成不變的, 在做出最初的架構(gòu)之后,隨著開發(fā)的具體情況和需求的變更, 需要對最初架構(gòu)做出變更和改進。
架構(gòu)演進的基本手段:
一致性, 隔離與統(tǒng)一管理, 螺旋式重構(gòu)改進, 消除重復, 借鑒現(xiàn)有方案。
1. 一致性: 確保使用統(tǒng)一模式來處理相同或相似的功能; 解決一次, 使用多次。
2. 模塊化、隔離與統(tǒng)一管理: 對于整體的應用, 分而治之,將其劃分為隔離性良好的模塊,提供必要的通信耦合;對于特定的功能模塊, 采用隔離手段,將其隔離在局部統(tǒng)一管理,避免分散在系統(tǒng)的各處。
3. 不斷重構(gòu)改進, 一旦發(fā)現(xiàn)更好的方式, 馬上替換掉原有方式。
4. 盡可能重用,消除重復。
5. 盡可能先借鑒系統(tǒng)中已有方案并復用之;如果有更好方案可替換之;
有一條設計準則是: 預先設計, 但不要過早設計。
意思是說, 需要對需求清楚的部分進行仔細的設計, 但是對于未知不清楚的需求,要堅持去理解它,但不要過早地去做出“預測性設計”;設計必須是明確的、清晰的、有效的, 不能針對含糊的東西來設計??梢栽诤笃谕ㄟ^架構(gòu)演進來獲得對后續(xù)需求的適應能力。
編譯:伯樂在線 - 范琦琦
死鎖是兩個甚至多個線程被永久阻塞時的一種運行局面,這種局面的生成伴隨著至少兩個線程和兩個或者多個資源。在這里我已寫好一個簡單的程序,它將會引起死鎖方案然后我們就會明白如何分析它。
Java死鎖范例
ThreadDeadlock.java
package com.journaldev.threads;
public class ThreadDeadlock {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
t1.start();
Thread.sleep(5000);
t2.start();
Thread.sleep(5000);
t3.start();
}
}
class SyncThread implements Runnable{
private Object obj1;
private Object obj2;
public SyncThread(Object o1, Object o2){
this.obj1=o1;
this.obj2=o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on "+obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on "+obj1);
work();
System.out.println(name + " acquiring lock on "+obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on "+obj2);
work();
}
System.out.println(name + " released lock on "+obj2);
}
System.out.println(name + " released lock on "+obj1);
System.out.println(name + " finished execution.");
}
private void work() {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上面的程序中同步線程正完成Runnable的接口,它工作的是兩個對象,這兩個對象向?qū)Ψ綄で笏梨i而且都在使用同步阻塞。
在主函數(shù)中,我使用了三個為同步線程運行的線程,而且在其中每個線程中都有一個可共享的資源。
這些線程以向第一個對象獲取封鎖這種方式運行。但是當它試著像第二個對象獲取封鎖時,它就會進入等待狀態(tài),因為它已經(jīng)被另一個線程封鎖住了。這樣,在線程引起死鎖的過程中,就形成了一個依賴于資源的循環(huán)。
當我執(zhí)行上面的程序時,就產(chǎn)生了輸出,但是程序卻因為死鎖無法停止。
t1 acquiring lock on java.lang.Object@6d9dd520
t1 acquired lock on java.lang.Object@6d9dd520
t2 acquiring lock on java.lang.Object@22aed3a5
t2 acquired lock on java.lang.Object@22aed3a5
t3 acquiring lock on java.lang.Object@218c2661
t3 acquired lock on java.lang.Object@218c2661
t1 acquiring lock on java.lang.Object@22aed3a5
t2 acquiring lock on java.lang.Object@218c2661
t3 acquiring lock on java.lang.Object@6d9dd520
在此我們可以清楚地在輸出結(jié)果中辨認出死鎖局面,但是在我們實際生活所用的應用中,發(fā)現(xiàn)死鎖并將它排除是非常難的。
分析死鎖
為了分析一個死鎖,我們需要關注下應用中的Java線程轉(zhuǎn)存,在上一節(jié)中我已經(jīng)解釋了如何使用VisualVM收集資料或者jstack應用程序產(chǎn)生線程轉(zhuǎn)存。
以下就是上述程序的線程轉(zhuǎn)存。
2012-12-27 19:08:34
Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.5-b02 mixed mode):
"Attach Listener" daemon prio=5 tid=0x00007fb0a2814000 nid=0x4007 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" prio=5 tid=0x00007fb0a2801000 nid=0x1703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"t3" prio=5 tid=0x00007fb0a204b000 nid=0x4d07 waiting for monitor entry [0x000000015d971000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f658> (a java.lang.Object)
- locked <0x000000013df2f678> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t2" prio=5 tid=0x00007fb0a1073000 nid=0x4207 waiting for monitor entry [0x000000015d209000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f678> (a java.lang.Object)
- locked <0x000000013df2f668> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t1" prio=5 tid=0x00007fb0a1072000 nid=0x5503 waiting for monitor entry [0x000000015d86e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f668> (a java.lang.Object)
- locked <0x000000013df2f658> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"Service Thread" daemon prio=5 tid=0x00007fb0a1038000 nid=0x5303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fb0a1037000 nid=0x5203 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fb0a1016000 nid=0x5103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fb0a4003000 nid=0x5003 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fb0a4800000 nid=0x3f03 in Object.wait() [0x000000015d0c0000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x000000013de75798> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
"Reference Handler" daemon prio=5 tid=0x00007fb0a4002000 nid=0x3e03 in Object.wait() [0x000000015cfbd000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000013de75320> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x000000013de75320> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00007fb0a2049800 nid=0x3d03 runnable
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fb0a300d800 nid=0x3503 runnable
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fb0a2001800 nid=0x3603 runnable
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fb0a2003800 nid=0x3703 runnable
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fb0a2004000 nid=0x3803 runnable
"GC task thread#4 (ParallelGC)" prio=5 tid=0x00007fb0a2005000 nid=0x3903 runnable
"GC task thread#5 (ParallelGC)" prio=5 tid=0x00007fb0a2005800 nid=0x3a03 runnable
"GC task thread#6 (ParallelGC)" prio=5 tid=0x00007fb0a2006000 nid=0x3b03 runnable
"GC task thread#7 (ParallelGC)" prio=5 tid=0x00007fb0a2006800 nid=0x3c03 runnable
"VM Periodic Task Thread" prio=5 tid=0x00007fb0a1015000 nid=0x5403 waiting on condition
JNI global references: 114
Found one Java-level deadlock:
=============================
"t3":
waiting to lock monitor 0x00007fb0a1074b08 (object 0x000000013df2f658, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x00007fb0a1010f08 (object 0x000000013df2f668, a java.lang.Object),
which is held by "t2"
"t2":
waiting to lock monitor 0x00007fb0a1012360 (object 0x000000013df2f678, a java.lang.Object),
which is held by "t3"
Java stack information for the threads listed above:
===================================================
"t3":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f658> (a java.lang.Object)
- locked <0x000000013df2f678> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t1":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f668> (a java.lang.Object)
- locked <0x000000013df2f658> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
"t2":
at com.journaldev.threads.SyncThread.run(ThreadDeadlock.java:41)
- waiting to lock <0x000000013df2f678> (a java.lang.Object)
- locked <0x000000013df2f668> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:722)
Found 1 deadlock.
這三個線程轉(zhuǎn)存的輸出清楚地說明了死鎖環(huán)境和線程,以及包含死鎖環(huán)境的資源。
為了分析死鎖,我們需要關注死鎖狀態(tài)的線程,然后資源再等待去封鎖,每一個資源都有一個獨特的ID,有了這個ID我們就能發(fā)現(xiàn)是哪一個進程已經(jīng)封鎖住對象。舉個例子,線程“t3”正在等待封鎖0x000000013df2f658,但是它已經(jīng)被線程“t1”封鎖住了。
當我們分析死鎖環(huán)境的時候,如果發(fā)現(xiàn)線程正在引起死鎖,這是我們就要改變代碼來避免死鎖的產(chǎn)生。
避免死鎖
有很多方針可供我們使用來避免死鎖的局面。
避免嵌套封鎖:這是死鎖最主要的原因的,如果你已經(jīng)有一個資源了就要避免封鎖另一個資源。如果你運行時只有一個對象封鎖,那是幾乎不可能出現(xiàn)一個死鎖局面的。例如,這里是另一個運行中沒有嵌套封鎖的run()方法,而且程序運行沒有死鎖局面,運行得很成功。
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1);
work();
}
System.out.println(name + " released lock on " + obj1);
System.out.println(name + " acquiring lock on " + obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2);
work();
}
System.out.println(name + " released lock on " + obj2);
System.out.println(name + " finished execution.");
}
只對有請求的進行封鎖:你應當只想你要運行的資源獲取封鎖,比如在上述程序中我在封鎖的完全的對象資源。但是如果我們只對它所屬領域中的一個感興趣,那我們應當封鎖住那個特殊的領域而并非完全的對象。
避免無限期的等待:如果兩個線程正在等待對象結(jié)束,無限期的使用線程加入,如果你的線程必須要等待另一個線程的結(jié)束,若是等待進程的結(jié)束加入最好準備最長時間。
看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人
關注「ImportNew」,提升Java技能
《單片機C51項目設計與開發(fā)》以實用案例為導向,通過19個典型任務,基于工作過程的學習思路,主要介紹單片機開發(fā)工具軟件(Keil、Proteus)、C51程序設計、廣告燈、電子鐘、LED屏、數(shù)字電壓表、萬年歷以及單片機綜合應用系統(tǒng)設計(機器人)等內(nèi)容?!秵纹瑱CC51項目設計與開發(fā)》注重技能訓練,內(nèi)容貼近電子行業(yè)的職業(yè)崗位需求,適當增加一些當今流行的新器件和新技術,并提供了詳細的原理說明、電路圖、完整的程序代碼及程序流程圖,具有很強的實用性、可讀性和可操作性。
《單片機C51項目設計與開發(fā)》可用作高等院校的電子信息類、通信類、自動化類、機電類等專業(yè)單片機技術課程的教材,也可用作應用型本科院校和培訓班的教材以及電子產(chǎn)品設計人員的參考書。