準備好的一天永遠不會到來。
當機會來到眼前時,首先要抓住它。
知識和技術可以在抓住後再獲得。這樣就沒問題了。
在這個觀念形成之前,2025年在各種意義上都是“動盪”的。
我休職、自我投資、改變環境、轉職,甚至改變居住地。
因為公司的原因而調動了。
在此時我還是覺得「努力應該會有辦法」,但回首過去,感覺從這裡開始漸漸出現了些微的偏差。
從10月到12月,我在部門的人際關係中苦惱不已。
年末年始的假期,甚至不是在休息,而是過度思考。
然後迎來了工作的開始。
2025年1月6日,工作開始的那一天,雖然走到了職場附近,但怎麼也走不出一步,於是轉身回去了。
那之後我直接去了精神科,被診斷為適應障礙。
診斷結果得出的那一瞬間,感受到的並不是安心,而是恐懼。
「接下來會怎麼樣呢?」
「如果職業停滯該怎麼辦?」
未來瞬間變得一片空白的感覺。
從那時開始只上班了一周,並在1月13日請了假。
(順便說一句,當時我已經擁有第三種電氣主任技術者(電檢三種)的資格。
但即便如此,狀況卻沒有發生改變。努力卻得不到回報的感覺,實際上是消耗我的心靈的。)
這個經驗讓我學到了三點。
其實,我從一年半前開始自學編程。
但即使學習,也看不到「能賺到錢的未來」。自己對於未來的路徑一直感到不安。
一起學習的夥伴也很少。
所以我下定決心。
「這樣回去沒什麼改變,唯有改變環境。」
於是2月,我進行了編程學校的自我投資。
如果用出行來比喻的話,
最有效的還是路線圖和夥伴。
「下步該做什麼」變得清晰,不安減少,當有夥伴一起同行時持續進步的難度下降。
第一個學校很好。
但我更想要。
在社交媒體上,看到了同樣使用一個哈希標籤發信的“熱情團體”(名字不便透露)。
那裡有許多比自己更強的人,我想「想要在這個環境中挑戰」。
8月,我在東京的一家初創公司擔任網頁工程師,並改變了居住地。
我想在現代的環境中累積實務經驗。
我知道強大的工程師會聚集在都市。
在工程師基數多的地方進行交流,建立人脈,是我所希望的。
在轉職後的幾個月裡,我從前端→後端→全端開發,目前參與AI代理人的開發。
※ 接下來將集中講述我在轉職後負責的業務中的 前端實現。
實務中我們最初所接觸的,很多是所謂的小改進。
這些小的修正看似不起眼,但卻與產品的可信度直接相關。
更重要的是,這是了解現有代碼的癖好、團隊的寫作風格、組件思想的最佳方式。
我專注於首頁的重構。
最糟糕的是 邏輯與顯示的混合(膨脹)。
首頁的代碼達到了 500~1000行,數據的獲取、整形、狀態、分支和顯示全部寫在同一個文件裡。
在這種狀態下,每當增加新功能時
結果,首頁變成了「不敢觸碰的頁面」。
本次重構中,最重要的是優先考慮 順序 而非技術選擇。
結論是這樣。
先分割顯示用的組件,再考慮分割邏輯。
如果先從邏輯開始切分,會在未看清UI整體性的情況下開始分割,
造成分割粒度不穩定,責任重疊,最終不能提高可讀性。
相反的,若先在「有意義的單位」上進行顯示分割,
依據這個順序,自然可以進入邏輯整理的階段。
首頁使用了Container / Presentation模式進行重構。
這次的方針是 按頁面來統一目錄,使責任只需靠置放位置來判斷。
首先,重構後的目錄結構如下。
features/
home/
containers/
HomeContainer.tsx
presentations/
HomePresentation.tsx
components/
HeroSection.tsx
KpiSummary.tsx
RecentUpdatesTable.tsx
hooks/
useHome.ts # ※只有在需要時(不進行過度切割)
api/
homeApi.ts # ※非必要(API調用的責任)
這樣的結構,使得即使是初見之人也能明確辨識:
接下來,C/P的關係(呼叫方向)也固定為 單向。
✅ 這裡的關鍵規則:C → P 只有這一種
❌ 不構建 P呼叫P / C呼叫C 的結構
(因為這樣會使邊界模糊,會減少分割的意義)
在這一前提下,我具體遵守的規則如下。
「是否能切割」不是關鍵,必須按照UI的整體性來進行。
與用戶作為一個整體能識別的單位相適應,將增強對變更的抵抗力。
原因很簡單,這樣的話便會導致失去分割的意義。
邊界變得模糊之後,又會回到“混雜”的狀態。
hook雖然很方便,但切割過度會導致責任分散,難以追蹤。
只有在「可重用且責任明確」的情況下才切割。
在置放位置上使責任可見。
邏輯放在containers,顯示放在presentations。消除迷惑。
如果過多地將狀態集合在上方,Container將膨脹成“神組件”。
因此,狀態應盡量靠近使用方的組件,
使Container專注於整個頁面的控制。
重構後最大的改善並非外觀,而是 可擴展性。
結果,當新增需求來臨時,
我能夠感受到「不會破壞整個頁面就能嵌入」的感覺。
由於首頁的重構大幅改變結構,「雖然外觀相同卻可能會崩潰」的風險很高。
然而當時,重構前並沒有準備足夠的測試。
結果,自己做的確認相當粗糙。
……這些過程都在地道的重複。
但手工操作難免會出現漏網之魚。
換句話說,說得不好聽「在沒有任何保障的狀態下進行」。
回想起來,這真的相當可怕。
因此,從某個時候開始,導入了一個可以攔截HTTP請求並替換回應的測試庫。
(例如:MSW(Mock Service Worker)的機制)
目標不是在「內部實現」上,而是在用戶視點下保證行為。
import { http, HttpResponse } from "msw";
export const handlers = [
http.get("/api/home", () =>
HttpResponse.json({
kpis: [{ label: "Todo", value: 3 }],
recentItems: [{ id: "1", name: "Item A", status: "open", updatedAt: "2026-01-05" }],
})
),
];
這明顯是一個失敗。
本應在後端維護的「規格的正確性」與「領域規則」,卻試圖在前端中維持,最終範圍擴大了太多。
現在我將角色分工進行如下劃分。
此次過程中我最深刻的感受就是這一點。
在重構之前,期望有一個先確保“未損壞”的測試。
當時幾乎沒有測試,我乖乖地用手工去操作和確認每一個步驟。
但手工操作仍然會出現漏網之魚。
也就是說,有著 「在沒有任何保障的恐懼」 的情況下進行。
回頭想想,真的相當可怕。
反過來說,如果可以像TDD(測試驅動開發)一樣,預先固定行為(期望值),
那麼該做的事情就會變得明確。
結果,也會更容易做出大膽的結構改變。
如果再做同等規模的改修,首先要建立最低限度的行為測試(重要導線),然後再逐步進行重構。
這是我個人得出的結論。
接下來,我將對我所全端實現的功能進行深入探討,作為案例研究。
實現的是 針對每個學校 / 每個班級的學員資訊輸出CSV的功能。
有三個要點。
此外一個重要的規範是,無論哪個UI都可以「不加篩選=契約的所有學員輸出」。
這次CSV的輸出,外觀有兩種模式。
在這裡,重要的要求是無論哪個UI都能夠「不加篩選=全件輸出」。
由於UI不相同,若硬要將其歸於一個API,
會增加查詢和分支,最終提高理解成本。
因此我決定了。
端點分成兩條,根據UI分開API。
比起“保持共通的優雅”,
優先考慮「不迷惘」「可追蹤」「可審核」會更快。
這個功能由於CSV的性質,信息洩露風險較高。
所以單靠認證(登錄)是不夠的,必須進行授權。
規範如下。
在實現中僅建立Pundit的Policy,
避免在Controller中的隨意if判斷。
在全端實現過程中,我深刻感受到這一點。
一旦在Controller中放入邏輯,維護工作就結束了。
CSV輸出容易增加要求(添加列、條件、特例處理)。
因此,我採取了不增加Controller負擔的方針。
自己的責任分割如下。
這次的輸出條件,最終整理為以下幾點。
將「全件」與「篩選」歸於同一個層面後,Service側負擔了進行控制,
使得Controller側保持輕量化。
在前端,我做了兩大部分。
不過,這裡也有一些反省。
選擇狀態和loading等太多持有在Container中,
導致Container膨脹,責任混雜。
現在我會這樣劃分。
僅遵守這一規則後,實現後的修正一下變得輕鬆了許多。
文字編碼我將其統一為 UTF-8。
但在實務中,更容易遇到的問題是檔名而非內文。
因此我採用的是,
檔名通過編碼/安全化(移除符號)確保安全形態
「用戶所需的意義(可辨識學校)」雖然保留,
但卻排除那些容易崩壞的字符。
# 例:移除符號+空白替換為_(擬似)
safe_school = sanitize_filename(school_name) # 移除符號/連續空白替換為_/長度限制等
filename = "#{Date.today.strftime('%Y%m%d')}_#{safe_school}.csv"
※ sanitize_filename 是「僅保留英數字・連字符・底線」「將空白替換為_」等,
“去除容易崩壞的字符以減少事故”的目的。
補充:相對於完全保留學校名稱,
「學校名稱(安全化)+學校ID」的形式會增添“一致性”,運營時也不容易出現問題。
做到這些,才算是“業務功能”的完成。
不清楚Pundit
→ 本質在於「聚合權限規範到Policy中」而非「寫法」
不清楚前端與後端如何連接
→ 事實是API的約定(端點/輸入/輸出/權限)
代碼基礎太龐大而迷失方向
→ 在擬定「此次觸及範圍」後,可減少迷失
完全推給AI,結果卻不會解釋
→ 比起速度,更需要「能在審核時解釋的理解」
PR的概要無法反映意圖
→ 雖然代碼可讀,但意圖不寫就不會傳達。
在這次完整的功能實現中,最大的成長在於以下幾點。
在「動作」的基礎上,應將重心轉向「可運行性」。
這樣設計出的判斷,在實務中將會是最有價值的。
目前我也參與了AI代理人的開發,但這超出了本文章的主題(2025年的環境變化與實務的學習),因此不再深入。
但這無疑將成為我下一個重大挑戰。
如果有機會,我將會將「在AI代理人開發中所學」另行整理成文章。
親愛的,致2025年1月6日的我。
首先想告訴你。
今天是你最年輕的一天。
要開始的不是明天,也不是一小時後,而是現在開始。
……但是,這樣的話你未必會覺得「那也沒辦法」。我懂。
我仍然清晰地記得那天早上的事。
在冰冷的寒風中,穿著西裝,握著冷冰冰的自行車手把,跑到了公司的附近。
一邊想著「可以的,需要去」,但身體的深處又在拒絕的感覺。
明明已經走到了工作的附近,卻怎麼也走不出一步,於是轉身回去了。
那之後我去精神科,被告知了適應障礙。
當得到這個名字的瞬間,感受到的比起安心,更是恐懼。
「接下來會怎麼樣」
「如果職業停滯會怎麼辦」
未來瞬間變得一片空白的感覺。
但是,我要先告訴你結論。
轉身回去是正確的。
並不是逃避,而是在崩潰之前停止了。
那是一次為了邁向下一步的明智選擇。
休職的事,現在我則能自信地說出來。
這並不是羞恥,而是權利。
而這段時間,不僅僅是「休息的時間」,更是改變環境的時間。
接下來,給你簡單預告一下。
你將會在隨後放棄自學,進行自我投資。
進入編程學校,遇見講師、導師、以及夥伴。
在那裡,出現了改變的瞬間。
「我無論如何也不會是一個人」的感覺,
不再只是希望,變成了無可置疑的自信,最終變為確信的瞬間。
這會讓你變得不一樣。
多次突破舒適圈。
持續給自己施加「適當的壓力」。
依靠眼前的機會,堅信著這是一個「機會」,毫不含糊地抓住。
轉職後也會貪婪地追求「自己想做的事情」,真正地做到。
還有,這是我的真心話。
關於一年半的自學期間,心中留有一絲悔恨。
「如果能早些投入自我投資,或許能更早以工程師身份啟程」。
但与此同时,自學培養的自我驅動力,確實在目前的工作中得到了體現。
提升人材價值的經驗之一毫無疑問。
但這條路——並不是推薦給每一個人的道。
你只是剛好堅持下來而已。
最後,只想留下這段話。
感謝2025年遇見的所有人。
特別是閱讀到這裡,覺得「這或許是我」或是「這或許是我」的人。
衷心感謝你們在我們的距離中和我互動,無論是我的任性還是稚嫩,都能包容我。
尤其是轉職的夥伴,我知道,真心覺得你們很厲害。
雖然這樣說不好,但卻真實存在。
但你們仍然接受我,為我提供了空間,然後培養我,真的非常感謝。
……好了,就要收尾了。
致一年前的自己。
如果此刻你在顫抖著覺得「無法回去」「無法挽回」,那我告訴你。
顫抖是可以的,害怕也可以。
但別就在這裡停下來。
今天是你最年輕的一天。
開始的不是明天,而是現在。
而正在閱讀這篇文章,正考慮挑戰的你們。
準備好的一天永遠不會到來。
如果期待不安消失後再行動,那一輩子都會是如此。
所以,選擇。
改變環境。
抓住機會。
抓住之後再學習。
沒問題。不需要完美。
就算笨拙,走出來的人會贏。
敬上。
準備好的一天永遠不會到來。
當機會來到眼前時,首先要抓住它。
知識和技術可以在抓住後再獲得。這樣就沒問題了。
讀到這裡的你,也許已經隱約意識到了。
「想要改變」「想要挑戰」「但又害怕」。
但接下來成功的,或許就是——你。
結果只有行動過的人才能知道。
光是考慮的世界,什麼事情都不會發生。真的。
再說一遍。
今天是你最年輕的一天!!
讓我們一起挑戰吧。
那麼有朝一日希望能與你享受喝酒的時光。
我其實也很想和你一起喝酒!!(笑)
未來一定會光明!!
以上,就是未來的強強工程師想對大家傳達的一切。
2026年,這一年將會是 靠實力讓別人信服的年。
要做的事情只有三件。
下次文章中,我會全方位揭露目前參與的 AI代理人開發的真實情況。
不追求“看起來厲害”,而是能夠重現的形式。
原文出處:https://qiita.com/Keita-0025/items/c0fb3bed10f49b0ed523