2022年10月23日 星期日

面試紀錄

雲海岸
---------
問get post的差異-其中有說明post在資安上是比較安全
使用 GET 的時候我們直接將要傳送的資料以 Query String(一種Key / Vaule的編碼方式)加在我們要寄送的地址( URL )後面,然後交給郵差傳送。使用 POST 的時候則是將寄送地址( URL )寫在信封上,另外將要傳送的資料寫在另一張信紙後,將信紙放到信封裡面,交給郵差傳送。
 POST 是將表單的內容放在 body 裡面,在不看封包的情況下似乎較為安全,此外在傳送檔案時會用到 multi-part 編碼,將檔案與其他表單一併放在 body 中傳送
https://medium.com/kurt/%E7%B6%B2%E9%A0%81get-%E8%88%87-post-%E5%B7%AE%E7%95%B0-%E7%A7%91%E6%99%AE%E5%A3%B9%E9%BB%9E%E9%80%9A-94cbaa666fdb

問spring IOC
主程式中所需要的輔助物件,並不是在自己的類別中建立,而是由外部控制的。建立好後,將其傳遞給主程式,這個動作稱為依賴注入(dependency injection,DI),是控制反轉的實現方式。
在Spring啟動時,這兩個類別會被建立成元件,存放在容器中。其中計算器使用了 @Autowired標記,因此框架會從容器中找出對應類別的元件,自動注入到計算器中。
一般來說,元件預設是「單例」的。意即在整個應用程式運行期間只會存在唯一一個。如此可避免產生不必要的重複物件。
Spring Boot透過容器,達到元件的控制反轉。而開發者透過用類別、介面甚至元件名稱來宣告輔助元件,讓容器得以完成依賴注入。在撰寫元件的程式碼時,我們可透過介面提供的方法來使用其他元件,以便在替換時,仍能保持一致的使用方式。而進行單元測試時,能夠自行傳遞不同屬性或實作類別的物件,提高了可測試性。
https://medium.com/chikuwa-tech-study/spring-boot%E8%88%87%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%89%E7%9A%84%E9%97%9C%E4%BF%82-ac1bd4b82ed5

在你專案中有用到什麼設計模式?
使用itext和POI的時候, 用Template樣板模式, 使其中重複用到的功能寫於抽象父類別, 而不同的generate report功能由各報表類別來實作, 合適的滿足開閉原則的要求

--------------
博彥
有考IOC AOP

AOP
AOP 的本質 — 改變程式碼的流程
以 Web Server 開發場景為例,我們經常會需要在很多 end-point API 的方法執行前先執行權限驗證,或者是在這些 end-point 執行 transaction 失敗時可以 rollback。

這些在程式碼中會重複出現,它們是重要但是不屬於我們核心業務的操作,如果要重複複製貼上到專案中的各處會造成難以維護的窘境。因此 AOP 試圖讓這些常被複用的邏輯獨立出來,用特殊的機制包裝起來,讓我們的業務邏輯不需要去看到任何相關的程式碼。

這件事本質上聽起來跟呼叫函式沒有太大的區別,然而 AOP 本質上是屬於一種 Meta Programming 。具體來說,實現 AOP 的工具處理的是程式碼本身(或 bytecode本身) 或是 class (或 object ) 的資訊,是用來改變程式碼的流程或織入( weaving ) 新的程式碼,而非只是單純地「執行一段程式」。

AOP 只是種指導編程模式的原則而已,在不同的語言和生態系中,類似的概念都有不同的實作方式,然而共通點都是藉由改變程式碼的流程讓核心邏輯不會受到額外的切面邏輯的影響。

在靜態語言中,程式的流程在編譯時期就會被寫死了,要穿插切面在程式碼各處會需要有額外的工具來支持。而在動態語言中,因為程式的流程並不是在編譯時期就被決定了,而是可以動態更改的,所以通常原生語法就支持了 AOP 功能。
https://tech-blog.cymetrics.io/posts/maxchiu/aop/



問: 有無使用TDD?

TDD(Test-Driven Development)是一種開發流程,中文是「測試驅動開發」。用一句白話形容,就是「先寫測試再開發」。先寫測試除了能確保測試程式的撰寫,還有一個好處:有助於在開發初期釐清程式介面如何設計。

程式介面,或是常說的 API 介面,是內部封裝細節和外部元件的溝通橋樑。在實作時,我們通常會希望程式介面維持穩定,越少改動越好。但在開發初期憑空定義出來的介面,常常在開發完成實際使用時才發現不好用,導致介面需要頻繁改動。

測試程式的作用是「模擬外部如何使用目標程式,驗證目標程式的行為是否符合預期」。換句話說,在寫測試時,會去了解目標程式如何被使用,比起憑空定義介面,更有助於在實作目標程式之前釐清適合的介面設計,減少後續變動的次數。

具體來說,TDD 流程可以分成五個步驟:

步驟一:選定一個功能,新增測試案例

  • 重點在於思考希望怎麼去使用目標程式,定義出更容易呼叫的 API 介面。
  • 這個步驟會寫好測試案例的程式,同時決定產品程式的 API 介面。
  • 但尚未實作 API 實際內容

步驟二:執行測試,得到 Failed(紅燈)

  • 由於還沒撰寫 API 實際內容,執行測試的結果自然是 failed。
  • 確保測試程式可執行,沒有語法錯誤等等。

步驟三:實作「夠用」的產品程式

  • 這個階段力求快速實作出功能邏輯,用「最低限度」通過測試案例即可。
  • 不求將程式碼優化一步到位。

步驟四:再次執行測試,得到 Passed(綠燈)

  • 確保產品程式的功能邏輯已經正確地得到實作。
  • 到此步驟,將完成一個可運作且正確的程式版本,包含產品程式和測試程式。

步驟五:重構程式

  • 優化程式碼,包含產品程式和測試程式(測試程式也是專案需維護的一部份)。
  • 提升程式的可讀性、可維護性、擴充性。
  • 同時確保每次修改後,執行測試皆能通過。

每個功能重複上述步驟,就是 TDD 的開發流程。

https://tw.alphacamp.co/blog/tdd-test-driven-development-example


問 Java 8 特性

https://www.796t.com/p/570214.html

https://blog.51cto.com/u_15236724/5368640


---------
匯誠
Array和List差異
Array需要先宣告陣列的大小,且是固定的無法再做更動,元素可透過"陣列名[索引index]=元素內容;"來進行新增的動作,再之後陣列名[索引index]就保有資料了,而常見的array型態也包括String型態。
ArrayList的大小可以變化,透過add來將元素新增至列表的末端,目前已有三筆資料(a、b、ccc),接著就看到其他常用的方法。
List是有序集合,是ArrayList的一個介面,但是只能夠使用List包含的方法,且不能實例化(Object),其他大部分都與ArrayList相像。

2022年9月12日 星期一

Big O

Overview

Big O help us find out how well the problem is solved.

We use it to distinguish that code from good code, good code from great code.

->great developer

What is good code?

1. Readable

2. Scalable

Big O allow us to measure the idea of scalable code.

How can we make sure that there is a way for us to measure in terms of efficiency, what is good code, 

what is bad code, and what is code that can scale that as the number of arrays or inputs increases, 

it doesn't constantly slow down more and more.

We can compare it to different algorithms or in this case, function using big O and say which one is better than the other when it comes to scale. Regardless of our computer differences.

When we talk about Big O and scalability of code, we simply mean when we grow bigger and bigger with inputs, how much does the algorithm or functions slow down.

