112 公務人員升官等薦任 資訊處理 程式語言 考古題詳解
第 一 題25 分
請依據以下 Python 程式碼回答問題:
(一) 請說明費氏數列函式 fib 的輸入參數與回傳結果。
(二) 請說明第 6 行輸出結果並加以說明。
(三) 請說明第 7 行輸出結果並加以說明。
程式碼:
def fib(n):if(n==0): return 0elif(n==1): return 1else:return fib(n-1) + fib(n-2)print("fib(1) = ", fib(1))print("fib(5) = ", fib(5))
登入後即可作答並保存紀錄。
核心觀念
本題考遞迴函式與費氏數列。費氏數列的前兩項定義為 、;其餘項由前兩項相加:
程式中的 fib 以 n 作為輸入,並依上述規則回傳第 項。第 2、3 行是遞迴的基底情況,第 5 行則是遞迴情況。
解題方法
先確認輸入值是否符合基底情況;若不符合,就將函式拆成兩次較小輸入的呼叫,直到抵達基底情況,再將結果逐層相加。
(一)fib 的輸入參數與回傳結果
fib(n) 的輸入參數是整數索引 n,用來指定要計算費氏數列的第幾項。程式以 n=0 回傳 0,以 n=1 回傳 1;其他輸入則回傳 fib(n-1) + fib(n-2)。
例如,fib(5) 會回傳費氏數列的第 5 項。此程式的定義適用於非負整數 n;負整數不會抵達基底情況,會持續遞迴。
(二)第 6 行輸出
第 6 行呼叫 fib(1)。因為 n==1,符合第 3 行的基底情況,所以函式回傳 1。
print 的兩個引數之間預設以一個空格分隔;第一個字串本身在等號後也有一個空格。因此輸出為:
fib(1) = 1
第 二 題25 分
請說明下列氣泡排序法,並回答以下 Python 程式碼之輸出結果。
程式碼:
data = [36, 22, 57, 9, 31, 42, 7, 15]print('before sorting: ', data)def Sort(data):n = len(data)while n > 1:n -= 1for i in range(n):if data[i] > data[i+1]:data[i], data[i+1] = data[i+1], data[i]print('第', 8-n, '輪排序:', data)return dataprint('after sorting: ', Sort(data))
登入後即可作答並保存紀錄。
核心觀念
氣泡排序法(Bubble Sort)會反覆比較相鄰兩個元素;若前者大於後者,就交換位置。每一輪由左往右掃描後,尚未排定部分中的最大值會移到最右側,因此下一輪可以少比較一次。
本題程式採由小到大排序,直接修改傳入的 data 串列,並在每一輪結束後印出目前狀態。排序結束時,n 已減至 ,共有 輪。
解題方法
初始串列為:
[36, 22, 57, 9, 31, 42, 7, 15]
第 4 行設定 n = 8。每次進入 while 迴圈先執行 n -= 1,所以各輪的 n 依序為 ;第 7 行的 range(n) 因此會比較 對相鄰元素。每輪結束後,第 10 行以 8-n 印出輪次。
逐輪排序如下:
| 輪次 | 比較範圍 | 輪末串列 |
|---|---|---|
| 第 1 輪 | range(7),索引 至 | [22, 36, 9, 31, 42, 7, 15, 57] |
| 第 2 輪 | range(6),索引 至 | [22, 9, 31, 36, 7, 15, 42, 57] |
| 第 3 輪 | range(5),索引 至 | [9, 22, 31, 7, 15, 36, 42, 57] |
| 第 4 輪 | range(4),索引 至 | [9, 22, 7, 15, 31, 36, 42, 57] |
| 第 5 輪 | range(3),索引 至 | [9, 7, 15, 22, 31, 36, 42, 57] |
| 第 6 輪 | range(2),索引 至 | [7, 9, 15, 22, 31, 36, 42, 57] |
| 第 7 輪 | range(1),索引 | [7, 9, 15, 22, 31, 36, 42, 57] |
第 三 題25 分
請試述下列名詞之意涵:
- 封裝(Encapsulation)
- 繼承(Inheritance)
- 多型(Polymorphism)
- SQL 隱碼攻擊(SQL Injection Attack)
- 預存程序(Stored Procedure)
登入後即可作答並保存紀錄。
核心觀念
本題考查物件導向程式設計的三項基本特性,以及資料庫程式設計中的 SQL 隱碼攻擊與預存程序。回答名詞解釋時,應先界定概念,再說明其目的或運作方式;涉及安全性時,則須交代攻擊原理與防護方式。
解題方法
依名詞分成兩組作答:
- 物件導向概念:說明封裝、繼承、多型各自處理的問題,並點出三者的差異。
- 資料庫安全與程式設計:說明 SQL 隱碼攻擊如何改變查詢語意,再交代預存程序的定義、用途及安全使用方式。
1. 封裝(Encapsulation)
封裝是將物件的資料(屬性)與操作資料的方法整合在同一個類別或物件中,並透過存取權限控制外部對內部狀態的存取。外部通常須透過公開的方法或介面操作資料,不直接任意修改內部欄位。
例如,銀行帳戶將餘額設為私有資料,外部透過 deposit、withdraw 等方法存取。方法可檢查提款金額是否超過餘額,避免物件進入不合理狀態。
封裝的重點是隱藏實作細節、保護資料並維持狀態一致性;它不等於單純把程式碼放在同一個類別中。
2. 繼承(Inheritance)
繼承是由既有類別建立新的類別,使新類別取得既有類別的屬性與方法,並可增加或改寫功能。既有類別稱為父類別(基底類別),新類別稱為子類別(衍生類別)。
例如,Vehicle 類別具有速度與行駛方法;Car 類別繼承 Vehicle 後,可沿用這些功能,並新增車門數等屬性。繼承有助於重用程式碼及表達「是一種」(is-a)的類別關係;若兩個類別只有程式碼相似,卻沒有合理的「是一種」關係,就不宜僅為重用程式碼而建立繼承。
3. 多型(Polymorphism)
多型是指不同類別的物件可透過相同的介面或操作名稱被使用,但依物件的實際類型執行不同的行為。常見方式包括方法覆寫及透過共同父類別或介面進行動態派發。
例如,Circle 與 Rectangle 都實作 draw 方法;程式呼叫 draw 時,圓形物件執行畫圓,矩形物件執行畫矩形。呼叫端只需依共同介面操作,不必依序判斷每個物件的具體類別。
第 四 題25 分
請依據以下 C 程式碼回答問題,列出輸出結果並加以說明。
程式碼:
#include <stdio.h>int main() {int i, arr[10];int *Pointer;for(i = 0; i <= 9; i++)arr[i] = (i+1)*10-i;Pointer = arr;printf("%d\n", *Pointer);printf("%d\n", *Pointer++);printf("%d\n", *++Pointer);printf("%d\n", (*Pointer)++);printf("%d\n", *--Pointer);return 0;}
登入後即可作答並保存紀錄。
核心觀念
本題考指標運算子與遞增、遞減運算子的優先順序,以及「指標移動」和「指標所指資料改變」的差別。
Pointer++、++Pointer、--Pointer:改變指標的位置。(*Pointer)++:改變指標所指的整數值,指標位置不變。- 後置遞增
x++先取用原值,再遞增;前置遞增++x先遞增,再取用新值。 - 陣列名稱
arr在此指定給指標時,代表陣列第一個元素的位址。
解題方法
先算出陣列內容:
因此:
| 索引 | arr[0] | arr[1] | arr[2] | arr[3] |
|---|---|---|---|---|
| 初始值 | 10 | 19 | 28 | 37 |
接著逐行追蹤指標位置與輸出值。令 Pointer 指向 arr[k] 表示指標位於索引 。
| 程式行 | 執行效果 | 輸出 | 執行後 Pointer 指向 |
|---|---|---|---|
Pointer = arr; | 指向 arr[0] | — | arr[0] |