tomatobanana
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Tomato Banana's Teaching Room time: 11/19/21 9:00pm - 11:10pm (- 10min) ```python= print('hello') ``` 1. write 和 fwrite 的区别,我看写binary IO 文件网友用fwrite,那socket 可以用 fwrite吗?socket io 我看是用write多一点,没见过用fwrite的 3. C怎么做serialization? 4. 可以serialize 一个函数吗 5. 当我们serialize一个 C++的类instance的时候,我们写的是什么?肯定跟serialize C struct有区别,因为C struct 只有数据(通常)? 6. Sizeof 好像也有 portable的问题? 7. vector矢量计算是到底是个什么几把东西 动态语言,反射(reflection),serialization,json,codegen,register,protobuf,rpc call, rpc protocol (GRPC) c++ 反射分静态反射和动态反射。现在有一些静态反射的提案 举个例子: ``` // 用户可以定义一些类型 struct X { int a; string b; }; // 这个时候库作者可能希望有一种机制,能够在编译期获取任意一个类型的一些属性,比如这个类型有哪些 fields,有哪些成员函数,这就属于静态反射的范畴 // 类似这种 for...(auto f : std::experimental::refl<X>::fields ) { // do something for f } 现在 c++ 任意写一个类类型之后,库作者没有什么非侵入性的方法读取类里有哪些属性和方法。protobuf 就是用一个 dsl 去生成一堆 c++ 代码,这样就绕过了这个问题。可以看到光标。还没有,有一些提案。 比如自动生成序列化函数 for...(auto f : std::experimental::refl<X>::fields ) { encode(f); } 可以啊,你可以对不同的类型定义不同的行为 encode<int> { ... } encode<string> { ... } encode<some user-defined class> { // 静态反射获取属性名和属性类型,然后依次 encode } // 有了静态反射,就可以在编译期生成很多特定行为的代码 ``` 对,python 这种动态语言很容易做动态反射。因为 python 基本上可以认为没有编译期,所以都是动态的。它内存里就有一些 map(function name -> function code) 所以很容易做。但是 c++ 运行期是没有这些信息的。读的话就是比如 linux 的 binary interpreter + cpu (程序指针寄存器 之类的) JSON.stringify JSON.parse() 没有关系,JS 是脚本语言,里面的值很容易在各种格式之间互相转换 有点卡,没太听清 可以看到 序列化不一定需要反射参与,但是有了反射会更简单/灵活。 ```c++ 比如没有反射的话你可以定义一些 json 结构 struct Object { std::variant< std::map<string, Object>, // map (str -> Object) std::vector<Object> // array(Object) float, string > data; ... } 是的。因为这种是最通用的。嗯,这个库和反射没什么关系 上面这种 key 是存在 map 里的,是运行期的 下面的 key 是编译期确定的 那就用上面那种结构吧,上面这种结构是动态的,没有 schema 的 应该是。没有,我推荐一个 C++ json 库 https://github.com/nlohmann/json 写起来、用起来非常自然(比 miloyip 那个 rapidjson 好用多了) 我的观点是,既然都用 json 了,估计不怎么关心性能,那就以好用为主 rapidjson 总是吹性能,但是不好用 那个 json 库怎么使用吗你是说?很简单的,看 readme 就行 类似这样一个(递归的)结构。 这样你可以定义 encode to json 和 decode from json 函数 但是有了反射之后可能你可以直接让用户定义一些简单的 class 来表达 schema struct Data { int x; std::vector<string> y; } 然后在编译期生成怎么 encode / decode Data 这个类型。 可能 Data a{1, {"a", "b"}} // c++ 可以 encode 成 {"x": 1, "y": ["a", "b"]} // json 这是需要有静态反射的,因为没有的话你很难知道 x 和 y 的 symbol name。 对,这些信息在 c++ 运行期是没有的。 对,c++ 这种编译型语言不需要很多 metadata 就能运行 java 不太一样,java 是编译到 vm 的。java 那个反射是动态反射,反射数据是在运行期取得的。 其实更重要的是用一种语言本身就有的特性规定 schema。就如果 decode 的时候出现了一个名字是 "c" 的 key 就会进入错误处理流程 ``` c++? 对,c++类 <--> JSON sh 怎么挂了 https://stackoverflow.com/a/2376224/5983841 这个问题就很显然了,你如果想要把任意一个 c++ 对象序列化,你就要知道这个对象有什么属性,这些属性什么类型。这是需要有反射才能知道的。 ``` struct A { char a[30], b[25], c[15]; int x; struct B; string c; void to_json(){ //this 遍历所有成员变量,然后调用一个 预先约定好的方法,拼成json // 用 for 需要有反射,你得一个一个属性自己 encode // 不用 for 就好了 for(auto data_member: ?){ //反射 is needed there //这里需要的是动态反射是吗? 一般是静态反射,因为效率高一些,可以在编译期展开。你在编译期获取到一个类型的 field,就可以在编译期展开这个循环。运行期就不需要循环了。嗯,就直接展开成 body 了 for(f: ...) do(f) -> do(f1); do(f2); do(f3); 不需要 if else 啊,我在编译期就知道 f 有三个,选择用哪个 do 函数是编译期的。如果有了静态反射,可以做一个动态反射的库。也不一定,java 就只有动态反射,静态反射编译器没暴露出来或者有些情况下做不到。差不多。本质上就是静态反射可以用来生成代码。 auto json_str = B.to_json(); } str += "\"a\":" + to_json(a) + ","; str += "\"c\":" + to_json(c) + ","; ... // 可以啊,但是这样太麻烦了,一大堆重复无意义的代码 from_json 会更麻烦,因为需要 parse 讲哪里 } } A.to_json() // 这是需要反射的,通过反射去生成一个特定的 to_json 函数 ``` 加上等号有行号 ```python= a = {"name": "tttt", "age": 17} # 这个比较像我上面写的那个 Object 类似的东西,是完全动态的,没有在运行期限定类型 json.dumps(a) class X : # sorry ... b = {"a": X()} # 这样也是可以的,么有限定类型(X() 是 X 类型的临时对象啊) ``` 对,c++ 也可以这样 ```c++ struct A{ virtual X encode() = 0; } 就是你可以强制让每个想被序列化的类型都提供 to_json 之类的方法(或者就给所有(基本/非基本)类型都重载 to_json 函数,不用方法) 然后再给基本类型重载 to_json 之类的函数,但是没有反射会特别麻烦 auto to_json(int) auto to_json(const X&) 或者你就 template <typename T> auto to_json(const T& v) { return v.to_json() } 然后重载基本类型的函数 auto to_json(int) { ... } auto to_json(float) { ... } 这样你就可以写成 to_json 方法了 类似的方法, 但是 protobuf 会复杂很多 protobuf 是通过 dsl 生成 c++ 代码的,可以理解为生成很多 to_json / from_json 方法 领域特定语言 就写了一些 schema message Student { string id = 1; string name = 2; ... } 然后它可以生成一些 struct StudentEncoder 之类的 ``` a = {"className": "Foo"} b = JSON.parse(a) if(get) x = json.loads() if "a" in x: // do something 这样 这样就很麻烦,没有一种统一的 dispatch 机制 dispatch 就是从一些特定的 key 分发到不同的方法或者类型,可以想象成是 switch 之类的 因为二进制序列化没有一个唯一的很好的解决方案 现在除了 protobuf 还有 avro, flatbuffers, thrift 之类的 c++ 这种追求效率的语言 你如果推出一种官方的方案,可能别人也会去用更高效的方案。python 用户就不太敏感这些。 c++ 也可以啊 ``` std::map<string, std::variant<string, float>> a = { {"name", "tttt"}, {"age", 17} } ``` 然后你需要自己定义一个特定的 encode 函数 没有,c++ 标准库没有相关 json 的东西 c++ 用类定义这种 schema 是编译期的 schema。 js python 也可以有 schema,但是是运行期的一些 check,比如自己写一些方法去 check 返回出来的东西的格式(一些 if 之类的) 指针的话,有几种方法吧感觉。一种就是直接序列化指向的对象(to_json(*x));或者就是给一个 label(或者称为 symbol),然后最后给一个 symbol list。 是,不过一般这些协议不会考虑指针这种问题吧,这种问题太特定语言了。 JSON is a schema-less protocol. 嗯 protobuf 之所以需要 schema 是因为它序列化之后的 data 里面没有很多信息,然后这个 schema 本身就是元信息。比如 key name 在序列化后的 data 里面是没有。你需要通过 schema 来恢复这些信息 ``` struct StarBucks{ static const char className[20] = "StartBucks001"; } if(className == "StartBucks001"){ }elif (xxx){ }else{ } ``` char[20] + 前 20 个字节是 class name 吗,后面是这个类型的对象的二进制吗(其实不需要长度,因为 class name 就确定了长度,你可以有一个 class name 到 sizeof 的映射) 但是这样做有非常多的问题。首先,你的 struct 需要跨架构吗。不是,protobuf 最大的意义在于 schema 的版本变更管理,比如你在业务里需要在 schema 里删除或者加入一些新字段,这时候你如果直接存二进制的话,原来的那些客户端就不能用了(假设你更新了服务器代码的 struct)。你不能强制要求更新客户端。还有安全问题。不能跨架构、跨编译器。还有就是如果 struct 里有指针,这个序列化的结果就没有意义了。 ``` struct A { char *a, *b, *c; int d; } write(fh, ptr, sizeof(struct a)). read(fh, ptr, sizeof(struct a)) ``` 你 read 和 write 并不一定在一台计算机上啊。序列化的意义就在于通信。可以,但是意义不大。你怎么存动态数组呢,怎么存 map 呢。对,那就很返璞归真了,这个协议就没啥意义了。你自己写 encode 动态数组还是要关心数据的格式。 1. write 和 fwrite 的区别,我看写binary IO 文件网友用fwrite,那socket 可以用 fwrite吗?socket io 我看是用write多一点,没见过用fwrite的 x fwrite 本身就是针对文件的吧(unix 里一切皆文件) fwrite 有 buffer 吗 3. C怎么做serialization? x 4. 可以serialize 一个函数吗 x 5. 当我们serialize一个 C++的类instance的时候,我们写的是什么?肯定跟serialize C struct有区别,因为C struct 只有数据(通常)?x 没什么区别感觉 6. Sizeof 好像也有 portable的问题? x 7. vector矢量计算是到底是个什么几把东西 函数序列化就相当于做一个脚本语言了。你把脚本语言代码传过去,然后在那边解释执行。 就是你两边要有同一个解释器。然后代码互相传,用同一个解释器解释执行。 所以动态语言,脚本语言,是不是可以理解为有一个living thing在那里的,类似一个,活着的编译器? ``` struct StarBucks{ static const char className[20] = "StartBucks001"; char b[100] customer; void doTransation(){ this.sendMoneyTo(this.customer); } } ``` protocol: char[20] + "doTransation" + id ``` map<id, StarBucks> ``` 这是不是就是一种RPC call restful就是语义化get, post ,put ,delete的http 的意思呗 是非常简陋、原始的 rpc restful 也可以理解为一种 rpc 嗯 grpc 首先是用 protobuf 做为协议 rpc 对比一般的程序里的 call,不同的地方就是要通过网络,所以要考虑的事情会多很多:这次请求会不会失败?失败了要不要再发一遍?还有就是 grpc 有 streaming 功能,可以持续的发送一串数据,在发送的同时那边就可以进行处理(不必等待都发完,是交互式的)肯定能做到类似的事情,但是不高效/写起来很复杂。 动态反射就是运行期获取一些 metadata,或者是获取某个对象的实际的类型而非声明的类型。算是。 python debug的时候,可以写type(a)以及dir(a) gpu? 矢量计算我觉得就是指的比如矩阵的计算吧 不一定要用 gpu,也可以用 cpu,只是 gpu 会算的快一些 gpu 可以同时并行几百个线程 ok hao 拜拜

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully