練題.doc:格式轉(zhuǎn)換與題庫提取實戰(zhàn)指南)
簡介在日常辦公與備考場景中我們經(jīng)常會收到來自網(wǎng)絡(luò)的.doc文檔這類舊版Word格式可能攜帶宏病毒因此安全打開是第一步。理解Office受保護視圖的原理合理設(shè)置信任中心并用PowerShell或oletools進行預(yù)檢能有效規(guī)避風(fēng)險。將.doc轉(zhuǎn)換為.docx則是后續(xù)利用python-docx等工具提取文本的基礎(chǔ)LibreOffice頭模式提供了高效批量轉(zhuǎn)換方案。針對覆蓋計算機二級C語言、計算機組成原理等考點的訓(xùn)練題文檔借助正則表達式可將題目結(jié)構(gòu)化進而構(gòu)建自測題庫。文章以一份實際訓(xùn)練題文件為例演示從安全驗證、格式轉(zhuǎn)換到題庫拆解的完整流程幫助備考者高效刷題、查漏補缺。1. “計算機訓(xùn)練題.doc”到底是什么一份能直接刷的題庫還是一個要拆的怪盒如果你在考研群、畢設(shè)小組或同事U盤里拿到一份名為“[詳細(xì)完整版]計算機訓(xùn)練題.doc”的文件第一反應(yīng)多半是雙擊打開??蒞indows常常會彈出“你嘗試預(yù)覽的文件可能對你的計算機有害。如果你信任此文件以及其來源請打開此文”很多人被這句警告勸退順手就把文件刪了。這份文檔的真實身份大概率是一份覆蓋計算機基礎(chǔ)、計算機組成原理、計算機二級C語言常考點的訓(xùn)練題集只是它被塞進了老舊的.doc容器里正文里還帶著公式、圖片甚至早期文檔才有的宏。這篇文章不聊虛的就講我拿到這類文件后怎么安全打開、怎么把題目結(jié)構(gòu)化、哪些坑會讓人白折騰一晚上。適合備考計算機二級、復(fù)習(xí)計算機組成原理和計算機系統(tǒng)結(jié)構(gòu)的讀者照著走一遍。2. 打開.doc前的安全課為什么Windows會警告“對計算機有害”以及怎么正確解除2.1 先搞懂警告來源宏、外部鏈接和“保護視圖”當(dāng)Windows彈出一句“你嘗試預(yù)覽的文件可能對你的計算機有害”時很多人第一反應(yīng)是殺毒軟件報毒了其實這是Office的受保護視圖提醒。受保護視圖的邏輯是對來自Internet、郵件附件或受限目錄的文檔先在一個隔離環(huán)境里渲染預(yù)覽默認(rèn)禁止編輯、禁止宏、禁止ActiveX控件。這么做的目的就是為了防止一份看似正常的doc在你雙擊的瞬間執(zhí)行惡意代碼。所以“預(yù)覽可能有害”這句話的準(zhǔn)確含義是在沒確認(rèn)內(nèi)容之前最穩(wěn)妥的辦法是只看不編輯。為什么這類警告總跟.doc綁在一起因為.doc是OLE2復(fù)合文檔格式它可以嵌入宏、嵌入對象、嵌入DDE域和外部鏈接。歷史上以宏病毒形式傳播的惡意Word文檔絕大多數(shù)都采用.doc后綴。Kill宏病毒的原理是檢測VBA工程里是否有AutoOpen、DocumentOpen這類自動宏。如果某個訓(xùn)練題doc里有自動宏你雙擊打開的一瞬間宏代碼就可能運行。所以看到一個舊版訓(xùn)練題doc第一件事不是看題而是看它有沒有宏。還要注意一個細(xì)節(jié)文件資源管理器在顯示“來自Internet”時實際上給文件關(guān)聯(lián)了一條NTFS數(shù)據(jù)流Zone.Identifier。Office讀到ZoneId為3Internet時就啟用受保護視圖。你可以把文件從下載目錄拖到桌面這條標(biāo)記仍然存在因為標(biāo)記跟隨文件本身而不是目錄。所以“我從下載文件夾拷出來了它應(yīng)該安全”這種想法靠不住。在Windows里我一般這樣判斷文件大小小于10KB但文件名寫著“詳細(xì)完整版”可疑文件屬性里沒有作者、沒有修訂信息只有“來自Internet”可疑雙擊后打開進入受保護視圖說明確有標(biāo)記不是殺毒誤報殺毒軟件掃描無異常只能說明沒有已知病毒不能說明沒有宏。真正拿到訓(xùn)練題doc別急著雙擊。先做掃描再看宏再決定要不要“啟用編輯”。這套習(xí)慣能擋掉絕大多數(shù)麻煩。2.2 用Word/WPS的安全打開三連解除鎖定、信任中心與只讀啟動在確認(rèn)文件來源基本可信后再用辦公軟件打開。這里的操作順序我總結(jié)成“先解除鎖定再設(shè)宏安全最后只讀啟動”。解除鎖定在文件上右鍵“屬性”常規(guī)頁簽底部有一個“解除鎖定”復(fù)選框前面有個安全鎖圖標(biāo)。勾上它Windows會刪除文件上的Zone.Identifier標(biāo)記。這樣再雙擊Office就不會強行用受保護視圖打開這個文件。注意只有文件確實來自Internet時這個復(fù)選框才會出現(xiàn)。如果文件是通過FTP、本地U盤拷貝過來的可能沒有這個選項那就跳過不影響后面。宏設(shè)置打開Word后進入“文件 選項 信任中心 信任中心設(shè)置 宏設(shè)置”選擇“禁用所有宏并發(fā)出通知”。這個選項的意思是文檔里的宏不會自動執(zhí)行但如果文檔確實包含宏Word會彈一個通知條提醒我。相比之下“禁用所有宏而不通知”過于安靜反而讓我不知道這文件里帶沒帶宏“啟用所有宏”則完全是給惡意文檔開門不要選。WPS里對應(yīng)位置通常在“設(shè)置 安全設(shè)置 宏安全性”同樣選禁用。只讀啟動在Word里用“文件 打開”選中文件后不直接雙擊而是點擊打開按鈕旁邊的下拉箭頭選“以只讀方式打開”。如果擔(dān)心宏寫入文件這個操作能保證當(dāng)前會話只讀。訓(xùn)練題嘛本來就只需要看不需要改原文件。只讀打開后如果看到“啟用編輯”按鈕點它不會讓宏自動運行只要你不點“啟用內(nèi)容”。宏設(shè)置是“禁用并通知”所以此時“啟用內(nèi)容”才是放行的開關(guān)。還有一點值得說如果只是臨時看題不需要把訓(xùn)練題doc轉(zhuǎn)成docx直接看就行。一旦想修改或者做題庫就另存為docx。另存的過程會把舊的OLE對象重新封裝一遍文檔里的VBA宏如果是不受歡迎的Word通常會在保存時提示或清除相關(guān)宏。這等于給文件做了一次“凈化”。2.3 不靠Office也能驗貨用PowerShell和oletools取樣很多情況下我不想打開Word再判斷尤其是來路不明的“[詳細(xì)完整版]計算機訓(xùn)練題.doc”。命令行比圖形界面更適合批量排查我先看文件有沒有Internet標(biāo)記再算哈希然后掃宏。# 查看文件是否帶著來自網(wǎng)絡(luò)的Zone.Identifier標(biāo)記 Get-Item -Path C:\Users\test\Downloads\[詳細(xì)完整版]計算機訓(xùn)練題.doc -Stream Zone.Identifier -ErrorAction SilentlyContinue | Format-List # 計算SHA256留底之后方便跟發(fā)布者核對文件是否一致 Get-FileHash -Path C:\Users\test\Downloads\[詳細(xì)完整版]計算機訓(xùn)練題.doc -Algorithm SHA256 | Format-List第一條命令如果輸出ZoneId3說明文件確實來自Internet如果沒有任何輸出可能是本機生成的也可能是所在磁盤不支持NTFS流。第二條命令生成一個64位哈希值這個值相當(dāng)于文件指紋。拿到指紋后發(fā)給傳文件給你的人他在自己電腦上算一遍SHA256如果兩個哈希一致說明文件在傳輸過程中沒有被替換也沒有發(fā)生損壞。這個操作在排查“文檔打開報錯”時特別好用因為很多“.doc打不開”其實根本不是Office問題是文件從網(wǎng)盤下載下來少了一半字節(jié)??赐旯T賿吆?。先安裝oletoolspip install oletools olevba -c C:\Users\test\Downloads\[詳細(xì)完整版]計算機訓(xùn)練題.doc-c參數(shù)讓olevba只打印檢測到的宏代碼。如果輸出區(qū)域顯示“VBA Macros: No”說明這個doc里沒有VBA工程可以放心用Word打開。如果顯示有AutoOpen、DocumentOpen這類自動宏就要警惕最好先搞明白宏里面的代碼到底干什么。注意oletools還能檢測DDE、外部關(guān)系但命令行里最常用的是olevba和oleid。一個訓(xùn)練題doc如果同時滿足“來自Internet 沒有宏 哈希正?!被究梢源_定只是普通文檔。提示把doc拖進在線掃描服務(wù)前先想清楚里面有沒有個人或敏感信息。訓(xùn)練題通常不涉及隱私但如果你不放心還是本地用oletools掃更穩(wěn)妥。3. 把.doc里的訓(xùn)練題變成可用的題庫文本提取與結(jié)構(gòu)化3.1 為什么不能直接用python-docx打開.doc先轉(zhuǎn)成.docx刷題刷多了就會發(fā)現(xiàn)手工翻Word文檔效率太低尤其這份“訓(xùn)練題doc”可能有幾百道題。很多人想寫腳本提取文本第一步就翻了車python-docx打開.doc文件直接拋PackageNotFoundError或docx file invalid。原因不是代碼寫錯而是python-docx只支持Office Open XML格式也就是.docx。doc是OLE2復(fù)合文檔內(nèi)部結(jié)構(gòu)是一堆Stream和Storage跟docx的ZIP目錄結(jié)構(gòu)完全是兩碼事。Windows上最簡單的方案是手動用Word打開然后另存為docx但只能一個文件一個文件地轉(zhuǎn)。如果訓(xùn)練題有好幾個doc手工操作非常浪費時間。我一般用LibreOffice的無頭模式批量轉(zhuǎn)換。LibreOffice是免費開源辦公套件有命令行接口能跑在Windows、Linux和macOS上。mkdir -p converted libreoffice --headless --convert-to docx [詳細(xì)完整版]計算機訓(xùn)練題.doc --outdir converted--headless表示不啟動圖形界面適合在服務(wù)器上跑--convert-to docx指定輸出格式--outdir converted把生成的docx放到converted目錄。如果遇到包含中文文件名的情況建議保持雙引號包裹否則部分Linux shell會因括號或空格解析錯亂。Windows下如果提示libreoffice: command not found是因為安裝時沒有把LibreOffice寫進PATH??梢杂萌窂綀?zhí)行 C:\Program Files\LibreOffice\program\soffice.exe --headless --convert-to docx C:\work\[詳細(xì)完整版]計算機訓(xùn)練題.doc --outdir C:\work\converted需要批量轉(zhuǎn)換時在Linux/macOS下用循環(huán)for f in *.doc; do libreoffice --headless --convert-to docx $f --outdir converted; done在Windows PowerShell下這樣寫Get-ChildItem *.doc | ForEach-Object { C:\Program Files\LibreOffice\program\soffice.exe --headless --convert-to docx $_.FullName --outdir converted }這里$_.FullName是當(dāng)前文件的完整路徑避免工作目錄不同導(dǎo)致找不到源文件。轉(zhuǎn)換時間不長幾兆的文件耗時幾秒鐘。轉(zhuǎn)換過程如果報錯通常有三種LibreOffice沒有安裝、源文件被占用、輸出目錄不存在。先創(chuàng)建converted目錄再執(zhí)行命令。3.2 遇到“dify unstructured api url is not configured for doc file processing”時怎么繞開除了本地刷題還有人想把這套訓(xùn)練題喂給AI知識庫讓大模型根據(jù)這份doc出題或者答疑。常見做法是使用Dify這類平臺搭建一個知識庫上傳文檔后讓平臺自動抽取文本。如果你直接把“.doc”拖上去平臺往往回你一句dify unstructured api url is not configured for doc file processing。這句話的意思是Dify處理doc文件依賴一個叫Unstructured的文檔解析服務(wù)而部署Dify時后臺沒有配置那個服務(wù)的API地址。于是系統(tǒng)無法對doc做文本抽取。這個報錯跟你的訓(xùn)練題沒關(guān)系是平臺配置缺失。兩條出路第一條如果你能控制Dify服務(wù)的環(huán)境變量到后臺配置UNSTRUCTURED_API_URL讓它指向可用的Unstructured服務(wù)地址。第二條也是最省事的一條不要直接傳doc而是先按3.1節(jié)的方法在本地把doc轉(zhuǎn)成docx再上傳。Dify對docx的解析不需要調(diào)Unstructured因為它自身能讀取docx內(nèi)部的文本節(jié)點。我在部署經(jīng)驗里吃過這個虧后來凡是遇到doc文件都養(yǎng)成了先轉(zhuǎn)docx再喂平臺的習(xí)慣。這不僅能繞開Dify的配置問題也能減少其他知識庫工具的兼容性報錯。如果堅持要在本地起Unstructured服務(wù)可以用Docker起一個鏡像把宿主機端口映射成服務(wù)端口然后在Dify的配置里填http://localhost:8000。但這對于一份訓(xùn)練題來說明顯是殺雞用牛刀。本地轉(zhuǎn)格式是零依賴的兜底方案。3.3 用正則把題目拆成結(jié)構(gòu)化條目題號、題干、選項、答案轉(zhuǎn)成docx后真正的難點是把雜亂的題目拆成結(jié)構(gòu)化數(shù)據(jù)。我先把拆題過程拆成兩步第一步統(tǒng)計題號格式第二步按統(tǒng)計結(jié)果做正式拆分。先寫統(tǒng)計腳本from collections import Counter from docx import Document doc Document(converted/[詳細(xì)完整版]計算機訓(xùn)練題.docx) patterns Counter() for para in doc.paragraphs: text para.text.strip() if not text: continue m re.match(r^(\d{1,3})[\.、\)], text) if m: patterns[m.group(1) .] 1 elif re.match(r^第[\d一二三四五六七八九十百]題, text): patterns[第X題] 1 elif re.match(r^[A-D][\.、\)], text): patterns[選項] 1 print(patterns.most_common(10))這段代碼遍歷每個段落分別統(tǒng)計“1.”“第1題”和“A.”三類開頭的數(shù)量。輸出能告訴你這份訓(xùn)練題的主要排版風(fēng)格。如果“第X題”出現(xiàn)次數(shù)很多正式拆分時就要優(yōu)先用中文題號。如果“1.”很多就用數(shù)字題號。不要跳過這步因為Word訓(xùn)練題里經(jīng)常出現(xiàn)“第2題”和“2、”混用直接寫死正則會拆出大量垃圾條目。統(tǒng)計完以后執(zhí)行正式拆分import re from docx import Document ITEMS [] CUR None def flush(): if CUR is not None: ITEMS.append(CUR) doc Document(converted/[詳細(xì)完整版]計算機訓(xùn)練題.docx) for para in doc.paragraphs: text para.text.strip() if not text: continue # 數(shù)字題號1、 1. 1 1 m re.match(r^(\d{1,3})[\.、\)]\s*(.*), text) if m: flush() CUR { id: int(m.group(1)), question: m.group(2), options: [], body: [], answer: None } continue # 中文題號第1題 第2題 m re.match(r^第(\d)題\s*(.*), text) if m: flush() CUR { id: int(m.group(1)), question: m.group(2), options: [], body: [], answer: None } continue if CUR is None: continue # 選項行 m re.match(r^([A-D])[\.、\)]\s*(.*), text) if m: CUR[options].append((m.group(1), m.group(2))) continue # 答案行 m re.match(r^(答案|參考答案)[:]\s*([A-D]{1,4}), text) if m: CUR[answer] m.group(2) continue # 其他都算題干補充 CUR[body].append(text) flush() print(拆出題目數(shù):, len(ITEMS))這段代碼的關(guān)鍵是CUR字典它保存正在組裝的一道題。遇到新的題號時先把上一題存進ITEMS再新建當(dāng)前題。選項行單獨匹配答案行同樣單獨匹配。正則里的(\d{1,3})限制題號最多三位目的是防止把“1.2 小節(jié)編號”誤判成題目編號。如果訓(xùn)練題是多選題答案可能是“ABC”或“ABCD”正則里的[A-D]{1,4}就是這個作用。單選的答案字符串只有1個字符拆出來也不影響。有些訓(xùn)練題答案不跟題而是集中在文檔末尾的“參考答案1-5 ABCDA6-10 BCDAB”這種段落。如果要處理這種集中式答案需要額外寫一段區(qū)間解析。我的做法是單獨讀取以“參考答案”開頭的段落用(\d)-(\d)\s*[:]?\s*([A-D])匹配題號區(qū)間和答案串然后把答案串按字符切開回填到對應(yīng)題目的answer字段。這是拆題時最容易被忽略的部分因為如果答案行和題目不在一起上面這段代碼拆出的所有答案都是None。另外python-docx的doc.paragraphs只包含段落不包含表格里的內(nèi)容。如果訓(xùn)練題的題干或選項放在Word表格里段落遍歷會漏掉。遇到這種情況我一般先用doc.tables把所有單元格文本抽出來再跟段落文本合并成一個“全文行列表”。合并后再跑拆分題目數(shù)量就對得上了。all_lines [] for p in doc.paragraphs: all_lines.append(p.text) for table in doc.tables: for row in table.rows: for cell in row.cells: all_lines.append(cell.text)注意表格里的文本順序不一定是題目順序因為Word表格有合并單元格和行列結(jié)構(gòu)。如果源文檔把一題一個表格順序是對的如果所有題目塞進一個大表格取出來順序容易亂。所以我在拆題前總會在統(tǒng)計腳本里加一行判斷l(xiāng)en(doc.tables)如果表格數(shù)量接近題目數(shù)說明是“題表格”結(jié)構(gòu)可以用表格方式拆如果只有一個表格那還是先復(fù)制到文本編輯器里轉(zhuǎn)成純文本再處理比較保險。4. 圍繞計算機組成原理與計算機二級C語言這份訓(xùn)練題怎么學(xué)才不白刷4.1 先把題目按“計算機系統(tǒng)結(jié)構(gòu)/組成原理/操作系統(tǒng)/網(wǎng)絡(luò)”歸類訓(xùn)練題這種doc一般不會像教材那樣按章節(jié)涇渭分明地排。它前面可能是Windows常識后面突然跳到進程調(diào)度再過兩頁又是C語言指針。從頭刷到尾最大的問題是你刷完100道題根本不知道自己哪塊弱。所以我拆完題以后第一件事是打標(biāo)簽。我給自己定的標(biāo)簽范圍是四類組成原理包含計算機系統(tǒng)結(jié)構(gòu)、操作系統(tǒng)、網(wǎng)絡(luò)、C語言。這四類基本覆蓋了計算機二級C語言和考研408的??挤较?。打標(biāo)簽可以用關(guān)鍵詞規(guī)則先初篩再人工確認(rèn)。下面是一個可用的Python示例import re TAG_RULES [ (r(補碼|原碼|反碼|浮點|IEEE|Cache|主存|流水線|中斷|DMA|尋址|字長|ALU), 組成原理), (r(進程|線程|死鎖|信號量|頁面置換|虛擬內(nèi)存|文件系統(tǒng)|磁盤調(diào)度), 操作系統(tǒng)), (r(TCP|UDP|IP地址|子網(wǎng)|交換機|路由器|OSI|幀|端口), 網(wǎng)絡(luò)), (r(指針|數(shù)組|結(jié)構(gòu)體|函數(shù)|遞歸|printf|scanf|sizeof), C語言), ] def classify(text): for pattern, label in TAG_RULES: if re.search(pattern, text): return label return 計算機基礎(chǔ)分類規(guī)則很簡單但很實用??吹健癈ache”“主存”“流水線”幾乎可以確定是組成原理題??吹健敖M間串行進位”這是并行進位鏈的考點屬于計算機系統(tǒng)結(jié)構(gòu)里比較經(jīng)典的內(nèi)容。這類題不能只看答案最好畫一畫進位鏈的傳遞邏輯否則遇到換一種參數(shù)的題又會錯。有的訓(xùn)練題還會包含“計算機系統(tǒng)結(jié)構(gòu)”和“計算機組成原理”的邊界題比如區(qū)分“透明性”“并行性”。我的處理原則是只要題目在說硬件內(nèi)部如何工作就歸到組成原理只要題目在說整機屬性或性能指標(biāo)就歸到計算機系統(tǒng)結(jié)構(gòu)。不用搞得很嚴(yán)格刷題只是為了查漏補缺。標(biāo)簽打完后我給每類題用不同策略復(fù)習(xí)。C語言題先用編譯器驗證組成原理題動筆算網(wǎng)絡(luò)和操作系統(tǒng)題重復(fù)記憶。如果一份訓(xùn)練題里“操作系統(tǒng)”類題目明顯多說明這份doc的出題偏向系統(tǒng)方向如果“組成原理”類多那更像是考研復(fù)習(xí)材料。根據(jù)自己的目標(biāo)調(diào)整刷題順序比死磕原文檔順序效率高。4.2 二級C語言題的“三遍刷法”讀題→畫內(nèi)存→對答案計算機二級C語言是這份訓(xùn)練題被廣泛搜索的核心關(guān)鍵詞。二級C語言考試?yán)镏羔?、?shù)組、結(jié)構(gòu)體、函數(shù)調(diào)用這些小題很多人看書感覺自己都會一到考試就發(fā)現(xiàn)輸出跟預(yù)想的不一樣。原因很簡單C語言的內(nèi)存模型不是靠眼睛看會的。我處理二級C語言題的固定方法是“三遍刷法”。第一遍只看題不碰編譯器。遇到指針或數(shù)組的代碼片段在草稿紙上畫內(nèi)存。四個字節(jié)的格子變量名寫在上面指針用箭頭指向格子。寫出代碼執(zhí)行到每個語句后的狀態(tài)。第二遍打開編譯器把題干里的代碼原樣敲進去運行看實際輸出跟手推的差在哪。絕大多數(shù)情況下差別來自的優(yōu)先級、*p和(*p)的區(qū)別、數(shù)組下標(biāo)從0開始的次數(shù)錯誤。第三遍把錯的題號和關(guān)鍵字寫進錯題本。這個錯題本不用寫整題只寫“*p等價于*(p)”這種一兩行結(jié)論。下面這個C語言片段幾乎能覆蓋所有指針自加考點#include stdio.h int main(void) { int a[4] {1, 2, 3, 4}; int *p a; printf(p %p, *p %d\n, (void *)p, *p); printf(*p %d\n, *p); printf(after *p, *p %d\n, *p); return 0; }第一次運行前我先在紙上寫p指向a[0]*p先取a[0]的值1然后指針移動到a[1]所以第一個printf輸出1第二個printf里*p變成2。實際運行時如果輸出順序和你預(yù)想不一致就說明對“后置”的求值時機理解有偏差。二級C語言就喜歡考這類細(xì)節(jié)單獨背語法規(guī)則容易忘跑一遍編譯器印象會深很多。還要注意如果代碼片段里有scanf、gets這些輸入函數(shù)單獨跑時要有輸入數(shù)據(jù)。我的習(xí)慣是把輸入寫進一個文本文件運行命令改成./a.out input.txt這樣每道題都能可重復(fù)驗證。4.3 唐朔飛課后題與訓(xùn)練題混用的邊界什么時候別迷信答案準(zhǔn)備計算機考研的同學(xué)手邊通常有唐朔飛《計算機組成原理》的課后題和這份訓(xùn)練題。這兩類題可以一起做但心里要有數(shù)訓(xùn)練題是“考點掃描”唐朔飛的教材題是“原理推導(dǎo)”。掃描題往往只給結(jié)論推導(dǎo)題需要你從頭寫過程?;熘r最忌諱的是把訓(xùn)練題答案當(dāng)成絕對權(quán)威。舉個常見的沖突點Cache的寫直達法和寫回法。有的訓(xùn)練題直接問“Cache更新主存的方式有哪些”答案列了一個“寫直達”沒有提“寫回”??商扑凤w的教材里這兩種方案都會詳細(xì)對比。如果你只是背了“寫直達”這個詞下次考試換個方式問“什么情況下寫回法優(yōu)于寫直達”照樣不會。所以我做這類題時只要訓(xùn)練題答案里出現(xiàn)“Cache”“主存”“寫直達”這些詞就會去翻教材把兩種策略的適用條件抄在題目旁邊。再比如“機器字長”的定義不同教材的用語略有差異。唐朔飛強調(diào)機器字長是CPU一次能處理的數(shù)據(jù)位數(shù)而某些訓(xùn)練題答案把存儲器的位寬也扯進來結(jié)果兩道題答案對不上。這種情況我以教材為準(zhǔn)訓(xùn)練題答案標(biāo)注為“有爭議”。復(fù)習(xí)時不要浪費時間去背一個錯誤說法。如果備考的是軟件設(shè)計師或其他計算機職業(yè)資格考試訓(xùn)練題里的組成原理部分同樣可以作為基礎(chǔ)練習(xí)但軟考更偏體系結(jié)構(gòu)、指令流水線和存儲系統(tǒng)訓(xùn)練題里偏老的硬件常識題可以跳過。計算機程序設(shè)計員Java三級這類考試也會考計算機基礎(chǔ)知識和C語言語法這份doc里的二級C語言段落當(dāng)熱身正合適。題目來源覆蓋風(fēng)格答案可靠度建議用法訓(xùn)練題doc碎、雜、考點面廣中偶有印刷錯誤先掃描知識盲區(qū)唐朔飛課后題推導(dǎo)鏈完整高有教材依據(jù)重點章節(jié)精做真題/模擬題貼近考試角度高考前限時刷5. 避坑指南訓(xùn)練題doc的5個常見坑每個坑都能讓你白折騰一晚上5.1 坑1公式和圖片抽不出來的最大元兇是OLE對象現(xiàn)象用python-docx讀取轉(zhuǎn)換后的docx題目文本能拿到但數(shù)學(xué)公式全部變成空白或者圖片位置只顯示一個空段落。碰到“浮點數(shù)加減法”這類題題干缺了核心表達式根本沒法判斷選項到底在問哪個兩個數(shù)相加。原因doc里的公式如果是由微軟公式編輯器或MathType插入的真正的內(nèi)容不在文本流里而在OLE對象里。python-docx主要讀取w:t文本節(jié)點OLE對象以二進制形式嵌入在word目錄下不暴露給paragraph.text。圖片也一樣doc里如果嵌入了WMF/EMF矢量圖轉(zhuǎn)成docx后雖然還掛著但python-docx默認(rèn)不會把它轉(zhuǎn)成可讀文本。解決如果只是看題不追求文本抽取直接讓LibreOffice把doc轉(zhuǎn)成PDF公式和圖片會以矢量或位圖方式留在PDF里。命令很簡單把--convert-to docx換成--convert-to pdf。如果一定要文本接受缺失把題干里的“______”當(dāng)占位符公式部分手動補錄。想自動提取公式目前只有把公式轉(zhuǎn)成圖片再用OCR識別成本高且對訓(xùn)練題來說不劃算。5.2 坑2題號正則匹配錯亂因為“第1題”和“1、”混用現(xiàn)象拆分腳本跑完題目數(shù)量少了三分之一。打開JSON一看有的題干被塞進上一題的body有的題號根本沒出現(xiàn)。原因這份doc很可能不是一個人排的版。前面幾章用“1、”后面幾章用“第22題”還有的題號后面是中文全角句號“”。統(tǒng)計腳本里只用^(\d{1,3})[\.、\)]匹配遇到“第11題”就匹配不上這段文字就會當(dāng)成普通文本追加到上一道題里。解決拆分前必須跑統(tǒng)計腳本并把它輸出的所有編號格式都納入正則匹配。正確的匹配順序是先匹配第(\d)題再匹配(\d{1,3})[\.、\)]。因為“第11題”里的數(shù)字也可被第二個正則吃掉但如果先匹配中文格式就不會誤拆。同時統(tǒng)計腳本里的.要寫成\.否則“1a”這種也會被當(dāng)成題號。全角句點“”的Unicode是UFF0E正則里直接寫字面量編碼工具一般都能識別。5.3 坑3直接用python-docx打開.doc報錯“docx file invalid”現(xiàn)象明明文件名是訓(xùn)練題.docDocument(訓(xùn)練題.doc)卻拋出PackageNotFoundError或者干脆報docx file invalid。原因python-docx的解析器完全依賴ZIP格式的docx結(jié)構(gòu)而doc是OLE復(fù)合文檔。它打不開doc不是代碼不兼容是格式根本不支持。很多新手在這里卡殼以為是文件壞了其實是選錯了工具。解決先做格式轉(zhuǎn)換再用python-docx讀。Windows下如果堅持用Word COM也不是不行$word New-Object -ComObject Word.Application $word.Visible $false $doc $word.Documents.Open(C:\temp\[詳細(xì)完整版]計算機訓(xùn)練題.doc) $doc.SaveAs2(C:\temp\計算機訓(xùn)練題.docx, 16) $doc.Close() $word.Quit()這里SaveAs2的第二個參數(shù)16是wdFormatXMLDocument也就是保存為docx。COM方案的問題是Word版本不同枚舉值可能變化而且服務(wù)器上COM權(quán)限經(jīng)常抽風(fēng)。LibreOffice的headless命令行更穩(wěn)定推薦優(yōu)先使用3.1節(jié)里的方案。記住任何需要批量處理的場景都不要走圖形界面另存為。5.4 坑4文件損壞或頁面異常一打開就轉(zhuǎn)圈甚至系統(tǒng)重啟現(xiàn)象雙擊doc后Word一直卡在“正在修復(fù)”界面幾分鐘后進程無響應(yīng)個別老筆記本直接藍(lán)屏重啟。把文件拷到同事電腦上可能又能正常打開。原因文件在U盤拷貝或網(wǎng)盤下載過程中沒有完整寫入造成OLE2容器結(jié)構(gòu)損壞。還有一種可能是文檔里嵌入了損壞的OLE對象比如MathType公式的某個片段壞掉了Office渲染時觸發(fā)崩潰。跟宏病毒不一定有關(guān)系但體驗上像“中招了”。解決先別雙擊。用2.3節(jié)的Get-FileHash算一下文件大小和哈希如果大小只有幾十KB基本可以判斷不完整。然后用LibreOffice嘗試轉(zhuǎn)換libreoffice --headless --convert-to txt [詳細(xì)完整版]計算機訓(xùn)練題.doc能轉(zhuǎn)出txt說明文檔主體還能讀如果LibreOffice也卡住就說明容器本身壞得厲害。遇到這種情況只能找原始來源重新獲取一份。我之前整理舊題庫時遇到過一個“打開就重啟”的doc后來發(fā)現(xiàn)是某道題里嵌入了一個損壞的Excel對象用LibreOffice轉(zhuǎn)PDF繞過去才把題目看全。5.5 坑5Word自動編號導(dǎo)致復(fù)制粘貼后題目順序錯亂現(xiàn)象從訓(xùn)練題里挑選20道組成原理題復(fù)制到新文檔后所有編號從“1、”重新開始。原來題干里的“第3題”字樣不見了做Excel統(tǒng)計時匹配不上原題號。原因Word里的“編號列表”不是實實在在的文本而是一個自動編號域。復(fù)制粘貼到新文檔時如果目標(biāo)文檔的列表模板也定義了自動編號新位置會按順序重新生成。這種引用關(guān)系并不保留原來的題號語義。解決復(fù)制之前先全選CtrlA然后復(fù)制到新文檔里右鍵選“粘貼為純文本”或“只粘貼文本”。這樣自動編號會落成普通字符格式可能會亂但題號不再是“活”的。對于做題庫來說犧牲格式換取真實文本是劃算的。粘貼后跑一遍3.3節(jié)的統(tǒng)計腳本如果還能識別出“1.”和“第X題”的數(shù)量就說明題號已經(jīng)變成純文本了。別直接CtrlV否則你會在刷題后臺看到一堆“1、1、1、1”的假編號。6. 把訓(xùn)練題做成自測腳本用Python模擬考試環(huán)境并統(tǒng)計錯題把題目拆進JSON之后這份訓(xùn)練題才真正算自己的。我最常用的自測腳本不到一百行。題庫格式固定成這樣{ id: 1, tag: 組成原理, question: Cache寫回法與寫直達法的主要區(qū)別是, options: {A: 每次寫操作都更新主存, B: 只更新Cache, C: 寫操作只寫主存, D: 寫操作同時更新主存和Cache}, answer: B }然后用random.sample隨機抽20題答題后對錯題累計import json import random with open(bank.json, encodingutf-8) as f: bank json.load(f) questions random.sample(bank, 20) score 0 wrong [] for q in questions: print(q[id], q[question]) for k, v in q[options].items(): print(f {k}. {v}) ans input(你的答案: ).strip().upper() if ans q[answer]: score 1 else: wrong.append((q[id], q[answer], ans)) print(f得分: {score}/{len(questions)}) print(錯題ID:, [x[0] for x in wrong])腳本里的random.sample每次從題庫里取不同題目適合模擬考試。如果想反復(fù)刷錯題就改成只從wrong列表里選或者給每道題加一個wrong_count字段權(quán)重越高抽中概率越大。我自己的做法是當(dāng)天用這20題模擬錯題ID寫進wrong_ids.txt第二天只從這些題里再抽10道直到正確率超過90%。這樣做能明顯減少盲目重復(fù)刷整卷的時間。最后一件事是我這些年整理訓(xùn)練題最深的教訓(xùn)別貪多先入庫再刷題。早期我拿到訓(xùn)練題doc第一時間就是從頭看結(jié)果看完就忘。后來改成先把題目結(jié)構(gòu)化再按知識點歸類最后用腳本自測一份幾百題的文檔只要一個晚上就能變成可復(fù)用的刷題系統(tǒng)。如果你也常跟舊版doc文件打交道建議把這個流程固定下來安全驗貨、轉(zhuǎn)格式、拆題入庫、分類自測。希望幫到你。本文還有配套的精品資源點擊獲取