When the Elements increase, the number of operations increased over and over. Some increase much, some doesn't increase much.

Instead of using performance and using time to measure the efficiency of our function, we can just calculate how many operations a computer has to perform because each operation takes time on a computer.

O(n)









The picture describes that 4 item in an array.

We do the asking loop "is it the nemo ?" 4 times 4 operations


As the items increased, the operation increased.

This is linear. We can say this findNemo notation O(n).


As the item increased, we find the time scaled.

O(1)


This is O(1), what we called constant time.

It is how many items in boxes, we just grasping the first item in the array.


The number of operations just stay flat.

function funChallenge(input) {
  let a = 10; //O(1)
  a = 50 + 3; //O(1)

  for (let i = 0; i < input.length; i++) {
    anotherFunction(); //O(n)
    let stranger = true; //O(n)
    a++; //O(n)
  }
  return a; //O(1)
}

We can calculate the function which is BIG O(3+3n).
It can be simplify as O(n).

function anotherFunChallenge(input) {
  let a = 5;//O(1)
  let b = 10;//O(1)
  let c = 50;//O(1)
  for (let i = 0; i < input; i++) {
    let x = i + 1; //O(n)
    let y = i + 2; //O(n)
    let z = i + 3; //O(n)

  }
  for (let j = 0; j < input; j++) {
    let p = j * 2; //O(n)
    let q = j * 2; //O(n)
  }
  let whoAmI = "I don't know";//O(1)
}
BIG O(4+5n).-> O(n)
How to simplify? 4 rules

Rule 1: Worst Case

If the worst case happen, we just need to run all the case of it.
However, we can add break when the function find the target.
The effort time will decrease.
We can know that in the following situation.
It may be O(1), O(4) for us to find the nemo.
The worst situation is O(n).
















Rule 2: Remove Constants

O(n+1), O(n+10000) -> O(n)
Because we consider the scale, we omit the constants.
On the other example,
We don't really care about how steep the line is.
O(2n), O(n/1000) -> O(n)
We care about how the line moves as our inputs increase.

Rule 3: Different terms for inputs

When the function has two different arrays of inputs,
we say O of A plus B.











When the loops were actually nested and they are not one after another,
the big O is A times B.










Rule 4: Drop Non Dominants












if we call the function > printAllNumbersThenAllPairSums([1,2,3,4,5]),
the Big O will be O(n+n^2).
The n will be drop due to the insignificance in the function.
Hence, it the Big O should be O(n^2). It is quadratic.

2022年8月4日 星期四

swarm intelligence 群體智慧- 托福 聽力46-2 部分內容

Swarm intelligence is a collective behavior that emerges from a group of animals, like a colony of termites, a school of fish, or a flock of birds.

群體智能是一群動物的集體行為,如白蟻群、魚群或鳥群。

Let's first consider the principles behind swarm intelligence, and we'll use the ant as our model.

Now, an ant on its own is not that smart. When you have a group of ants, however, there you have efficiency in action.

You see, there's no leader running an ant colony.

讓我們首先考慮群體智能背後的原理,我們將使用螞蟻作為我們的模型。

現在,一隻螞蟻本身並不那麼聰明。 然而,當你有一群螞蟻時,你就有了行動的效率。你看,沒有領導者管理蟻群。

Each individual, each individual ant operates by instinctively following a simple set of rules when foraging for food.

Rule number 1: Deposit a chemical marker... called a pheromone. And rule 2: Follow the strongest pheromone path.

The strongest pheromone path is advantageous to ants seeking food.

So, for example, when ants leave the nest, they deposit a pheromone trail along the route they take.

If they find food, they return to the nest on the same path and the pheromone trail gets stronger—it's doubled in strength.

Because an ant that took a shorter path returns first, its pheromone trail is stronger, and other ants will follow it, according to rule 2.

And as more ants travel that path, the pheromone trail gets even stronger.

每個個體,每個個體的螞蟻在覓食時都本能地遵循一套簡單的規則。規則 1:存放一種化學標記物……稱為信息素。 規則 2:遵循最強的信息素路徑。最強的信息素路徑有利於螞蟻尋找食物。因此,例如,當螞蟻離開巢穴時,它們會沿著它們所走的路線放置一條信息素軌跡。如果它們找到食物,它們會沿著同一條路徑返回巢穴,並且信息素痕跡會變得更強——它的強度會增加一倍。因為根據規則 2,走較短路徑的螞蟻首先返回,它的信息素軌跡更強,其他螞蟻會跟隨它。隨著越來越多的螞蟻在這條路上旅行,信息素的踪跡變得更加強大。

So, what's happening here?

Each ant follows two very basic rules, and each ant acts on information it finds in its immediate local environment.

And it's important to note: Even though none of the individual ants is aware of the bigger plan, they collectively choose the shortest path between the nest and a food source because it's the most reinforced path.

By the way, a-a few of you have asked me about the relevance of what we're studying to everyday life.

And swarm intelligence offers several good examples of how concepts in biology can be applied to other fields.

Well, businesses have been able to use this approach of following simple rules when designing complex systems, for instance, in telephone networks.

When a call is placed from one city to another, it has to connect through a number of nodes along the way.

那麼,這裡發生了什麼?

每隻螞蟻都遵循兩條非常基本的規則,每隻螞蟻都根據在其直接本地環境中找到的信息採取行動。重要的是要注意:即使沒有一隻螞蟻知道更大的計劃,它們也會集體選擇巢穴和食物來源之間的最短路徑,因為它是最堅固的路徑。順便說一句,你們中的一些人問過我我們正在學習的內容與日常生活的相關性。群體智能提供了幾個很好的例子,說明生物學中的概念如何應用於其他領域。好吧,在設計複雜系統時,例如在電話網絡中,企業已經能夠使用這種遵循簡單規則的方法。當從一個城市向另一個城市撥打電話時,它必須通過沿途的多個節點進行連接。

At each point, a decision has to be made: Which direction does the call go from here?

Well, a computer program was developed to answer this question based on rules that are similar to the ones that ants use to find food.

Remember, individual ants deposit pheromones, and they follow the path that is most reinforced.

Now, in the phone network, a computer monitors the connection speed of each path, and identifies the paths that are currently the fastest—the least crowded parts of the network.

And this information, converted into a numeric code, is deposited at the network nodes.

This reinforces the paths that are least crowded at the moment.

The rule the telephone network follows is to always select the path that is most reinforced.

So, similar to the ant's behavior, at each intermediate node, the call follows the path that is most reinforced.

This leads to an outcome which is beneficial to the network as a whole, and calls get through faster.

在每一點上,都必須做出決定:呼叫從這裡往哪個方向進行?

嗯,開發了一個計算機程序來回答這個問題,其規則類似於螞蟻用來尋找食物的規則。請記住,個體螞蟻會沉積信息素,它們會遵循最強化的路徑。現在,在電話網絡中,計算機監控每條路徑的連接速度,並識別當前最快的路徑——網絡中最不擁擠的部分。這些信息,轉換成數字代碼,存放在網絡節點上。這加強了目前最不擁擠的路徑。電話網絡遵循的規則是始終選擇最強化的路徑。因此,類似於螞蟻的行為,在每個中間節點,調用遵循最強化的路徑。這導致對整個網絡有利的結果,並且呼叫更快地通過。

2022年4月10日 星期日

