從啟明星數學系統Math說起
最近做了一個數學系統(還沒做完),中間使用了不少第三方開源外掛,但是發現這些外掛基本上都是國外的.
事實上這些外掛基本上都使用Javascript開發,也並不會涉及太高深的JS知識,但是,這些外掛對演算法要求甚高。
(1)數學公式
數學公式使用Latex展示,但是把Latex解析為HTML是非常考驗基本功的技術。
(2)SVG畫圖,看起來簡單,但是做起來也不容易,這通常出現在習題裡,例如"三角形ABC,D是BC上一點。。。"類似這樣的題目
(3)幾何圖形,包括正弦,餘弦,正切,餘切,指數,對數,微積分,線性變化,圓,橢圓,雙曲線等圖形
這種圖形適合教學,例如通過圖形,很容易讓學生知道正弦餘弦的效果。
上面這些都是基本功,事實上,他是和語言無掛的。如果JS做不出,那麼用NET/JAVA/GO/等仍然很難做出。
這就像使用AutoCAD進行機械製圖,AutoCAD只是一個工具,如果你設計不同出圖形,那麼無論使用何種CAD,還是作不出。
因此,相比語法,演算法可能更重要。
語法與演算法
語法,這裡特指計算機語法,是計算機語言規定的一套規則,不同的語言如Java,NET,甚至Javascript,Typescript都定義了自己的一套語言規則。
要使用該語言,必須符合該語言規則。
演算法,是解決一件事情的方法,或者說是一系列解決問題的清晰指令,同樣一個問題,可以有不同的方法解決,因此演算法有好的演算法也有不好的演算法。
演算法的優劣可以用空間複雜度與時間複雜度來衡量。
軟體=語法+演算法。一個軟體的執行需要“語法+演算法”兩則缺一不可。
計算機只要三個語法即可
事實上,早期,人們編寫程式發現,計算機只要三個流程即可:正常的順序流程,條件流程和迴圈流程。
順序流程比較簡單,程式碼一行一行執行,沒什麼可說明的。
條件流程就是 if 語句
迴圈流程就是while語句。
除此以外,其它語句都不是必須的,以.NET為例,其實net還提供了goto語句,但是後來人們發現,goto一方面破壞了程式的可讀性,讓程式跳來跳去,
一方面goto語句可以使用if和whilte替代,所以,goto使用率極低。
掌握了上面的三個流程,就可以寫出程式。
順序的語句
int a=1; int b=2; int c=a+b
if條件語句
int a=1; int b=2 if(a<b) { //do something2 } else { //do something2 }
white迴圈語句
int i = 0; int sum = 0; while (i < 10) { sum += i; i++; }
由此,.NET的其它語法都可以由這3個基本規則推導而來。
例如switch基本上是和if等效的
switch (i) { case "1": break; case "2": break; case "3": break; } if(if=="1") { // } if(if=="3") { // } if(if=="4") { // }
而.NET的 foreach也是可以由while語句實現
string[] studens = { "s1","stud2"}; foreach (string stud in studens) { .... } int len=studens.Length; while(i<len) { string stud=studens[i]; i++; }
所以,任何計算機語言都一定會提供if語句和while語句,否則這個語言就無法真正成為計算機語言。
演算法是千變萬化
和計算機語言相對穩定相比,演算法才是千變萬化。在計算機教程裡,對排序的演算法講解的最多,包括 簡單排序、插入排序,快速排序,氣泡排序、希爾排序等
每種排序演算法都有優點和確定,例如快速排序雖然快速但是穩定性差, 簡單排序效率差但是穩定性強。
這就像“馬兒跑的快但是力氣小,牛兒力氣大但是走的慢”,所以,牛馬都有各自的應用場景。
軟體競爭力核心在演算法
在很多情況下,我們感覺“這個軟體好,那個軟體不好”很大程度上是由演算法決定的,這裡的演算法不僅僅只是排序那麼簡單。
對NET進行序列化和反序列化,主要有微軟提供的DataContractJsonSerializer類和JavaScriptSerializer類,以及開源社群提供的Newtonsoft.Json(JSON.Net)類。
雖然他們都使用.NET開發,但是能明顯感覺Newtonsoft.Json優於微軟提供的類。(圖片來自yanweidie)
演算法是發散思維的
計算機語言是限定思維的,就是你只能使用他定義的語法,但是,演算法則是發散思維的。這種發散思維體現的是“解決問題的方法”。
當我們在網頁裡,雙擊一個文字時,會自動選擇該文字對應的單詞,
我相信這背後有微軟提供的詞庫,例如你雙擊“歸納”的“歸”,他會自動選中“歸納”,而不是“妨歸”。
但是,在進行svg的操作裡,微軟並未提供這樣的“選中”功能,這就需要我們自己實現“選中物件”
上次看mrdoob實現的方式很簡單,建立一個span,設定它滑鼠樣式為:none,設定它邊框為紅色,就可以實現下圖的效果。
var selection = document.createElement( 'span' ); selection.style.position = 'absolute'; selection.style.display = 'block'; selection.style.outline = 'solid 2px #ff0000'; selection.style.pointerEvents = 'none'; document.body.appendChild( selection );
類似的例子還有很多。
談一談Visual Studio的實現
以下內容純屬猜想,我也沒找他資料來查證下面的猜想。
Visual Studio號稱宇宙開發第一工具,一直很好奇他是怎麼實現的,特別是字型變亮,語法提示,效果又準又快。
好在有開源的力量,最早知道的是codemirror,codemirror可以讓textarea秒變編輯器。
再配合一些外掛,就算非專業人士,也能實現類似部分Visual Studio的效果。
但是,Codemirror太複雜.
所以,又找到了 PrismJS,這是一個輕量級的程式碼顯示工具,
使用prism能讓你的程式碼,在web上顯示時,看起來很專業。
很容易看到他提供的原始碼,核心還是“正規表示式”。也就是系統預定義了樣式,當選中所需序言時,切換對應的樣式進行變色。
說起來容易,做起來還是很複雜的。
當然,Visual Stuido的實現肯定比這複雜,例如VS的關鍵字應該是編譯後顯示亮度,而不是隻靠字面的文字。
雖然leetcode也有演算法,可是她只是一個點,不是一條線。
--------------------------------------------------------------
啟明星數學系統 http://demo.dotnetcms.org/math,主要是供老師使用的一套系統。