跳槽是每个人的职业生涯中都要经历的过程,不论你是搜索到的这篇文章还是无意中浏览到的这篇文章,希望你没有白白浪费停留在这里的时间,能给你接下来或者以后的笔试面试带来一些帮助。
也许是互联网未来10年中最好的一年。WINTER IS COMING。但是如果你不真正的自己去尝试尝试,你永远不知道市面上的行情如何。这次找工作下来,我自身感觉市场并没有那么可怕,也拿到了几个大厂的offer。在此进行一个总结,给自己,也希望能帮助到需要的同学。
面试准备
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
面试准备根据每个人掌握的知识不同,准备的时间也不一样。现在对于前端岗位,以前也许不是很重视算法这块,但是现在很多公司也都会考。建议大家平时有空的时候多刷刷leetcode。算法的准备时间比较长,是一个长期的过程。需要在掌握了大部分前端基础知识的情况下,再有针对性的去复习算法。面试的时候算法能做出来肯定加分,但做不出来也不会一票否决,面试官也会给你提供一些思路。
我们利用 AssemblyScript 来实现了这个测试应用,测试代码如下:
$ cat tests/dapr/index.ts
// @ts-ignore
import { Console } from “as-wasi”;
import { DaprClient, StateItem } from “./dapr”;
import { JSON } from “assemblyscript-json”;
Console.log(“Testing Dapr API …”)
let dapr = new DaprClient()
dapr.saveState(“statestore”, “weapon”, JSON.Value.String(“Death Star”))
let o = JSON.Value.Object()
o.set(“name”, “Tatooine”)
o.set(“test”, 123)
let item = new StateItem(“planets”, o)
let items: StateItem[] = [item]
dapr.saveBulkState(“statestore”, items)
let testObj = dapr.getState(“statestore”, “planets”)
let testStr = dapr.getState(“statestore”, “weapon”)
if (testStr.toString() == “Death Star” && testObj.isObj && (<JSON.Integer>(<JSON.Obj>testObj).getInteger(“test”)).valueOf() == 123) {
Console.log(“Test successfully!”)
} else {
Console.log(“Test failed!”)
}
代码逻辑非常简单,就是创建一个 Dapr 客户端,然后通过 REST API,进行 Dapr 的状态管理。我们可以快速验证一下。
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.19s
Running target/debug/wasi-experimental-http-wasmtime-sample
Testing Dapr API …
POST http://127.0.0.1:3500/v1.0/state/statestore with [{“key”:“weapon”,“value”:“Death Star”}]
POST http://127.0.0.1:3500/v1.0/state/statestore with [{“key”:“planets”,“value”:{“name”:“Tatooine”,“test”:123}}]
GET http://127.0.0.1:3500/v1.0/state/statestore/planets
GET http://127.0.0.1:3500/v1.0/state/statestore/weapon
Test successfully!
module instantiation time: 333.16637ms
wasi-experimental-http 项目在 Wasmtime (来自 Bytecode Alliance 的一个 WASM 实现)虚拟机上实现了扩展,支持在 WASI 应用中,访问 HTTP 服务。它还提供了一个 AssemblyScript 的 HTTP Client 实现。
wasi-experimental-http 项目:https://github.com/deislabs/wasi-experimental-http/。
在此之上,我们为 AssemblyScript 提供一个 Dapr 的封装,可以参见:https://github.com/denverdino/wasi-experimental-http/blob/main/tests/dapr/dapr.ts。
// @ts-ignore
import { Console } from “as-wasi”;
import { Method, RequestBuilder, Response } from “…/…/crates/as”;
import { JSONEncoder, JSON } from “assemblyscript-json”;
export class StateItem {
key: string
value: JSON.Value
etag: string | null
metadata: Map<string, string> | null
constructor(key: string, value: JSON.Value) {
this.key = key
this.value = value
this.etag = null
this.metadata = null
}
}
…
export class DaprClient {
port: i32
address: string
constructor() {
this.address = “127.0.0.1”
this.port = 3500
}
stateURL(storeName: string): string {
return “http://” + this.address + “:” + this.port.toString() + “/v1.0/state/” + storeName
}
saveState(storeName: string, key: string, value: JSON.Value): boolean {
let item = new StateItem(key, value)
let items: StateItem[] = [item]
return this.saveBulkState(storeName, items)
}
saveBulkState(storeName: string, items: StateItem[]): boolean {
// Handle field
let encoder = new JSONEncoder();
// Construct necessary object
encoder.pushArray(null);
for (let i = 0, len = items.length; i < len; i++) {
let item = items[i]
encoder.pushObject(null);
encoder.setString(“key”, item.key)
encodeValue(encoder, “value”, item.value)
if (item.etag != null) {
encoder.setString(“etag”, item.etag)
}
encoder.popObject()
};
encoder.popArray();
// Or get serialized data as string
let jsonString = encoder.toString();
let url = this.stateURL(storeName);
Console.log("POST " + url + " with " + jsonString);
let res = new RequestBuilder(url)
.method(Method.POST)
.header(“Content-Type”, “application/json”)
.body(String.UTF8.encode(jsonString))
.send();
let ok = res.status.toString() == “200”
res.close();
return ok
}
getState(storeName: string, key: string): JSON.Value {
let url = this.stateURL(storeName) + “/” + key;
Console.log("GET " + url);
let res = new RequestBuilder(url)
.method(Method.GET)
.send();
let ok = res.status.toString() == “200”
let result = <JSON.Value> new JSON.Null()
if (ok) {
let body = res.bodyReadAll();
result = <JSON.Value>JSON.parse(body)
}
res.close();
return result
}
};
测试应用的 main 函数,会创建一个 Wasmtime 运行时环境,并为其添加为 HTTP 扩展,并加载执行测试应用的 WASM 字节码:https://github.com/denverdino/wasi-experimental-http/blob/main/src/main.rs。
fn main() {
let allowed_domains = Some(vec![
“http://127.0.0.1:3500”.to_string(),
]);
let module = “tests/dapr/build/optimized.wasm”;
create_instance(module.to_string(), allowed_domains.clone()).unwrap();
}
/// Create a Wasmtime::Instance from a compiled module and
/// link the WASI imports.
fn create_instance(
filename: String,
allowed_domains: Option<Vec>,
) -> Result<Instance, Error> {
let start = Instant::now();
let store = Store::default();
let mut linker = Linker::new(&store);
let ctx = WasiCtxBuilder::new()
.inherit_stdin()
.inherit_stdout()
.inherit_stderr()
.build()?;
let wasi = Wasi::new(&store, ctx);
wasi.add_to_linker(&mut linker)?;
// Link wasi_experimental_http
let http = HttpCtx::new(allowed_domains, None)?;
http.add_to_linker(&mut linker)?;
let module = wasmtime::Module::from_file(store.engine(), filename)?;
let instance = linker.instantiate(&module)?;
let duration = start.elapsed();
println!(“module instantiation time: {:#?}”, duration);
Ok(instance)
}
==============================================================================
WASM/WASI 为轻量化、可移植、缺省安全的应用运行时提供了良好的基础,在区块链等领域 WebAssembly 已经得到了广泛的应用。然而,对于通用性的服务器端应用,WASM/WASI 的差距还非常明显。由于 berkeley socket 这样标准化的网络编程接口的缺失,只能通过扩展 WASM 虚拟机的方式来进行补齐。此外 WASM 的多线程能力还没有被标准化,目前的 HTTP 调用采用阻塞式同步调用,还无法实现高效和稳定的网络通信。
此外,另外 WASM/WASI 的一个短板就是开发效率和生态建设。目前而言,虽然众多的编程语言已经逐渐开始提供 WebAssembly 的支持,但是对于普通开发者而言,AssemblyScript 这样的脚本语言是更加合适的选择。AssemblyScript 复用了 TypeScript 的语法,与 Rust/C++ 相比,大大降低了学习曲线,也提供了非常好的 IDE 工具体验,如 VS Code 等。但是与 TypeScripty 通过翻译成为 JavaScript 执行不同,AssemblyScript 应用会被编译成 WASM 字节码执行。AssemblyScript 本质上是一个静态类型的编译型语言,本质上与 JS/TS 这样的动态类型的解释型语言非常不同。二者在语法上也有一些不同,比如目前 AssemblyScript 缺少对闭包 (closure) 和正则表达式 (Regex) 等常用功能支持,这让开发 WASM 应用还是有一定的技术门槛。
另外与 NPM 强大的生态相比,AssemblyScript 社区也很年轻。很多功能都需要从头构建,比如对 JSON 的序列化与反序列化,我们选择了 https://github.com/nearprotocol/assemblyscript-json ,但是其易用性和性能与成熟的 JSON 类库还有一定差距。当然我们也看到 AssemblyScript 的快速成长,以及越来越多的开发者开始贡献 AssemblyScript 代码库,比如 regex 支持等等。
Dapr 的出现为 WASM/WASI 开发通用的分布式应用,尤其是为可移植的、Serverless 化的应用带来另外一缕曙光。然而 Dapr 也并非完美:API 标准化在提升对后端服务可移植性的同时也阻碍了对差异化能力的支持。Sidecar 架构在提升灵活性的同时增加了部署和管理复杂性。
作为一个理性乐观派,任何技术都有其青涩的时代,期待社区的共同努力让计算无处不在、创新触手可及的理想成为现实。
总结
=============================================================
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。