[超速學習讀書筆記] 第五章 法則2: 專心致志-把刀磨利

 開頭作者用一個科學家的故事"瑪莉, 薩莫維爾", 來說明學習可透過短時間專心而達到成效, 那個時代女人要學習是相對於男人難的多, 因為普遍社會對女性只期待家務, 而並不重視女性教育, 而她除了精通數學, 會流利的說幾門外語,也懂畫畫跟鋼琴,是她將拉普拉絲的天體力學翻譯並加以延伸, 自幼她培養專注力, 來自於當大人不准她睡覺的時候, 她在腦子中反覆讀歐幾里得的數學著作, 她在照顧孩子期間每早研讀一小時的植物學, 而她翻譯及延伸天體力學同時, 都是的完成照顧小孩還有家務相關忙碌的事, 甚至有時朋友會從遠方來看她, 她就建立一種學習習慣, 就是間斷一段時間回來能夠快速的找到她學習的主題,而人們之所以會遇到學習的困難, 作者列出以下三種原因

1無法開始

2無法維持

3無法做到真正的專注

問題一: 無法開始專注(拖延)

簡單的說~就是你沒做應該做的事, 反而做別的事或是偷懶, 作者指出一些拖延原因, 可能來自於我們對於做那件事本身有厭惡, 也有可能更喜歡做其他(分心)的事, 因此, 要克服他第一步, 就是承認自己在拖延, 這方面是因為, 有很多拖延的時候, 你覺得你在"休必要的假", 或"玩樂是必要的休閒",但事實就是~你不願意去做, 你需要承認你正在拖延

接下來, 你可以去做的是, 覺察你現在做的狀態, 然後同時給自己一個支撐的力量, 因為當你知道你開始進行正事後, 就會像輪子轉動, 只需要一點點力氣就能維持旋轉, 但是你需要一個開始的力量, 找到那個只要一點點力量就可以讓你開始working的說服自己開始從事該事情, 會是一個好解法

而在中間, 你可能遇到, 每次開始都堅持個三五分鐘, 然後就開始偷懶, 這有一部分是, 你並沒有給自己設定一個休息區間, 比方說, 我只要寫完這一個大題, 我就可以去休息, 我只要背完上面幾個單字, 我就休閒一下,這些都是讓自己專心堅持更久時間的小方法, 最後, 透過合適的時間表安排, 找出空嫌時間來利用, 可以使你對學習項目的專注度, 有正確的規劃, 雖然無法避免想偷懶的感覺, 但是掌握練習, 可以使你能面對這些影響力

問題二: 無法持續專注(分心)

作者提出, 持續在一個事情上學習, 可以注意一個概念"心流", 就是一種專注的理想範本, 不會被惱人念頭打擾, 然後完全讓自己進入到手邊工作的狀態, 雖然超速學習和刻意練習, 可能是進行一種很有挑戰的做法, 就是挑戰學困難事情, 但是其中, 其實當你在穩定進行的時候, 你已經不知不覺的啟動心流狀態, 並且, 其實當你強化學習, 熬過一段時間, 只要有維持高強度學習, 就不會有落空, 難熬是因為不確定有沒有成果, 但是當你知道這些做的不論是什麼, 都是學習上的投資, 會有回收的效益, 你的心情就會輕鬆許多

另外一方面, 其實本身要長時間專注一個主題, 是不容易的事情, 但是如果同時有幾個可以交替學習的項目, 這樣交叉輪流練習無疑會提升學習效果(我可以試試英文和程式交叉學習), 而這部分到底怎麼分配, 還是來自於個人習慣, 你要觀察自己如何能達到效率最大化, 假設你已經某種程度找到自己的最適點, 可以注意一下以下提出三個分心來源

分心來源1:你的環境

是吵雜會令你分心, 是否有手機或是可以看電視玩遊戲? 是有背景音比較讓你好做事, 還是完全安靜空間? 在你開始學習的時候, 把些分心的來源避開是需要的, 另外, 了解自己最佳學習環境先準備好, 可以幫助專注

分心來源2:你的學習任務

比方說"閱讀"其實比看影片還難專注, 當你進行這個項目, 你可以修改一下做的事情, 讓自己專注提升, 比方說學習寫下自己重新解釋困難概念的筆記, 防止假讀書(只做讀書動作, 而心已經飄到其他事情上), 而如果是要解決問題, 製造出某個東西, 其實相對來說是比較不容易分心的項目

分心來源3:你的心

負面情緒, 焦躁不安, 做白日夢, 都可能是專注的最大障礙, 這些非常有可能干擾你的學習, 有可能是負面思考, 覺得自己正在一條錯誤的人生道路上, 或是就是拿情緒沒責, 也有可能對未來的擔憂感, 這種時候, 最好的方式就是意識到它的存在, 感受自己的感覺, 然後慢慢將焦點轉移到自己的工作上, 負面焦慮憂慮, 就會比較容易過去, 雖然說還比較容易, 但是當你有負面感覺的時候, 適時的給自己一點空間recover, 然後在把焦點放到該專注的事情上, 會比一直強迫自己還好, 不要用壓抑來面對自己負面的情緒, 經過時間的練習, 的確可以幫助自己回到專注的事情上

問題三: 無法做到真正的專注

這部分作者提出了興奮感來補充, 想睡覺時興奮感是低的, 運動時興奮感是高的, 當興奮感過高, 專注力會開始受損, 而最好的事, 有一點興奮感的進行學習, 另外可能面對大量單純的工作時, 反而使用一些噪音來增加興奮感會表現更佳, 但是這一部分就是因人而異, 有可能吵雜的咖啡廳提升了你的學習效果, 也有可能在圖書館這樣安全的空間能使你專注收穫最大化, 這部分可以自我測試看看

結尾

小處著手, 大大提升你的專注力

專注力並不是少數人的例子, 你可以透過一系列的流程來提升自己的專注力, 作者建議: 承認你所處的狀態, 然後從小處著手

有的人一分鐘坐不住, 嘗試讓它變成兩分鐘, 嘗試解決自己分心的問題, 然後逐漸拉長能專注時間, 讓自己的學習品質提升, 本章討論了如何開始學習困難事物, 下面進一步討論學習的正確方法: 直截了當, 能解釋你學習應該先開始作哪一類的事, 以及更重要的, 若你希望盡快運用所學, 哪些是你應該避免

2022年4月5日 星期二

後設學習 ex 托福

a 為什麼?

兩方面都是

功能性

1 為找工作: 因為有些國外公司應聘的時候會看, 也是可以作為語文能力的一個補充證明

簡單有力說出自己是可以進行全英文工作

2 為技術提升: 因為外語資源多, 如果掌握短時間精進英文能力, 對於短時間學習外語資源會有所幫助, 特別是考托福中, 作即時課堂筆記也會是考試內容之一, 筆記越完全相對來說答題較容易高分, 可以整體提升外語學技術的能力

3 為了教英文: 這部分純粹是教英文可以多一個證明, 說明我自己有足夠實力去家教英文

4 為了留學: 這部分雖然沒打算, 但是說不定未來還是有進修空間, 或是再讀一個國外研究所會有幫助

本質性: 

1說外語感覺優美, 喜歡聲調好聽

2外語好感覺就很聰明, 頭腦也動比較快


b 做什麼?

1 了解四個項目出題運作, 整體結構, 比方說出題文章結構, 寫作時範文架構

目前透過Utube, 可能會買書補強自己較弱部分(4/5本周需要先裸考一次, 先考再買書)

2 需要背單字, 有下載黑書 高頻, 可以用單字黃書, 從菁英網上閱讀資源中找單字來背

a 練習發音, 從每次朗讀課件來練習, 並錄音起來, 每次進行下面一段落, 先回放記憶, 再進行

