偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

手寫(xiě)編程語(yǔ)言-如何為 GScript 編寫(xiě)標(biāo)準(zhǔn)庫(kù)

開(kāi)發(fā) 前端
在寫(xiě)標(biāo)準(zhǔn)庫(kù)的過(guò)程中還會(huì)有額外收獲,可以再次閱讀一遍 Go 標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)流程,換了一種語(yǔ)法實(shí)現(xiàn)出來(lái),會(huì)加深對(duì) Go 標(biāo)準(zhǔn)庫(kù)的理解。

版本更新

最近 GScript 更新了 v0.0.11 版本,重點(diǎn)更新了:

  • Docker運(yùn)行環(huán)境
  • 新增了 byte 原始類(lèi)型
  • 新增了一些字符串標(biāo)準(zhǔn)庫(kù) Strings/StringBuilder
  • 數(shù)組切片語(yǔ)法:int[] b = a[1: len(a)];

具體更新內(nèi)容請(qǐng)看下文。

前言

前段時(shí)間發(fā)布了 GScript 的在線 playground

這是一個(gè)可以在線運(yùn)行 GScript 腳本的網(wǎng)站,其本質(zhì)原理是接收用戶的輸入源碼從而在服務(wù)器上運(yùn)行的服務(wù);這簡(jiǎn)直就是后門(mén)大開(kāi)的 XSS 攻擊,為保住服務(wù)器我設(shè)置了運(yùn)行 API 的后端服務(wù)的用戶權(quán)限,這樣可以避免執(zhí)行一些惡意的請(qǐng)求。

但也避免不了一些用戶執(zhí)行了一些耗時(shí)操作,比如一個(gè)死循環(huán)、或者是我提供 demo 里的打印楊輝三角。

這本質(zhì)上是一個(gè)遞歸函數(shù),當(dāng)打印的三角層數(shù)過(guò)高時(shí)便會(huì)非常耗時(shí),同時(shí)也非常消耗 CPU。

有幾次我去檢查服務(wù)器時(shí)發(fā)現(xiàn)了幾個(gè) CPU 過(guò)高的進(jìn)程,基本上都是這樣的耗時(shí)操作,不可避免的會(huì)影響到服務(wù)器的性能。

使用 Docker

為了解決這類(lèi)問(wèn)題,很自然的就能想到可以使用 Docker,所有的資源都和宿主機(jī)是隔離開(kāi)的,無(wú)論怎么瞎折騰也不會(huì)影響到宿主機(jī)。

說(shuō)干就干,最后修改了 API 執(zhí)行腳本的地方:

    string fileName = d.unix("Asia/Shanghai") + "temp.gs" ;
s.writeFile(fileName, body, 438);
string pwd = s.getwd();
// string res = s.command("gscript", fileName);
string res = s.command("docker","run","--rm","-v", pwd+":/usr/src/gscript","-w","/usr/src/gscript", "crossoverjie/gscript","gscript", fileName);
s.remove(fileName);
r.body = res;
r.ast = dumpAST(body);
r.symbol=dumpSymbol(body);
ctx.JSON(200, r);

主要修改的就是將直接執(zhí)行的 GScript 命令修改為了調(diào)用 docker 執(zhí)行。

但其實(shí)也還有改進(jìn)空間,后續(xù)新增協(xié)程之后可以便可監(jiān)控運(yùn)行時(shí)間,超時(shí)后便會(huì)自動(dòng) kill 進(jìn)程。

我也將該 Docker 上傳到了 DockerHub,現(xiàn)在大家想在本地體驗(yàn) GScript 的 REPL 時(shí)也只需要運(yùn)行Docker 就能使用。

docker pull crossoverjie/gscript
docker run --rm -it crossoverjie/gscript:latest gscript

當(dāng)然也可以執(zhí)行用 Docker 執(zhí)行 GScript 腳本:

docker run --rm -v $PWD:/usr/src/gscript -w /usr/src/gscript crossoverjie/gscript gscript {yourpath}/temp.gs

編寫(xiě) GScript 標(biāo)準(zhǔn)庫(kù)?

接下來(lái)重點(diǎn)聊聊 GScript 標(biāo)準(zhǔn)庫(kù)的事情,其實(shí)編寫(xiě)標(biāo)準(zhǔn)庫(kù)是一個(gè)費(fèi)時(shí)費(fèi)力的事情。

現(xiàn)在編譯器已經(jīng)提供了一些可用的內(nèi)置函數(shù),借由這些內(nèi)置函數(shù)寫(xiě)一些常見(jiàn)的工具類(lèi)是完全沒(méi)有問(wèn)題的。

對(duì)寫(xiě) GScript 標(biāo)準(zhǔn)庫(kù)感謝的朋友可以當(dāng)做一個(gè)參考,這里我打了一個(gè)樣,先看下運(yùn)行效果:

// 字符串工具類(lèi)
StringBuilder b = StringBuilder();
b.writeString("10");
b.writeString("20");
int l = b.writeString("30");
string s = b.String();
printf("s:%s, len=%d ",s,l);
assertEqual(s,"102030");
byte[] b2 = toByteArray("40");
b.WriteBytes(b2);
s = b.String();
assertEqual(s,"10203040");
println(s);

// Strings 工具類(lèi)
Strings s = Strings();
string[] elems = {"name=xxx","age=xx"};
string ret = s.join(elems, "&");
println(ret);
assertEqual(ret, "name=xxx&age=xx");

