108 司法特考三等 檢察事務官電子資訊組 程式語言 考古題詳解

108 年・司法特考・三等・檢察事務官電子資訊組
試題代碼 程式語言

第 一 題25 分

若有下列的 Backus-Naur Form(BNF)語法:

S→SaS∣SbS∣εS \to SaS \mid SbS \mid \varepsilon

(一)請畫出 abaaba 的剖析樹(Parsing Tree)。(15 分)

(二)請確認是否為不明確的語法(Ambiguous Grammar)。若是不明確的語法,則請舉例說明可能的解決方式;若非不明確的語法,則請說明為何沒有問題。(10 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

  1. 上下文無關文法(Context-Free Grammar, CFG)與 BNF 語法: BNF(Backus-Naur Form)為描述程式語言語法結構的形式化表示法。文法由四元組 G=(V,Σ,R,S)G = (V, \Sigma, R, S) 組成,其中 VV 為非終端符號(Non-terminals)、Σ\Sigma 為終端符號(Terminals)、RR 為產生規則(Production Rules)、SS 為起始符號(Start Symbol)。
  2. 剖析樹(Parse Tree): 以樹狀結構視覺化推導(Derivation)過程。樹根為起始符號 SS,內部節點為非終端符號,葉節點由左至右串接(Yield)即為產生的終端字串(包含空字串 ε\varepsilon)。
  3. 不明確語法(Ambiguous Grammar)之定義: 若文法中存在至少一個字串,可找出兩棵(含)以上相異的剖析樹,或存在兩條相異的最左衍生(Leftmost Derivation)/最右衍生(Rightmost Derivation),則該語法即為不明確語法(歧義語法)。
  4. 消除歧義(Disambiguation)策略: 語法呈現 A→AαAA \to A \alpha A 之雙側遞迴結構時,會因無法決定結合方向(結合律,Associativity)而產生歧義。解決方式為改寫文法,規範符號的結合方向(改為嚴格的左遞迴或右遞迴)。

解題方法

(一)畫出 abaaba 的剖析樹(15 分)

本題給定文法規則: S→SaS∣SbS∣εS \to SaS \mid SbS \mid \varepsilon

欲產生終端字串 w=abaw = aba,可採用最左衍生推導如下:

  1. S⇒SbSS \Rightarrow SbS(套用 S→SbSS \to SbS)
  2. ⇒SaSbS\Rightarrow SaSbS(最左邊之 SS 套用 S→SaSS \to SaS)
  3. ⇒εaSbS\Rightarrow \varepsilon aSbS(最左邊之 SS 套用 S→εS \to \varepsilon)
  4. ⇒εaεbS\Rightarrow \varepsilon a \varepsilon bS(SS 套用 S→εS \to \varepsilon)
  5. ⇒εaεbSaS\Rightarrow \varepsilon a \varepsilon bSaS(SS 套用 S→SaSS \to SaS)
  6. ⇒εaεbεaS\Rightarrow \varepsilon a \varepsilon b \varepsilon aS(SS 套用 S→εS \to \varepsilon)
  7. ⇒εaεbεaε=aba\Rightarrow \varepsilon a \varepsilon b \varepsilon a \varepsilon = aba(最後之 SS 套用 S→εS \to \varepsilon)

對應之剖析樹結構如下圖所示:

 S
 / | \
 S b S
 / | \ / | \
 S a S S a S
 | | | |
 ε ε ε ε

葉節點由左至右驗證: Yield=ε⋅a⋅ε⋅b⋅ε⋅a⋅ε=aba\text{Yield} = \varepsilon \cdot a \cdot \varepsilon \cdot b \cdot \varepsilon \cdot a \cdot \varepsilon = aba 符合題目要求。


(二)確認是否為不明確的語法與解決方式(10 分)

1. 確認結果:此語法為「不明確的語法(Ambiguous Grammar)」

證明(反例法): 只要能為同一個字串找出第二棵相異的剖析樹,即可證明該語法為不明確語法。以題目指定的字串 abaaba 為例,除第(一)小題繪製的剖析樹(樹根以 S→SbSS \to SbS 展開)外,尚存在另一棵完全合法的相異剖析樹(樹根以 S→SaSS \to SaS 展開):

🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 二 題25 分

請問下列 Java 程式碼:

class NumAdd { public int add(int x, int y) { return (x + y); }

public int add(int x, int y, int z) {
    return (x + y + z);
}

public int add(double x, int y) {
    return ((int) x + y);
}

public int add(int x, double y) {
    return (x + (int) y);
}

}

public class Main { public static void main(String[] args) { NumAdd na = new NumAdd();

    System.out.println(na.add(1, 2));
    System.out.println(na.add(3, 4, 5));
    System.out.println(na.add(6.7, 8));
    System.out.println(na.add(9, 10.1));
}

public Main() {
    super();
}

}

(一)其執行後的輸出為何?(7 分)

(二)請註明程式碼行號,那些程式段落使用到多載(Overloading)、覆寫(Overriding)與多型(Polymorphism)功能?(18 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題評量物件導向程式設計(OOP)的三大基礎核心機制與 Java 型態轉換:

  1. 方法多載(Method Overloading):在同一個類別內,定義多個「方法名稱相同」,但「參數列(Parameter List)不同」(參數個數、參數型別或參數順序不同)的方法。編譯器在編譯時期依據呼叫端傳入的引數型別與個數決定呼叫目標,屬於編譯期多型(Compile-time / Static Polymorphism)​或早期繫結(Early Binding)。
  2. 方法覆寫(Method Overriding):子類別重新定義父類別中已存在且具備「相同方法名稱、相同參數列與相容回傳型態」的實體方法。這是實現執行期多型(Runtime / Dynamic Polymorphism)​與動態繫結(Dynamic / Late Binding)​的前提。特別注意:建構子(Constructor)無法被繼承,因此建構子絕不可能被覆寫。
  3. 多型(Polymorphism):
  • 靜態多型(Static Polymorphism):主要透過「方法多載(Overloading)」實現。
  • 動態多型(Dynamic Polymorphism / Subtype Polymorphism):透過「繼承(Inheritance)或介面實作(Interface Implementation)」結合「方法覆寫(Overriding)」,使父類別型態的參照變數在執行時期指向子類別物件,並動態調用子類別覆寫後的方法。
  1. 型態轉換(Type Casting):浮點數型態(double)強制轉型為整數型態(int)時,會直接無條件捨去小數部分(Truncation),而非四捨五入。

程式碼行號對照基準

為便於精確標註第(二)小題之行號,本題程式碼行號標定如下:

 1: class NumAdd {
 2: public int add(int x, int y) {
 3: return (x + y);
 4: }
 5: 
 6: public int add(int x, int y, int z) {
 7: return (x + y + z);
 8: }
 9: 
10: public int add(double x, int y) {
11: return ((int) x + y);
12: }
13: 
14: public int add(int x, double y) {
15: return (x + (int) y);
16: }
17: }
18: 
19: public class Main {
20: public static void main(String[] args) {
21: NumAdd na = new NumAdd;
22: 
23: System.out.println(na.add(1, 2));
24: System.out.println(na.add(3, 4, 5));
25: System.out.println(na.add(6.7, 8));
26: System.out.println(na.add(9, 10.1));
27: }
28: 
29: public Main {
30: super;
31: }
32: }

解題方法

(一)執行輸出追蹤

逐行推導 main 方法中的呼叫過程:

  1. 第 23 行:na.add(1, 2)
  • 傳入引數為兩個整數 (int, int)。
  • 匹配第 2~4 行的方法 public int add(int x, int y)。
  • 計算過程:1+2=31 + 2 = 3。
  • 輸出:3。
  1. 第 24 行:na.add(3, 4, 5)
  • 傳入引數為三個整數 (int, int, int)。
  • 匹配第 6~8 行的方法 public int add(int x, int y, int z)。
  • 計算過程:3+4+5=123 + 4 + 5 = 12。
  • 輸出:12。
  1. 第 25 行:na.add(6.7, 8)
  • 傳入引數為浮點數與整數 (double, int)。
  • 匹配第 10~12 行的方法 public int add(double x, int y)。
  • 計算過程:(int) 6.7 + 8。
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 三 題25 分

請問下列兩個 Python 程式,若分別輸入 Andy、World、Everyone 後:

程式 A:

import sys

def Calc(sInput): sOutput = "Hello, " + sInput + "!" return(sOutput)

sInput = sys.stdin.readline()

while (sInput != ""): sInput = sInput.replace("\r", "").replace("\n", "") print(Calc(sInput)) sInput = sys.stdin.readline()

程式 B:

def Calc(sInput): sOutput = "Hello, " + sInput + "!" return(sOutput)

try: while(1): print(Calc(input())) except (EOFError): pass

(一)其執行後的輸出分別為何?(10 分)

(二)若兩個程式都可以被正常執行,請說明其執行方式與優缺點?(15 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題旨在評量考生對於 Python 標準輸入(Standard Input, stdin)的處理機制、I/O 效能差異、字串換行字元處理,以及迴圈終止機制(條件哨兵值 vs. 例外處理機制)的掌握程度:

  1. 輸入函式行為差異:sys.stdin.readline 屬於底層緩衝讀取,會保留行尾換行字元(\n 或 \r\n),讀至檔案結尾(EOF)時回傳空字串 "";內建函式 input 則會自動去除行尾換行字元,讀至 EOF 時會拋出 EOFError 例外。
  2. 流程控制哲學:程式 A 採用傳統結構化程式設計的「哨兵值(Sentinel Value)」迴圈;程式 B 採用 Python 慣用的 EAFP(Easier to Ask for Forgiveness than Permission)風格,利用「例外處理(Exception Handling)」控制流程結束。

解題方法

(一)執行後的輸出分析

題目給定輸入依序為:Andy、World、Everyone,最後觸發 EOF(輸入結束)。

  1. 自訂函式 Calc(sInput) 行為:
  • 接收字串參數 sInput,透過字串串接回傳 "Hello, " + sInput + "!"。
  1. 程式 A 追蹤:
  • 第 1 次 sys.stdin.readline 讀入 "Andy\n"(或 Windows 下的 "Andy\r\n"),字串長度非 0,滿足 sInput != ""。
  • 經 .replace("\r", "").replace("\n", "") 去除換行字元後,sInput 變為 "Andy"。
  • Calc("Andy") 回傳 "Hello, Andy!" 並由 print 印出。
  • 依序處理 "World" 與 "Everyone",分別印出 "Hello, World!" 與 "Hello, Everyone!"。
  • 第 4 次讀取遇到 EOF,sys.stdin.readline 回傳空字串 "",條件 sInput != "" 不成立,跳出迴圈終止程式。
  1. 程式 B 追蹤:
  • 第 1 次 input 讀入 "Andy"(自動濾除行尾換行字元),呼叫 Calc("Andy") 印出 "Hello, Andy!"。
  • 第 2 次、第 3 次依序讀入 "World" 與 "Everyone",分別印出 "Hello, World!" 與 "Hello, Everyone!"。
  • 第 4 次 input 遇到 EOF,引發 EOFError。
  • 程式由 except (EOFError): 捕捉例外並執行 pass,正常結束程式。

(二)執行方式與優缺點評析

1. 執行方式比較
  • 程式 A:
  • 讀取模組:依賴 sys 標準函式庫,直接調用底層檔案物件的 sys.stdin.readline 方法。
  • 迴圈終止機制:採用「前置讀取(Priming Read)」配合 while 哨兵值判斷。當回傳值為長度為 0 的空字串 "" 時判定為 EOF 並終止迴圈。
  • 格式整理:必須透過字串替換方法手動濾除 CR(\r)與 LF(\n)。
  • 程式 B:
  • 讀取模組:使用 Python 內建高階函式 input,無需匯入任何模組。
  • 迴圈終止機制:採用無窮迴圈 while(1),完全依賴事件導向的「例外處理(try...except)」。以 EOFError 作為中斷信號。
  • 格式整理:input 在讀入字串時自動剝除行尾換行字元。
2. 優缺點比較
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

第 四 題25 分

有關預存程序(Stored Procedure),請回答下列問題:

(一)請說明其定義。(7 分)

(二)請寫出程式碼範例。(10 分)

(三)請說明其優缺點為何?(8 分)

登入後即可作答並保存紀錄。

這一題的完整詳解

核心觀念

本題考驗關聯式資料庫管理系統(RDBMS)中預存程序(Stored Procedure, SP)​的架構定位、語法設計與實務應用評估:

  1. 儲存與執行架構:預存程序是預先編譯並儲存於資料庫伺服器端的 SQL 語句與程序控制敘述集合,具有伺服端執行、執行計畫快取(Execution Plan Caching)等特性。
  2. 與一般 SQL 查詢之差異:相較於由應用程式端發送的動態 ad-hoc SQL,預存程序支援輸入/輸出參數、流程控制結構(IF-ELSE、迴圈、例外處理),並可封裝複雜的資料交易(Transaction)。
  3. 資訊安全與軟體工程權衡:參數化傳遞可有效防止資料隱碼攻擊(SQL Injection),並降低網路負載;但在多層次架構(N-Tier)中,將業務邏輯放置於資料庫端會衍生伺服器負載、版本控管不易與跨平台移植(Vendor Lock-in)困難等缺點。

解題方法

本題為標準的問答申論與實作題,作答策略如下:

  1. 第(一)小題(定義):從「儲存位置」、「編譯機制(Pre-compiled)」、「介面特性(參數與流程控制)」三維度進行精準定義,點出其介於單純 SQL 語句與高階程式語言模組之間的特性。
  2. 第(二)小題(程式碼範例):採用公職考題中最普及且符合標準的 ANSI SQL / T-SQL 語法。範例必須具備「輸入參數(Input Parameter)」、「業務邏輯或交易處理」及「呼叫執行方式(EXEC 或 CALL)」,展現完整的語法結構,避免僅撰寫無參數的單一 SELECT 語句。
  3. 第(三)小題(優缺點):分別從「效能與網路」、「安全與權限」、「維護與移植性」、「伺服器硬體負載」四大構面進行對稱式條列分析,確保論點全面且具實務深度。

解題技巧

  1. 概念區隔防踩雷:
  • 預存程序 vs. 自訂函數(UDF):UDF 必須有傳回值且不能執行影響資料庫狀態的 DDL/DML(不得有副作用);預存程序可無回傳值、可傳回多個結果集(Result Sets),且允許完整的 DML 交易。
  • 預存程序 vs. 觸發程序(Trigger):Trigger 是事件驅動(隱式觸發),預存程序必須顯式呼叫(Explicit Call)。
  1. 範例拿滿分關鍵:程式碼必須包含 CREATE PROCEDURE、宣告參數(型別)、邏輯本體(BEGIN ... END),並補上呼叫範例(如 EXEC ...),閱卷評分標準方能給予完整的 10 分。

【答案】

(一)預存程序(Stored Procedure)之定義(7 分)

預存程序(Stored Procedure)​是一組預先編寫、經過編譯並儲存在關聯式資料庫管理系統(RDBMS)伺服器端的一段 SQL 語句與程序導向控制結構(如條件判斷、迴圈、例外處理)的集合。

其核心特點包含:

  1. 預先編譯(Pre-compiled)與最佳化:資料庫在首次編譯或建立預存程序時,即完成語法解析並產生最佳化的「執行計畫(Execution Plan)」存入快取記憶體,後續呼叫可直接重複利用,大幅節省解析時間。
  2. 介面化與參數支援:可定義輸入參數(IN / 輸入變數)與輸出參數(OUT / 回傳值),如同一段函式或副程式,供外部應用程式或其它資料庫模組傳參呼叫。
  3. 封裝性:將複雜的資料庫操作(如跨資料表查詢、多步交易)封裝在伺服端單一邏輯單元內。

(二)程式碼範例(10 分)

以下以業界與國考常用的標準 T-SQL(適用於 Microsoft SQL Server / Sybase)實作一個「員工調薪處理程序」,包含輸入參數、更新操作與例外控制:

1. 建立預存程序(CREATE PROCEDURE)
🔒

後續完整解題步驟與【答案】

免費註冊,享 3 天全站完整詳解閱覽。

免費註冊

其他考古題