b 練習寫作, 本周先進入寫作課程, 然後在下一周開始每周都寫作文 4/12, 4/19, 4/26, 5/3, 5/10, 5/24

c 剩下的模考會有5次 5/11, 5/18, 5/25, 6/1, 6/8 差不多在一個月後, 可以檢視一下提升多少

d 線上課程之外買書進行的部分


c 如何做?

使用udemy課程每日2小時, 使用菁英線上資源, 每日1小時, 小黃書1小時, 早上和下午各30分鐘複習+背

參考utube介紹準備方式

https://www.youtube.com/channel/UCa5oulemRwjN3zEVHWPJuUg




2022年4月3日 星期日

[超速學習讀書筆記] 第四章 法則1: 後設學習-先畫一張學習地圖

 如果說我看得比別人遠, 那是因為我站在巨人肩上

一開始作者舉了一個 丹 學語言的例子, 只花了30分鐘, 由一個母語者說單一字詞, 學習者評判斷, 模仿和記憶, 完全能開口說新語言, 他如何快速學會單字文法, 及發音? 來自於第一法則, 後設學習

後設學習, 簡單的說, 就是學習關於學習這件事,接下來作者舉了中文例子, 藉由知道部首如何組成, 而去學習該字詞意思, 是一種學習如何學習, 而他的學習法是來自多年的學語文經驗, 透過一系列物品和動作認識, 而自行理出該語文樣貌

後設學習地圖的力量

後設學習是一種幫助你學習新事物時, 可以更快, 更有效, 看出該科目如何運作, 以及需要精通什麼技能使之更有效地辦到, 這是超速學習計畫的成功關鍵, 以求達到知曉目的地而不會迷路

接下來作者舉了學語文兩個和三個的比較, 成果是學雙語者明顯優於單語者,原因是有其相似文字與文法特徵, 所謂的後設語言意識, 就是藉由已知道的語文特徵, 對於新語言的運作機制提升理解上的幫助

要如何畫出你的學習地圖?

短期而言可以針對提升後設學習能力深入研究, 這是一種高強度且自主的本質, 而使之比正規教育學得更快, 比方說短期程式班, 可以幫助比大學學位更快找到工作, 這是因為你可以針對個人所需要能力, 量身訂做你的學習計畫, 不過, 也是有做出不智選擇得到更糟的風險, 為了降低風險, 花些力氣做學習的研究, 找出可以突破現狀的學習訣竅是有幫助的

長期而言, 你應用範圍更大, 因為知曉自己能力, 可以做最佳的時間管理, 也會有有效的策略, 並且學的事情越多, 越有自信, 且享受學習過程

本篇強調短期的研究策略, 原因是長期可從短期疊代出來, 只要一層一層短期累積使用超速學習方式, 熟練運用就可

決定為什麼, 做什麼, 以及怎麼做

這是計畫一開始, 拆解後設學習的好方式

為什麼? 指的是了解學習動機

做什麼? 是你需要取得什麼知識與能力, 把事情拆解成概念, 事實和程序

怎麼做? 指的是你學習時使用的資源 環境 與方法


a 為什麼?

可以拆為功能性及本質性

功能性: 簡單的說, 並不是出於熱誠, 而是為了達到某種有利的成果而學

本質性: 簡單的說, 不帶有其他目的, 純粹為其本質而學

若是計畫屬於功能性, 後設學習的評估就更重要, 需要特別去評估此學習是否達到你想要的有利結果, 比方說讀研究所是否對找工作有幫助?

深入研究的好方法: 專家訪談法

做此研究, 最好跟已經達到你所欲達成目標的人聊一聊, 並且找專家, 並不會困難, 寫封郵件就可以了, 把重點列出來, 簡單說明為何要跟對方聯絡, 並請對方給予15分鐘的對話, 有些專家還是很樂意協助, 這些事情可以避免你花了大把的時間卻學習不重要的事


b 做什麼?

可以在紙上寫下以下三個標題

1概念: 寫下所需要了解的事情, 運作的原則, 也可當作理論

2事實: 寫下需要背的東西, 不需要太深入, 只需要記得, 或是公式類

3程序: 寫下一切需要練習的事, 比方說發音, 不是概念, 也不用背, 只需要重複念

因此, 比方說學醫學需要大量記憶, 你可能要買一套間隔性複習的學習軟體

比方說你要學數學, 你可能要花時間去練習解釋概念, 讓自己真正理解, 藉此來選擇相對正確的工具來幫你達到目標,通常粗略分析就可以到達下一段, 隨著經驗增多, 可以挖更深, 找尋有效學習方法, 隨著一段時間學習, 可以再重新檢視或改正作的方式, 使之成為長期後設學習


c 如何做?

建議兩種方式1 標竿法 2強調排除法

1 標竿法: 簡單的說, 就是找出人們共同學習此項目的方式, 有可能是google該項目的學習課綱, 也有可能採用直接專家訪問法, 此時可以避免學習找錯方向

2 強調排除法: 簡單的說, 比較出其中重要, 或是相對不重要的事情, 將重心放在相對重要的項目上, 比方說要會寫程式, 學習程式開發內部運作重要性明顯大於運算理論


應該要做多少計畫?

首先計畫不是全面, 能開始施力, 就可以試試看, 避免自己拖延研究當學習的藉口

時間上的衡量, 作者是認為百分之十是不錯, 大概十天的進修, 花上一天來規劃, 那麼兩個月的進修, 花上一周來弄清楚是可以的

另外一個可參考的點就是邊際效應遞減, 就是你多花一些時間研究, 到底能不能反應在學習上, 可能一開始花時間在後設學習是有很大幫助, 但是隨著研究已經到一段落, 其實直接學習的效益會比再研究下去還大, 這時就趕緊開始學習才是對自己比較有效益

目前提的都是短期效益, 但是回過頭來, 每次後設學習,都有機會提供你新的學習方法, 蒐集資源的新方式, 以及更好的時間管理, 也可以理一理你的學習動機

每次的成功也會帶給你信心, 這些只能靠親身經驗取得, 作者表示, 有許多人藉由後設學習, 去了解到學習自身覺得困難事物的方法, 帶給他們信心, 並去追求之前從未想過的遠大目標, 然而後設學習, 仍然是為了達到學習效率而做的, 切勿本末倒置而變為研究專家, 而目標遲遲未動工

了解這些後可以進到下個超速學習法則: 專心致志

2022年4月2日 星期六

[超速學習讀書筆記] 第三章 如何成為超速學習者?

 本篇使用一個自願參加超速學習白老鼠計畫的實例揭開對於此方法練習的成果實測

蒙特貝洛是一個音樂家兼企業家, 除了他之外, 還有大約10多人的小組, 大部分是作者的部落格讀者,

一開始他決定要以學習鋼琴為目標, 但是考量他原本就會鋼琴, 也擔任樂團主唱, 這樣的挑戰顯然不具有觀察計畫可行性, 而在他思考後, 決定挑戰公開演說, 其中他之前的演說經驗可以說是頗糟糕,

大部分的時候, 聽者都覺得無聊, 當他說些笑話時, 卻沒有人笑, 而公開演說, 其實是一項綜合技能, 具有培養自信, 說故事, 寫作, 創意, 訪談, 銷售技巧, 涉及好多不同領域