bool b = s.hasPrefix("http://www.xx.com", "http");
println(b);
assertEqual(b,true);
b = s.hasPrefix("http://www.xx.com", "https");
println(b);
assertEqual(b,false);

其中的實(shí)現(xiàn)源碼基本上是借鑒了 Go 的標(biāo)準(zhǔn)庫(kù),先來(lái)看看 StringBuilder 的源碼:

class StringBuilder{
byte[] buf = [0]{};

// append contents to buf, it returns the length of s
int writeString(string s){
byte[] temp = toByteArray(s);
append(buf, temp);
return len(temp);
}

// append b to buf, it returns the length of b.
int WriteBytes(byte[] b){
append(buf, b);
return len(b);
}

// copies the buffer to a new.
grow(int n){
if (n > 0) {
// when there is not enough space left.
if (cap(buf) - len(buf) < n) {
byte[] newBuf = [len(buf), 2*cap(buf)+n]{};
copy(newBuf, buf);
buf = newBuf;
}
}
}

string String(){
return toString(buf);
}
}

主要就是借助了原始的數(shù)組類(lèi)型以及 toByteArray/toString 字節(jié)數(shù)組和字符串的轉(zhuǎn)換函數(shù)實(shí)現(xiàn)的。

class Strings{
// concatenates the elements of its first argument to create a single string. The separator
// string sep is placed between elements in the resulting string.
string join(string[] elems, string sep){
if (len(elems) == 0) {
return "";
}
if (len(elems) == 1) {
return elems[0];
}

byte[] bs = toByteArray(sep);
int n = len(bs) * (len(elems) -1);
for (int i=0; i < len(elems); i++) {
string s = elems[i];
byte[] bs = toByteArray(s);
n = n + len(bs);
}

StringBuilder sb = StringBuilder();
sb.grow(n);
string first = elems[0];
sb.writeString(first);

string[] remain = elems[1:len(elems)];
for(int i=0; i < len(remain); i++){
sb.writeString(sep);
string r = remain[i];
sb.writeString(r);
}
return sb.String();

}

// tests whether the string s begins with prefix.
bool hasPrefix(string s, string prefix){
byte[] bs = toByteArray(s);
byte[] bp = toByteArray(prefix);
return len(bs) >= len(bp) && toString(bs[0:len(bp)]) == prefix;
}
}

Strings 工具類(lèi)也是類(lèi)似的,都是一些內(nèi)置函數(shù)的組合運(yùn)用;

在寫(xiě)標(biāo)準(zhǔn)庫(kù)的過(guò)程中還會(huì)有額外收獲,可以再次閱讀一遍 Go 標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)流程,換了一種語(yǔ)法實(shí)現(xiàn)出來(lái),會(huì)加深對(duì) Go 標(biāo)準(zhǔn)庫(kù)的理解。

所以歡迎感興趣的朋友向 GScript 貢獻(xiàn)標(biāo)準(zhǔn)庫(kù),由于我個(gè)人精力有限,實(shí)現(xiàn)過(guò)程中可能會(huì)發(fā)現(xiàn)缺少某些內(nèi)置函數(shù)或數(shù)據(jù)結(jié)構(gòu),這也沒(méi)關(guān)系,反饋 issue 后我會(huì)盡快處理。

由于目前 GScript 還不支持包管理,所以新增的函數(shù)可以創(chuàng)建 Class 來(lái)實(shí)現(xiàn),后續(xù)支持包或者是 namespace 之后直接將該 Class 遷移過(guò)去即可。

本文相關(guān)資源鏈接

  • GScript 源碼:https://github.com/crossoverJie/gscript
  • Playground 源碼:https://github.com/crossoverJie/gscript-homepage
  • GScript Docker地址:https://hub.docker.com/r/crossoverjie/gscript
責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2022-09-27 08:01:48

遞歸函數(shù)GScript

2020-04-15 10:50:19

編程語(yǔ)言工具技術(shù)

2015-09-16 17:30:20

安裝Go語(yǔ)言Linux

2017-09-28 16:18:55

語(yǔ)言PythonGo

2022-09-19 08:10:37

運(yùn)算符函數(shù)語(yǔ)言

2023-04-02 23:13:07

Go語(yǔ)言bufio

2020-02-11 09:41:02

Go語(yǔ)言程序員文章

2020-02-05 16:55:11

Go語(yǔ)言程序員文章

2011-11-08 17:11:47

程序員

2018-04-17 08:41:47

Java機(jī)器學(xué)習(xí)應(yīng)用iOS

2020-03-30 17:43:13

開(kāi)源開(kāi)源項(xiàng)目編寫(xiě)文檔

2017-11-20 13:32:54

微服務(wù)數(shù)據(jù)庫(kù)開(kāi)發(fā)

2022-05-05 09:11:33

數(shù)據(jù)庫(kù)加密數(shù)據(jù)安全

2009-11-16 08:58:43

PHP語(yǔ)言

2019-01-02 13:11:53

GO語(yǔ)言緩存

2024-09-30 08:01:44

2020-10-30 12:42:06

TypeScript編程開(kāi)發(fā)

2011-05-16 14:07:12

MySQL數(shù)據(jù)庫(kù)設(shè)置密碼

2023-01-13 18:55:09

游戲Ada編程語(yǔ)言

2011-02-25 10:12:09

GoWeb
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)