他一開始著手, 是從國際演講協會聚會開始, 他說服了一位資深演說家, 來當作指導協助蒙特貝洛, 完成計畫, 而同時也報名了世界演講冠軍賽, 直到上台, 只剩下一個星期, 因此他全力以赴, 再之後一周完成六場的資格淘汰賽, 當他練習的時候, 有時一天就有兩場比賽, 而他把每場演講都錄下來反覆分析可以改進的地方, 每次演講完他都會詢問其他人意見, 也得到回饋, 教練也提供一些建議, 給他做選擇, 而他總是選對他比較困難的, 因此學習幅度較大,同時, 他也去上即興表達課, 也詢問一位導演朋友的意見, 對方建議他用各種風格來練習演講稿, 比方說, 憤怒, 嘶吼, 饒舌等方式, 這些方法幫助他破除了演講時不自然的情緒

又藉由另外一位舞台劇背景的朋友指導下, 懂得如何表達姿體語言, 他也挑戰和中學生演講, 來挑戰和聽眾能有好的互動,藉由各種不同的練習下, 一個月後, 他在所參加的地方會賽勝出, 打敗了有二十年經驗的對手, 最後也贏得區賽與部賽, 最終他挺進了決賽前十名

後來聽說蒙特貝洛成功的朋友們, 開始紛紛來訊問其如何達到速學的方式, 並有願意出學費來學習的人, 而蒙特貝洛和其指導老師嗅到此商機, 便以此開辦了公司名為超速演說

然而其他一同測試者, 不一定有這麼幸運, 有些人遇到挫折放棄了, 而也有些人則是在各領域中進步著, 即使成果沒這麼顯著, 但是經過一段時間仍能完成一項新技能培養, 蒙特貝洛成功, 來自於他在其中不斷嘗試自己極限可以走多遠

這故事也說明了, 每個人都有可能有他獨特的學習方式, 超速學習可以視為一種高強度的自我演化學習機制, 在於了解運作, 拆解, 簡化, 並快速解決問題並反覆練習, 本書提出了九項法則, 並描繪如何實踐其法則, 作者是參考了參加學習計畫的觀察, 並且個人的經驗, 從不同的方法中, 整理出一些通則, 並將通則與科學文獻比對, 看是否有實驗支持此論點

這九項分別是

1: 後設學習: 先畫一張學習地圖

開始先學習如何來學習該主題, 並做好研究, 並設想如何利用過去能力讓學習新技能簡單化

2: 專心致志: 把刀磨利

培養專注的能力, 始之在學習時能騰出更多時間, 更容易放手去做

3: 直截了當: 走最短的路, 勇往直前

透過實際去做你想擅長的事來學習, 而不是用其他比較方便的或舒服的方式代替

4: 反覆操練: 直擊你最大弱點

要堅決改善你最大弱點, 把複雜的技能拆解成一個個小部分, 然後精通每一部分再組合起來

5: 提取記憶: 用測驗來學習

測驗不僅是評估, 也可以創造知識, 主動去詢問自己知識點, 藉此驗證自己是否學會

6: 意見回饋: 別躲避重拳

回饋是嚴厲, 不舒服的, 要懂得如何利用他, 從回饋中提出自己可以加強, 或是忽略的部分

7: 保留記憶: 別往有漏洞的桶子倒水

要了解你忘記什麼與為何忘記, 要學習不只現在記得, 要永遠記得

8: 培養直覺: 先深掘, 再累積

透過遊戲及對概念或技能探索來培養直覺, 去理解是如何發生, 而不是硬背下來

9: 勇於實驗: 往舒適圈外探索

除了本來遵循的法則之外, 另外探索其他人沒走過的道路或方法, 探索其學習可能性


在原則之上, 最重要的是一種為自己學習負起責任的精神, 就是你想要學什麼, 怎麼學, 成為怎樣一個人, 全都由你自己來學定, 你來掌握全局, 也是對你做出的成果負責, 可以視上面的原則為彈性的方針, 並且這部分, 你必須親自試驗出合適自己的一套超速學習方式

這樣我們可以進到下一章後設學習


[超速學習讀書筆記] 第二章 超速學習為何重要?

超速學習: 一種獲取技能與知識的策略, 兼具自主性與高強度

超速學習是一種自主學習, 屬於自己教導自己, 此主導者是在自己, 一般超速學習者都會採取特殊步驟, 來達到最高學習效率, 例如嘗試說剛學新語言, 有系統操練千萬個益智題目, 反覆練習直至完美, 大多不是玩票性質, 而高強度學習使你完全投入, 而失去時間感, 深刻且有效地學習事物是永遠最優先考量

你應該學習超速學習理由

1 為了工作

你已經耗費大量時間在工作上, 難以投入更多時間去全面學習, 因此暫小時間的學習投資壓力較小, 無論快速轉換跑道, 接受新挑戰, 都是有利的工具

2 為了個人生活

多少人夢想彈奏樂器, 精通外語, 成為廚師, 作家, 攝影師

超速學習為你提供一條道路, 克服你的自身限制,帶來人生滿足感

經濟因素: 再見, 平庸世代

簡單的說工作分為兩級, 要馬向上, 要馬向下, 中間級越來越少, 而, 要在兩級中走到上層階級, 有基本的教育, 每天努力工作已不足以讓你成功, 取而代之, 你必須前進到不段學習的高技能組, 否則會被列為底層低技能組

教育因素: 學費太貴

高等教育學費太貴, 在學校要完成職涯上所需技能, 還有段差距, 勢必要花而外時間去採取一些課程, 更重要的是, 專業人士在工作中仍有學習新科目並新技能的需求

科技因素: 學習的新領域

資訊傳遞變為方便, 任何人都可以取得最優秀學校的免費課程, 而善用這些技術, 也隨之帶來新的學習方法可去利用

超速學習的三大幫助

1加快原有工作的發展-蔻比, 善用超速學習 學文案, 使寫文案速度上升

2轉換工作跑道-維沙爾, 轉職成為人工智慧研究者

3在充滿競爭的世界裡培養出隱藏優勢-擔任圖書館員, 兼有學會統計及資料視覺化能力

超速學習最可貴的一點-完成夢想

巴隆製作出夢想的電玩

克雷格喜愛金頭腦節目並夢想打破難關

路易斯熱愛旅行喜歡跟各國人交流

超越學習是當你挑戰困難的事而有所提升, 藉此帶給你信心, 開拓視野, 看見之前看不見的事

重要的是你學到什麼, 成為怎樣的人

關於天賦

似乎也有些人與生俱來學習能力, 是一般人無法達到

但是與其說是基因決定智力, 不如說他們的基因使他們用了更有效率的方式去學習

假設這種有效率的方是一般人也可學, 那麼天才就並非不可複製

本書採取說故事方式, 並不打算凸顯出天賦者, 而想讓讀者了解,一般人也可以做到


超速學習可以用一個短的時間達到, 即使是分散, 只要進入高強度狀況, 並使用正確的策略即可

另外, 如果是利用暫時失業, 或是轉換跑道, 這樣進行也是不錯的

最後一種就是你已經有在進行學習, 或是進修, 只要把超速學習的原則融入到你進修的時間中就好

重要的是對有效學習的熱切, 進取心, 承諾, 而非時間表的細項

參考: 超速學習

[超速學習讀書筆記] 第一章 你能在不上MIT的情況下, 學會MIT的某套課程嗎?

 一開始場景是作者正在準備期末考複習, 看著筆記, 用自問自答, 回想上課學過內容, 以增強記憶

>複雜的方程式, 抽象的概念, 困難的證明

主因是, 作者覺得入錯科系, 想重新學習一套課程, 同時發現MIT課程, 而開始想挑戰, 並認為, 短期快速精通某行業知識與技能, 這樣的學習技術是否可行

而他想開始的計畫取決於一個愛爾蘭朋友, 三個月能說出一口流利外語, 這個朋友短期待在一個地方三個月, 然後就將該語言學習得非常流利,包含西班牙語, 義大利噢, 蘇格蘭語, 法語, 葡萄牙語, 還有德語

另一個例子是羅傑. 克雷格, 參加一個類似金頭腦的節目, 並用文本分析軟體技術, 來鍛鍊自己熟悉各樣題目, 分析強項弱項, 並分析考題趨勢, 並找出出題模式, 答完所有題目

一個軟體設計的朋友, 巴隆, 因為喜歡一款遊戲, 並感覺可以做得更好, 便獨自一人做開發遊戲的計畫, 憑著熱愛, 甚至學習畫畫, 音樂, 遊戲製作的各項目一一精通, 若是遇到困難, 就拆解, 然後增強練習, 最後以其開發的遊戲"星霧谷物語", 成為百萬富翁, 是一個對夢想全力以赴的例子

而作者的經驗, 用不到一年時間學完MIT課程並達成各科考試通過, 始於一種自己計畫, 挑戰, 並取得成果, 作者認為短時間精通, 的確是一個可行的事, 接著他嘗試了朋友多語的挑戰, 一年的時間去精通了四國語言, 另外他又花了一個月的時間去學習素描, 發現的確有其捷徑

而這些例子中存在一些共通的脈絡, 是一種追求極致, 自主性的學習計畫, 都是利用類似的戰術來達到成果,而作者所遇過的學習者, 各有各的特性, 而相同的特性, 就是會連續對一個項目幹個幾個月, 並用特有學習法, 比方說交叉練習法, 榨時卡門檻, 或是關鍵字記憶法, 共通的是他們都在乎學習, 有內在強烈動機去處理高強度計畫, 即使要犧牲工作資歷或是規律生活

雖然超速學習並不簡單, 過程也令人沮喪, 但是所成就成果, 會讓一切努力都值得

讓我們花些時間了解超速學習, 了解這一切背後的法則, 了解超速學習者如何藉此學得更快更好

參考: 超速學習


2022年3月31日 星期四

React打包排除

當React資料夾, 放在SpringBoot專案下面的時候

他在run Maven install的時候

整包會被複製到Target中

這樣整個操作過程會相當緩慢

如果要避免這個複製的動作可以在pom檔中build加入以下






<resources>

<resource>

<directory>src/main/resources</directory>

<excludes>

<exclude>react/**</exclude>

</excludes>

</resource>

</resources>

2022年3月24日 星期四

table 去邊框 + 組合

 這次的需求是寄出信件,

但是信件內容是html組成如下







一開始覺得麻煩, 乾脆都弄表格的

因為不知道去邊框怎麼弄成這種格式

後來有想法

只要都只留下橫線的部分,  另外把外框去掉, 就可以形成外面的部分

另外, 中間就再弄個3X3 table出來就好了

去外框可以用 frame=void

都使用橫線可以用 rules=rows

<html> 
<head> <title> TABLE 範例程式 </title> </head>
<body> 
<table BORDER="5"WIDTH="680" frame=void rules=rows> 
<tr></tr> 
<tr><td COLSPAN="8" align="center">雲端腎臟病照顧平台訊息通知[庫存量]</tr> 
<tr><td COLSPAN="6">訊息來源<td COLSPAN="4">[台北透析診所]雲端腎臟病照顧平台</tr> <tr> <td COLSPAN="8">
<p>訊息內容</p>
 <table border=4 align=center width=80% cellspacing=5 cellpadding=6 rules=none frame=void> 
<tr> <td>商品代號</td> <td>品項名稱</td> <td>目前庫存量</td> </tr> 
<tr><td>12345678</td><td>安全穿刺針17G</td><td>10</td></tr> 
</table> 
<p>本信件為系統自動寄出,請勿直接回覆</p> 
</td></tr> 
<tr></tr> 
</table> 
</body> 
</html>

結果








參考
https://www.twblogs.net/a/5b7f41f82b717767c6aea0a3
https://blog.csdn.net/tobebetterprogrammer/article/details/52527441
https://www.w3schools.com/html/html_tables.asp
http://mirlab.org/jang/books/html/table.asp?title=3-2%20%AA%ED%AE%E6%20(Tables)
https://www.itread01.com/content/1549340291.html

2022年3月10日 星期四

timestamp 查詢某月份資料

這裡timestamp和timestamp with time zone都可以處理

Select * From patient_examine_order where to_char(sampling_date, 'YYYYMM') like '202102%'

可以使用to_char再搭配like組字做使用

超難的阿~~

https://www.postgresql.org/docs/9.6/functions-formatting.html

2022年3月9日 星期三

想把興趣當工作? 何不反過來看

https://www.gvm.com.tw/article/73791

整篇圍繞著興趣不能當工作, 及為何興趣不能當工作在走

凸顯各種, 不能....因為....

這種思維是不會使一個人進步的


何不反過來看

為何不能把工作當興趣?

工作真的不能當興趣嗎?

本文開始

----------------------------------------------------------------------------------------

職涯發展中, 總是有時候在高峰, 有時候在低谷, 沒有人是永遠在顛峰

好像有種循環, 

不知道從什麼時候開始,

我好像在期待下班, 在期待下一次發薪水, 期待下一個月, 我存款裡的數字增加不少,

期待早上看著自己帳戶的股票成長, 而對於工作, 進修, 什麼的, 一點興趣也沒有?

像這樣的想法我相信一般工作者或多或少都有過這樣的心情,

有的人找方法轉念, 上些心靈成長的課, 有的人藉由假日的休閒, 轉換工作狀態,

和朋友一起去吃吃喝喝, 唱唱歌, 舒緩一下壓力,

也有的人參加讀書會, 獲得一些正面力量, 再回來面對工作

不禁讓人思考

我現在的工作, 真的是我的興趣嗎?

或是, 為何我感興趣的事變成工作, 我就對它厭煩?


的確, 是有可能工作久了, 我逐漸對我的工作開始厭煩

但是原因真的是因為"工作"嗎?

如果仔細去探究其根源, 其實真正令你厭煩的, 另有其他東西


比如, 公司內部走一個高壓, 需要高效的產出, 

使得你不得不占用下班的休息時間去完成公司所安排的任務, 

在付出與薪水極度不平衡之下, 你厭惡這份工作

更準確地說, 

你厭惡的並不是工作, 

而是公司習慣榨乾你最後一分力氣的文化

你下意識地將工作和累進行了連結, 

而實際上, 或許有另外一份工作不用你"這麼累"

只是這公司對你的安排, 使你"這麼累"


又比如, 上司對你極其嚴厲, 你常常被上司定, 

同事對你的評價也差, 覺得你就是個毫無用處的大叔, 

看你的眼神中充滿著不屑, 

在公司裡充滿著挫折, 

沒成就感, 

公司外,

又缺乏自信, 交不到女朋友, 

因此, 你就認為, 這份工作你沒興趣, 

因為這工作令你感到自己

是一個魯蛇, 

但是, 真的是工作造成你這麼負面的嗎? 

是這工作害你交不到女朋友嗎? 

是這工作讓你人生失敗嗎? 

不, 更有可能是性格上, 

漫不經心, 常常丟三落四, 被上司盯上, 

另外一面, 人際關係也差, 

不懂得和同事怎麼相處, 

只知道抱怨主管,

抱怨工作, 

然後就被同事白眼了, 列為黑名單

這是工作的問題嗎? 

是不是只有"你"才發生問題?

然而你為了讓自己好過點, 

於是就說"這工作真是令我厭煩", 

然後對工作一點興趣也沒有, 

下班只想要各種放鬆跟休息, 

但是真正的問題是工作嗎?

---------------------------------------------------------------------------------------------------------------------

這裡, 我不想要給什麼喝起來好喝, 一點用處都沒有的雞湯

好讓你感覺很好, 然後接受現狀, 就這樣下去


我們不如反過來想

是我決定"工作"成為厭煩的事

是我決定"把興趣"當成藉口

是我決定當遇到所有挫折的時候都用這句"工作不能當興趣"做擋箭牌

我就是這些事情的主宰

我需要對這些事情付完全的責任

因為"這是我的人生", 即使我因他人或其他事影響

"所有做決定的都是我"

上面這句話, 你覺得論述如何?

如果你覺得並沒有說錯

那我可以大膽的說


我可以"把工作當興趣"

我可以"把提早做完工作當成就"

我可以"把bug數減少當作遊戲分數"

我可以"改善自己的人際關係"

我可以"使上司對我改觀"

如果我的一切事情, 都是我可以決定的,

那我也可以決定要這樣做, 要這樣想


其實, 事實就是這樣

我們在想很多藉口的時候, 只是我們想逃避那要付出的成本

但是當我們去做的時候, 就發現事情沒我們想得那麼難

我得承認的確有些事情很難, 但是我認為當我們"只有想想", 很容易就把事情想難了

也不得不說

其實有些事情, 會需要去學點方法, 

和前輩請教, 會降低許多難度

但是這些都不及

"你真的想去這麼做"


如果你真的想把工作當興趣, 

你基本上就會思考, 怎麼去克服其中的難點,

很多的難點, 還是在自身身上, 

是溝通需要改善, 是想法要再開拓點, 是面對事情態度

當我想著, 我提早做完, 把事情做好, 對我來說是無比喜悅

當我有時間整理好運用的技術, 我從一個個項目有新的學習

就好像遊戲中蒐集武器入庫一樣愉悅

當我從工作中, 發現那些優秀的code, 優秀的人經營的github

我感到世界是如此廣闊, 帶著感謝運用著他人已經為我寫好的範例

誠心的感謝google帶來的便利

在下班的時候, 因今天的進度而感到充實, 因今天的見聞而覺得自己有所成長

而去鍛鍊身體, 使工作能更專注, 而去學習說有趣的話使同事感覺舒壓

我可以做的事情, 就遠遠比我消極的領薪水來的多


更何況.....薪水不少........未來還會更多的時候........

然後自己又會投資把錢翻倍的時候.........

是不用想著有錢之後我要做什麼什麼什麼, 那只會令自己期待著下班, 領下個月薪水

還不如這樣想

為何不能把工作當興趣?

工作真的不能當興趣嗎?


參考閱讀: 

被討厭的勇氣

參考課程: 

超越魅力 第二階段 負責任模式

超越魅力 第三階段 團隊貢獻度







2022多益線上家教 版本202203

地點線上 Teams

教學課程 多益, 生活會話, 外商面試


*具有多年讀書會經驗

*聽力滿分

*懂得如何從低分群準備到高分群

*多次考試經驗, 並從準備考試中建構會話基礎


主教多益聽力部分,以及準備方法

每周上課1小時,會出一天份量的回家作業

藉由每周進度,幫助久未接觸英文的工作人

找回英文的熟悉度,並累積英文基礎能力

養成良好的學習模式


主要分為四階段

1階段: 發音矯正, 句型累積, 單字記憶

2階段: 簡易生活會話應用

3階段: 多變情境應用

4階段: 英文面試情境準備


目前進度: 多益第二大題

目前人數:8

程度: 多益 500-700


地點:Teams 線上

時間:周日 晚上8:20 - 10:00

收費:300(失業者 or 為人父母者 收費100)

收費方式:轉帳

聯絡方式 : 站內私訊,或是line: iw5420 

教材:由老師提供,也可自行購買課本

資料表存JSON格式文字

把JSON存進資料庫的欄位, 要做以下的設置



@Entity(name = "patient_xxx")
@TypeDef(name = "json", typeClass = JsonType.class)
public class PatientXXX {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    // 傳送Json內容
    @Type(type = "json")
    @Column(name = "content", columnDefinition = "json")
    private String content;
...
}

另外, 接值進來的時候, 要用ObjectMapper轉成字串




    @PostMapping("/lab/PutStatus")
	 public JwtResponseResult putStatus(@RequestBody PutStatusRequestVo putStatusRequestVo) {
    	
    	try {
    		ObjectMapper mapper = new ObjectMapper();
       	  String jsonString = mapper.writeValueAsString(putStatusRequestVo);
       
        	labService.updatePatientExamineOrder(putStatusRequestVo.getExamList());
        	labService.recordCallApiLog(
        		putStatusRequestVo.getLab_id(), 
        		jsonString, 
        		PatientExamineLogEnum.Receive.getCode(),
        		"OK");
        
		} catch (Exception ex) {
			ex.printStackTrace();
			return new JwtResponseResult("fail", messageHelper, "common.error", ex.getMessage());
		}
		return new JwtResponseResult("ok", null);
	 }

***如果直接VO.toString()的話, 是沒辦法列印成做成JSON結構的

Java String 轉 localdatetime yyyyMMddHHmmss 格式


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class LocalDateTimeTest {
	
	@Test
	void test() {
		String datetimestr ="20210212111022";
		DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		LocalDateTime datetime = LocalDateTime.parse(datetimestr, formatter);
		System.out.println(datetime);
		
		DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		String datetime2 = datetime.format(formatter2);
		System.out.println(datetime2);
	}

}

2022年3月6日 星期日

使用RestTemplate請求Token

參考了幾篇文章, 直接拿來用, 然後就.....掛掉

真是不靠譜, 還是自己寫一篇好

根據下列這篇

https://www.baeldung.com/spring-resttemplate-post-json

基本上傳過去的內容是可以用Json物件

不過~他其實也可以傳自定義物件

所以我們就拿自定義物件來做示範


這是要傳過去的物件


public class JwtUserExternal {
	
	private String account;
	private String pwd;
	...
}

在開始的地方先注入


	@Autowired
	RestTemplate restTemplate;

要在Config也加入Bean就是, 不然會報java.lang.IllegalStateException: Failed to load ApplicationContext錯誤


	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

因為URI是從資料庫取出來, 我們化名為Target

然後從Target對象中取出帳號密碼, 生出JwtUserExternal物件

然後就~call sendRequestForToken function, 把Url和物件傳過去, 取得Token


	public String getToken(String LabId) {
		Target target = targetRepo.findById(Id);
		if (target == null) {
			throw new ICUmodelJwtException(HttpStatus.NOT_FOUND, "patientExamin not found");
		}
		JwtUserExternal jwtUser = new JwtUserExternal(target.getTokenId(), target.getTokenPassword());
		String token = sendRequestForToken(patientExamine.getTokenUrl(), jwtUser);
		return token;
	}

打對方API細節

這裡先生出HttpHeader, 再用它和傳送物件生出HttpEntity為request

然後使用restTemplate.postForObject(url, request, String.class)

將回傳值用使用ObjectMapper轉成JsonNode

目前回傳格式是這樣

{
    "CODE""OK",
    "TOKEN""eyJhbGciOxxxxxxxxx"
}

因此就root.path("TOKEN").asText()就能拿出Token


	public String sendRequestForToken(String url, JwtUserExternal requestObject) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			HttpEntity<jwtuserexternal> request = new HttpEntity<jwtuserexternal>(requestObject, headers);
			String personResultAsJsonStr = restTemplate.postForObject(url, request, String.class);
			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode root = objectMapper.readTree(personResultAsJsonStr);
			return root.path("TOKEN").asText();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	

完整的類別如下



@Service
public class JwtLogin {

	@Autowired
	RestTemplate restTemplate;

	@Autowired
	TargetRepo targetRepo;

	private String targetId;

	public String getToken() {
		String token = getToken(this.getLabId());
		return token;
	}

	public String getToken(String id) {
		Target target = targetRepo.findByTargetId(id);
		if (target == null) {
			throw new ICUmodelJwtException(HttpStatus.NOT_FOUND, "target not found");
		}
		JwtUserExternal jwtUser = new JwtUserExternal(target.getTokenId(), target.getTokenPassword());
		String token = sendRequestForToken(target.getTokenUrl(), jwtUser);
		return token;
	}

	public String sendRequestForToken(String url, JwtUserExternal requestObject) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			HttpEntity<JwtUserExternal> request = new HttpEntity<JwtUserExternal>(requestObject, headers);
			String personResultAsJsonStr = restTemplate.postForObject(url, request, String.class);
			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode root = objectMapper.readTree(personResultAsJsonStr);
			return root.path("TOKEN").asText();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public String getTargetId() {
		return targetId;
	}

	public void setTargetId(String targetId) {
		this.targetId = targetId;
	}

}

重構以上程式碼

差異部分,直接傳Json物件過去

重構的點是因為, 有可能來源來自於不同Table

我們對前面邏輯, 開放新增方法, 可以自行新增將JwtUserExternal set進來

也就是如果他從其他來源來, 可以新增一個類似setTargetId, 只要將JwtUserExternal設到成員變數就可

對後面邏輯封閉, 傳參JwtUserExternal類讓他可以打API, 來取回Token

新增方法上符合開閉原則

JwtUserExternal類別


public class JwtUserExternal {
	
	private String account;
	private String pwd;
	private String url;
	...
		
}

主程式


@Service
public class JwtLogin {

	@Autowired
	RestTemplate restTemplate;

	@Autowired
	PatientExamineRepo patientExamineRepo;

	private JwtUserExternal jwtUserExternal;
	

	public String getToken() {
		String token = sendRequestForToken(this.getJwtUserExternal());
		return token;
	}
	
	public void setTargetId(String targetId) {
		Target target = targetRepo.findByTargetId(targetId);
		if (target == null) {
			throw new ICUmodelJwtException(HttpStatus.NOT_FOUND, "target not found");
		}
		this.setJwtUserExternal(new JwtUserExternal(
						target.getTokenId(),
						target.getTokenPassword(),
						target.getTokenUrl())
				);
	}

	public String sendRequestForToken(JwtUserExternal jwtUser) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			JSONObject requestObject = new JSONObject();
			requestObject.put("account", jwtUser.getAccount());
			requestObject.put("pwd", jwtUser.getPwd());
			HttpEntity<String> request = new HttpEntity<String> (requestObject.toString(), headers);
			String personResultAsJsonStr = restTemplate.postForObject(jwtUser.getUrl(), request, String.class);
			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode root = objectMapper.readTree(personResultAsJsonStr);
			return root.path("TOKEN").asText();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public JwtUserExternal getJwtUserExternal() {
		return jwtUserExternal;
	}

	public void setJwtUserExternal(JwtUserExternal jwtUserExternal) {
		this.jwtUserExternal = jwtUserExternal;
	}	

}

2022年3月4日 星期五

spring boot 後端 i18n

Spring boot 其實有自動配置好

因此只需要注入MessageSource就可以使用了



而~i18n檔案的目錄

可以從application.properties檔案中做控制

例如:

spring.messages.basename=static/i18n/report

這個是從resource下面開始的路徑








後面~我們檔案名稱就為report

多國檔就會為report_xxx


@Autowired
    private MessageSource messageSource;
    
    @Test 
    void test() {
    	String s1 = messageSource.getMessage(
            "demo.message", 
            null, 
            Locale.ENGLISH);
    	System.out.println(s1);

       	String s2 = messageSource.getMessage(
                "demo.message", 
                null, 
                Locale.TAIWAN);
        System.out.println(s2);
  
    }

在多國文字檔案的部分如下










run的結果如下





另外~我們可以發現, 他原生的用法, 參數多又麻煩
所以, 我另外寫了一個helper把它簡化
只要一開始設定完語言, 使用的時候就只要getMessage一個參數就搞定
寫好的內容如下, 裡面還有一個邏輯是圖片的邏輯
比方說中文版, 我們就原圖, 英文版我們使用英文版的圖, 圖檔名結尾為_en
這樣, 方便我們getImage取得相對應的路徑
程式碼如下




@Service
public class ReportHelper {
	
	   @Autowired
	   private MessageSource messageSource;
	   
	   private Locale locale;
	   
	   public String getMessage(String name) {   	
	    	return messageSource.getMessage(name, null, locale);
	    }

		public Locale getLocale() {
			return locale;
		}

		public void setLocale(Locale locale) {
			this.locale = locale;
		}   
		
		public String getImagePath(String path) {
			String suffix="";
			if(locale.equals(Locale.TAIWAN)) {
	        	suffix="";
	        } else {
	        	suffix="_en";
	        }
			return path + suffix;
		}

}

使用如下


    @Autowired 
    private ReportHelper reportMessage;
    
    @Test
    void utilTest() {
    	reportMessage.setLocale(Locale.TAIWAN);
    	String s2 = reportMessage.getMessage("demo.message");
    	System.out.println(s2);
    }

最後~如果有超過一種以上的多國檔要注入只要在application.properties檔案用逗號隔開就好

ex


# i18n
spring.messages.basename=static/i18n/report, static/i18n/message

安裝nvm, node

為何要安裝呢? 
因為現在專案開始有使用到React, 
有React包 但是他的相依套件, 
並不會上到gitlab 所以, 在打包之前要先載入相關套件, 
build完 再run maven install產生jar檔 
那要使用 
npm i 
npm build 
可以先下載nvm再用其下載node 
https://github.com/coreybutler/nvm-windows

步驟如下








然後~在3做完後~是有一個小坑, 就是
windows他預設安裝路徑是在user下面
是很有可能被擋到的(以至於nvm install版號, 沒反應)










這個時候就換個資料夾來安裝就好
我是直接放D巢







安裝完之後~
在command打一下 nvm version
出現以下就OK






然後~可以上到node官網看一下版號16.14.0 












然後在回到command下 nvm install 16.14.0
他就會開始安裝node 16.14.0 版本

安裝完之後要輸入nvm use 版本號
這時~第二個小坑來了, 這裡他可能會出現亂碼
你就要採取以下作為解決





或是用系統管理員身分啟動command會進到一樣的路徑
然後 輸入 nvm use 版號
這樣就能run了
然後~當拉下新專案時
進入到reat資料夾
在command 輸入 
npm i
完後輸入
npm build
就可以進行後面spring boot 專案打包


[leetcode] [KMP] KMP

ABCDABD... ABCDABF... 簡單的說, 傳統解兩字串匹配部分 可能會來個雙迴圈, 哀個比對, 當不匹配的時候, 會將下方列再後移1位 然後不匹配再後移 然而 如果像上放已經有4個屬於匹配的字串, 她就應該直接往後移四位來匹配, 而不是只移動1位 隱藏的思維是, 當...