目录

前言 1.1

计算机编程领域 1.2

版本号命名和版本发布 1.2.1

长期支持版本 1.2.2

命令行终端 1.2.3

Help查看帮助信息 1.2.4

Next Generation 1.2.5

i18n和l10n 1.2.6

知识技能图谱 1.2.7

编译和链接 1.2.8

硬件和嵌入式领域 1.3

上层软件领域 1.4

debounce防抖动 1.4.1

库/包的依赖管理工具 1.4.2

配置文件名为xxxfile 1.4.3

Cheat Sheet和Handout 1.4.4

awesome xxx 1.4.5

上层软件 - 数据库 1.4.6

schema模式 1.4.6.1

各种编程语言领域 1.5

print打印 1.5.1

log日志 1.5.2

async和wait 1.5.3

getter和setter 1.5.4

编程语言 - Python 1.5.5

adapter适配器 1.5.5.1

附录 1.6

参考资料 1.6.1

前言

计算机编程通用逻辑知识概念

最新版本：v3.2

更新时间：20231213

简介

计算机和编程等领域内存在很多跨语言，跨领域的通用知识，现整理出来，供参考。

源码+浏览+下载

本书的各种源码、在线浏览地址、多种格式文件下载如下：

HonKit源码

crifan/program_common_logic: 计算机编程通用逻辑知识概念

如何使用此HonKit源码去生成发布为电子书

详见：crifan/honkit_template: demo how to use crifan honkit template and demo

在线浏览

计算机编程通用逻辑知识概念 book.crifan.org

计算机编程通用逻辑知识概念 crifan.github.io

离线下载阅读

计算机编程通用逻辑知识概念 PDF

计算机编程通用逻辑知识概念 ePub

计算机编程通用逻辑知识概念 Mobi

版权和用途说明

此电子书教程的全部内容，如无特别说明，均为本人原创。其中部分内容参考自网络，均已备注了出处。如发现有侵权，请通过邮箱联系我 admin 艾特 crifan.com，我会尽快删除。谢谢合作。

各种技术类教程，仅作为学习和研究使用。请勿用于任何非法用途。如有非法用途，均与本人无关。

鸣谢

感谢我的老婆陈雪的包容理解和悉心照料，才使得我crifan有更多精力去专注技术专研和整理归纳出这些电子书和技术教程，特此鸣谢。

其他

作者的其他电子书

本人crifan还写了其他150+本电子书教程，感兴趣可移步至：

crifan/crifan_ebook_readme: Crifan的电子书的使用说明

关于作者

关于作者更多介绍，详见：

关于CrifanLi李茂 – 在路上

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 16:00:32

计算机编程领域

计算机编程领域

此处介绍计算机编程领域内的一些通用知识、逻辑和概念。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

版本号命名和版本发布

版本号命名和版本发布

版本号命名规范

比如每次发版本的app，如果只是小功能更新，则只是第二位加1（或根据功能数量决定），否则大的版本的改进，则是第一位加1

Configuration · GitBook Toolchain Documentation

是有个官网推荐的做法的：

Semantic Versioning 2.0.0 | Semantic Versioning

其解释是：

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version: when you make incompatible API changes,

MINOR version: when you add functionality in a backwards-compatible manner, and

PATCH version: when you make backwards-compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

中文版翻译是：

语义化版本 2.0.0

版本格式：主版本号.次版本号.修订号，版本号递增规则如下：

主版本号：当你做了不兼容的 API 修改，

次版本号：当你做了向下兼容的功能性新增，

修订号：当你做了向下兼容的问题修正。

先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面，作为延伸。

现在个人的常见做法是：

主版本：有重大功能更新

比如多加了一个大的功能模块

次版本：有一些重要更新

比如部分功能有重大优化

补丁版本/小版本：细节的优化

比如一些小功能的优化，修复了一些小bug等等

版本发布的一些实践和做法

对于发布新版本，去写更新日志时，其形式可以借鉴jeesite的做法：

其效果很醒目，且点击每条可以展开显示详情

但是建议关键字还是用个人目前常用的做法：

新增：增加了新功能

修复：修复了之前存在的bug和问题

优化：改进，优化了已有的东西

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

长期支持版本

长期支持版本LTS

LTS=Long Term Support=长期支持

背景

在软件领域内，很多的软件，发布的版本，随着时间的流逝，很多软件会发生很多可能，其中很大的可能是，过了一段，或许可以称为足够长的时间后，该版本的软件，已经不被原先的发布商所支持了。导致依赖于此版本的软件的其他软件，变得不可用了。这种现象，尤其是在大的软件和系统中比较常见。

解决办法

对此，大的软件发布商为了告诉其他人说，我发布的某某版本的某个软件，会长期支持，不会中断，保持一定成程度的稳定，可以被信任，则此版本的软件，往往就叫做LTS，长期支持版本。

比如：

Ubuntu的LTS版本

Ubuntu就发布过很多个LTS的版本，比如Ubuntu 12.04 LTS

详见：LTS - Ubuntu Wiki

Node.js的LTS版本

Node.js的也有LTS版本

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

命令行终端

命令行终端

计算机领域内，常常会提及到终端，也叫做命令行，往往指的是：

Windows中的cmd

Linux中的shell

Mac中的terminal

然后还有很多第三方的扩展、工具或插件，用于增强或替换系统自带的终端，比如：

Windows的Power Shell

Linux/Mac的zsh

Mac的iTerm

终端能用来做什么

答 运行各种脚本和命令，完成各种任务

而对于linux的shell来说，功能强大到都算作一门单独的语言: shell脚本语言

可以利用不同的语法和函数，编写复杂逻辑的代码，实现特定的功能

比如小功能：

自己的批量重命名的shell脚本

TODO: 把脚本找到 贴出来

比如，其他人用shell去给OpenWrt的极路由去写应用：

开发极路由云插件 - OpenWrt.io

比如：

在linux mac win 下运行我的python脚本BlogsToWordpress

用vi在无图形界面的centos中编辑文本文件

各种终端的用法 心得

下面来介绍各种不同的终端的各种用法和心得。

Windows中的终端

Windows自带的cmd

TODO: 把之前那个cmd心得的帖子整理过来

Windows中的Hyper Terminal

嵌入式中都有和终端有关的工具使用

嵌入式开发期间，会遇到把开发版中运行程序的输出打印显示出来，以及输入和命令执行，也需要用到终端。

有时候Windows自带的terminal也够用，但是Win7中有个更好用一点的：Hyper Terminal

详见：【整理】如何在Win7中安装使用超级终端Hyper Terminal – 在路上

Mac的中的终端

Mac中自带的terminal

Mac中的iTerm2

TODO: 整理mac的iterm2的好用之处

Linux的shell

linux shell编程

shell入门

快速有个了解和概念：

Shell脚本编程30分钟入门

完整和深入的学习

Shell 教程 | 菜鸟教程

Linux Shell脚本教程：30分钟玩转Shell脚本编程_Shell中文网

其它还可以的资料

LINUX与UNIX Shell编程指南

Shell编程基础 - Ubuntu中文

详细介绍Linux shell脚本基础学习(一) - 雪洁 - 博客园

英文不错的话，直接看英文

比较系统的英文教程

Advanced Bash-Scripting Guide

BashGuide - Greg's Wiki

其它更加全面的，更加系统的书籍

《UNIX Shells by Example Fourth Edition》

chm版本下载：Prentice.Hall-Unix.Shells.By.Example,4th.Edition.chm_微盘下载

Linux Command Line and Shell Scripting Bible第三版

对于Shell有了基本的了解和实践之后，再去看

Shell脚本编程的常识

这些往往是经常用到，但是各种网络上的材料都语焉不详的东西，个人认为比较有用）

支持多平台的SecureCRT

当然，远程操作（CentOS等）Linux类系统，也是通过终端类等工具去操作的

比如常用的SecureCRT

TODO：把【crifan推荐】支持多种协议的串口开发工具：SecureCRT

【crifan推荐】极佳的串口开发工具：SecureCRT – 在路上

整理过来。

其他环境中的终端

IDE工具中集成的终端

其他第三方工具，尤其是IDE，为了方便开发同时集成了终端

比如 VSCode PyCharm

详见 TODO： ide总结的帖子

Android的app去模拟终端

【已解决】android中的shell命令行工具 – 在路上

以便于我们在手机中通过终端去操作系统的资源，实现各种复杂的功能

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

Help查看帮助信息

Help查看帮助信息

用help查看帮助信息

用help获取主命令和子命令的帮助信息

想要搞懂命令的基本语法，可以用：

some_command --help

或：

some_command help

甚至是命令下面的字参数，子命令的更详细的语法，可以用：

some_command help sub_command

往往可以输出对应的命令的帮助信息

举例：

嵌入式的uboot的语法

U-Boot: Quick reference - CompuLab Wiki

help - print online help

-> help xxx

可以输出子命令的具体的详细的语法

xxx是uboot的子命令，比如ls，cp，md等等

iOS中包管理器Carthage的语法

Carthage/Artifacts.md at master · Carthage/Carthage

Carthage/Carthage: A simple, decentralized dependency manager for Cocoa

licrifandeMacBook-Pro:Zzz crifan$ carthage help
Available commands:

   archive           Archives built frameworks into a zip that Carthage can use
   bootstrap         Check out and build the project's dependencies
   build             Build the project's dependencies
   checkout          Check out the project's dependencies
   copy-frameworks   In a Run Script build phase, copies each framework specified by a SCRIPT_INPUT_FILE environment variable into the built app bundle
   fetch             Clones or fetches a Git repository ahead of time
   help              Display general or command-specific help
   outdated          Check for compatible updates to the project's dependencies
   update            Update and rebuild the project's dependencies
   version           Display the current version of Carthage

licrifandeMacBook-Pro:Zzz crifan$ carthage help build
Build the project's dependencies

[--configuration (string)]
the Xcode configuration to build

[--platform (platform)]
the platforms to build for (one of ‘all’, ‘Mac’, ‘iOS’, ‘watchOS’, 'tvOS', or comma-separated values of the formers except for ‘all’)

[--derived-data (string)]
path to the custom derived data folder

[--no-skip-current]
don't skip building the Carthage project (in addition to its dependencies)

[--color (color)]
whether to apply color and terminal formatting (one of ‘auto’, ‘always’, or ‘never’)

[--verbose]
print xcodebuild output inline

[--project-directory (string)]
the directory containing the Carthage project

[[]]
the dependency names to build

苹果的Swift编译器swiftc

之前在：

［已解决］Xcode项目编译出错：Command failed due to signal: Segmentation fault: 11

期间，注意到点苹果的swift语言的编译器swiftc，对应help结果是：

➜  crifanLib git:(master) swiftc --help
OVERVIEW: Swift compiler

USAGE: swiftc [options] <inputs>

MODES:
  -dump-ast              Parse and type-check input file(s) and dump AST(s)
  -dump-parse            Parse input file(s) and dump AST(s)
  -dump-scope-maps <expanded-or-list-of-line:column>
                         Parse and type-check input file(s) and dump the scope map(s)
  -dump-type-refinement-contexts
                         Type-check input file(s) and dump type refinement contexts(s)
  -emit-assembly         Emit assembly file(s) (-S)
  -emit-bc               Emit LLVM BC file(s)
...
  -parse                 Parse input file(s)
  -print-ast             Parse and type-check input file(s) and pretty print AST(s)
  -typecheck             Parse and type-check input file(s)

OPTIONS:
  -api-diff-data-file <path>
                          API migration data is from <path>
  -application-extension  Restrict code to those available for App Extensions
  -assert-config <value>  Specify the assert_configuration replacement. Possible values are Debug, Release, Unchecked, DisableReplacement.
...
  -whole-module-optimization
                          Optimize input files together instead of individually
  -Xcc <arg>              Pass <arg> to the C/C++/Objective-C compiler
  -Xlinker <value>        Specifies an option which should be passed to the linker

sftp命令不了解，用help去查看有哪些命令

之前：

【已解决】命令行中ftp操作上传到远程服务器crifan.com

期间，对于sftp的命令有哪些不是很了解，所以可以通过help去查看：

sftp> help
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
chgrp grp path                     Change group of file 'path' to 'grp'
chmod mode path                    Change permissions of file 'path' to 'mode'
chown own path                     Change owner of file 'path' to 'own'
df [-hi] [path]                    Display statistics for current directory or
                                   filesystem containing 'path'
exit                               Quit sftp
get [-afPpRr] remote [local]       Download file
reget [-fPpRr] remote [local]      Resume download file
reput [-fPpRr] [local] remote      Resume upload file
help                               Display this help text
lcd path                           Change local directory to 'path'
lls [ls-options [path]]            Display local directory listing
lmkdir path                        Create local directory
ln [-s] oldpath newpath            Link remote file (-s for symlink)
lpwd                               Print local working directory
ls [-1afhlnrSt] [path]             Display remote directory listing
lumask umask                       Set local umask to 'umask'
mkdir path                         Create remote directory
progress                           Toggle display of progress meter
put [-afPpRr] local [remote]       Upload file
pwd                                Display remote working directory
quit                               Quit sftp
rename oldpath newpath             Rename remote file
rm path                            Delete remote file
rmdir path                         Remove remote directory
symlink oldpath newpath            Symlink remote file
version                            Show SFTP version
!command                           Execute 'command' in local shell
!                                  Escape to local shell
?                                  Synonym for help
sftp>

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:58:11

Next Generation

Next Generation

有些软件，代码，功能，在开发了新一代，下一代，功能更好更强的版本后，有的会以Next Generation去命令。

比如之前的：

嵌入式的交叉编译的工具crosstool-ng

crosstool 的下一代，新一代版本，叫做：crosstool-ng

用于科学上网的shadowsocks的Mac版本Shadowsocks-NG

之前叫做ShadowsocksX，其新版本，下一代，叫做Shadowsocks-NG

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

i18n和l10n

i18n和l10n

在开发软件、APP时，往往会涉及到除了支持中文之外，还要支持其他国家的语言，比如英语、法语、德语等等，专业叫法叫做：多国语言（版本）或者国际化

而在谈论多国语言、国际化时，常常会遇到这个词：i18n

其实i18n==internationalization == 国际化 == 多国语言

-> 之所以这么叫是由于internationalization单词太长，把中间的18个字母internationalizatio省略掉，简写为了i18n

和i18n的类似的含义的类似叫法还有：l10n== localization== 本地化

举例：

之前见过的： python-babel/flask-babel: i18n and l10n support for Flask based on Babel and pytz

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

知识技能图谱

知识技能图谱

在学习不同领域的技术时，往往会发现，不同领域所需要学习的内容和方向差距还是很大的，感觉算是隔行如隔山，换个技术领域和方向，很多名词甚至都没听说过。

另外，在某个领域有了深入专研之后，往往可以总结出很多该领域相关的技术和名词，整理出成系统的内容，往往就叫做该领域的技术图谱，知识图谱，技能树，技术成长路线图。

TeamStuQ/skill-map: 程序员技能图谱

这个TeamStuQ/skill-map: 程序员技能图谱中已经整理了几十个领域的技能图谱了，此处就不再做重复劳动，请移步去看即可。

此处把其他一些人制作的的图谱整理如下，供参考：

前端开发 知识图谱

QzhouZ/Front-End-Study: 前端开发基础知识学习

[JacksonTian/fks: 前端技能汇总 Frontend Knowledge Structure]https://github.com/JacksonTian/fks

机器学习算法工程师

计算机视觉工程师

自动驾驶工程师

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

编译和链接

编译和链接

此处介绍编译和链接方面的通用的知识、概念和逻辑。

之前接触过嵌入式和Linux，断断续续接触过很多编译和链接的东西，主要是命令行界面中用makefile、gcc等各种工具去做编译和链接的工作。

后来又接触过移动端开发，包括Xcode等IDE集成开发环境

编辑器和IDE

详见：【整理Book】文本编辑器和IDE集成开发环境

发现其实IDE背后都是利用了编译和链接方面的通用知识。

对此编译和链接方面的通用的知识、逻辑、概念，去尝试总结，以供参考。

Xcode中底层是用swiftc去编译swift代码

之前在：

［已解决］Xcode项目编译出错：Command failed due to signal: Segmentation fault: 11

期间，通过错误的log中的：

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -incremental -module-name XxxApp -Onone -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk -target i386-apple-ios9.0 -g -module-cache-path /Users/crifan/Library/Developer/Xcode/DerivedData/ModuleCache -Xfrontend -serialize-debugging-options -enable-testing -I /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Products/Debug-iphonesimulator -F /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Products/Debug-iphonesimulator -F /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/Carthage/Build/iOS -c -j4 /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/XxxApp/CrifanLibHttp.swift
...
/Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/XxxApp/CrifanLibDemo.swift /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/XxxApp/AddTaskViewController.swift -output-file-map /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/Objects-normal/i386/XxxApp-OutputFileMap.json -parseable-output -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/Objects-normal/i386/XxxApp.swiftmodule -Xcc -I/Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/XxxApp-generated-files.hmap -Xcc -I/Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/XxxApp-own-target-headers.hmap
...
-Xcc -I/Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/DerivedSources/i386 -Xcc -I/Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/DerivedSources -Xcc -DDEBUG=1 -emit-objc-header -emit-objc-header-path /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Intermediates/XxxApp.build/Debug-iphonesimulator/XxxApp.build/Objects-normal/i386/XxxApp-Swift.h -import-objc-header /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/XxxApp/XxxApp-Bridging-Header.h -Xcc -working-directory/Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS

而知道：

用的swiftc这个编译器，传递的参数是：

要编译的是：各个swift文件

输出是：XxxApp

期间利用到的各种：

SDK库是：-sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk

include的头文件的路径是：-I xxx

等等

即：

对于Xcode这个IDE，你点击了编译按钮后，内部的实际过程是：

调用swiftc这个编辑器去swift代码，期间涉及到

引用哪些库

设置哪些编译参数

引用include哪些头文件: xxx.h

包含哪些路径

去哪些路径中寻找头文件：-I xxx

去哪些路径中寻找所要包含的库文件:-L xxx

设置哪些环境变量

供后续过程去调用

-> 而这些都是编译和链接方面的通用知识。

-> 而其他的IDE的功能的内部过程大同小异，只不过用了不同的编译器，链接参数不同而已。

-> 而编译链接方面的知识，越是接近于底层开发，越是接触的多，理解的深入，比如嵌入式开发，Linux开发等等

-> 而对于编译和链接这方面的知识，如果之前折腾过嵌入式，Linux开发等方面的内容，则更能深切的体会到各种编译器、等内容。

Xcode中通过设置头文件搜索路径而解决了头文件引用找不到的问题

比如：

【已解决】Xcode9代码出错：Realm/Realm.h file not found with angled include use quotes instead

期间，对于错误提示：

<Realm/Realm.h> file not found with angled include use quotes instead

如果对于编译链接知识不了解的话，则很容易被误导，而去一个个的修改（对应的几十个）swift文件，把：

<Realm/Realm.h>

改为：

Realm/Realm.h

但是却没能从根本上解决问题。实际上是，搜索头文件的路径却少了，需要去设置：

Headers Search Paths

把Realm的头文件的路径，添加进去，即可真正彻底解决头文件找不到的问题。

Xcode中如何引入已改名的和已改变链接方式的库

之前在：

【已解决】Xcode9.2编译出错：ld library not found for -lMobClickLibrary

就遇到：

一个第三方库：友盟统计

之前是3.6.6的的静态库：libMobClickLibrary.a

现在版本升级为4.0.1，且功能拆分为2个库文件了，且是动态库：

统计功能的Analytics：UMMobClick.framework

社交功能的Social

所以，搞清楚这点后，才知道去把Xcode中的： Build Settings-》Linking-〉Other Linker Flags 中的： -l"MobClickLibrary" 改为： -framework "UMMobClick" 表示：引入新的UMMobClick的framework动态库，解决： ld library not found for -lMobClickLibrary 的问题。

苹果的swiftc编译器和-j4多线程编译

之前在：

［已解决］Xcode项目编译出错：Command failed due to signal: Segmentation fault: 11

期间，看到错误的log中的：

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -incremental -module-name XxxApp -Onone -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk -target i386-apple-ios9.0 -g -module-cache-path /Users/crifan/Library/Developer/Xcode/DerivedData/ModuleCache -Xfrontend -serialize-debugging-options -enable-testing -I /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Products/Debug-iphonesimulator -F /Users/crifan/Library/Developer/Xcode/DerivedData/XxxApp-fxzzwvtqreanqsgzqmztnatyyjjd/Build/Products/Debug-iphonesimulator -F /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/Carthage/Build/iOS -c -j4 /Users/crifan/dev/dev_root/daryun/Projects/Xxx/Zzz/Sourcecode/XxxAppiOS/XxxApp/CrifanLibHttp.swift

其中有-j4，猜测估计是类似于之前Linux中makefile中的make的-j4，估计是4个线程去并行执行的效果。

所以先去看看对应的编译器 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc

结果是：

➜  crifanLib git:(master) swiftc --version
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
Target: x86_64-apple-macosx10.9

果然是苹果的Swift语言的编译器。然后再去：

➜  crifanLib git:(master) which swiftc
/usr/bin/swiftc

可以看到，此处swiftc编译器是放在常见的/usr/bin目录下面的

再去通过：

➜  crifanLib git:(master) swiftc --help
...
  -I <value>              Add directory to the import search path
  -j <n>                  Number of commands to execute in parallel
  -L <value>              Add directory to library link search path
  -l<value>               Specifies a library which should be linked against
...
  -Xcc <arg>              Pass <arg> to the C/C++/Objective-C compiler
  -Xlinker <value>        Specifies an option which should be passed to the linker

中的： -j <n> Number of commands to execute in parallel

可以看到： -jN表示用多少个命令并行执行

-> 和Make中的-j是类似的效果。

-> 另外，此处也说明了对于Xcode这个IDE，内部编译代码，链接库等操作，底层对应的逻辑，都是编译链接方面的知识，都是通用的。

-> 只不过用了不同的编译器，链接参数而异。

-> 而对于编译和链接这方面的知识，如果之前折腾过嵌入式，Linux开发等方面的内容，则更能深切的体会到各种编译器、库函数、参数、头文件、包含路径、环境变量等内容。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:58:42

硬件和嵌入式领域

硬件和嵌入式领域

对于硬件和嵌入式领域内的一些通用知识、概念和逻辑，已整理出独立教程，详见：

硬件和嵌入式通用逻辑知识概念

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

上层软件领域

上层软件领域

此处介绍上层软件领域内的通用知识、概念和逻辑。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

debounce防抖动

debounce防抖动

debounce的英文是防反跳，也叫防止误动作、防抖动

典型的用途有，键盘按键的去抖动，防抖动

类似的写前端页面时常会遇到类似的场景：

用户输入要搜索的文字而触发搜索，调用后台接口去返回数据，然后前端页面列表刷新显示

但是如果每次输入一个字符后就立刻触发后台搜索，则往往在一次性输入多个字符串时会导致中间的无效搜索，也会导致性能浪费和界面卡顿。

解决办法是：

当用户输入一个字符时，延迟触发搜索，比如延迟500ms：

在500ms内，如果用户没有在继续输入，再去调用接口返回搜索结果

在500ms内，如果用户又继续输入其他字符了，则重新触发，重新计算，再延迟500ms判断是否输入

由此可以实现：

不论用户是一次性只输入单个字符串，还是一段时间内连续输入多个字符串，最终都只是触发一次搜索，返回结果，刷新页面，使得用户体验很好。

对于上述逻辑，可以自己写代码实现：

在获得用户输入的事件时，设置一个定时器，计算倒计时。

也可以利用：

这个概念本身叫做debounce

有第三方库帮忙实现这个debounce的效果，比如lodash的debounce

比如之前写的：ReactJS中实现，延迟搜索的效果的代码：

import { h, Component } from 'preact';
import style from './style.less';
import PropTypes from 'prop-types';

import _ from "lodash";

export default class Search extends Component {
  state = {
    value : null
  }

  constructor(props) {
    super(props);

    this.onInput = this.onInput.bind(this);
    this.onClick = this.onClick.bind(this);
  }

  componentWillMount() {
    this.delayedOnInput = _.debounce(this.props.onInputChange, this.props.debounceTimeout);
  }

  onInput(e){
    this.setState({value : e.target.value});

    e.persist();
    this.delayedOnInput(this.state.value);
  }

  onClick(e){
    if (this.props.onClick) {
      this.props.onClick(e);
    }
  }

  render () {
    return (
        <div class={style.cz_top_box}>
          <ul>
            <a>
              <li class={style.min_box}>
                <input
                  type="search"
                  value={this.state.value}
                  placeholder={this.props.placeholder}
                  onClick={this.onClick}
                  onInput={this.onInput} />
              </li>
            </a>
          </ul>
        </div>
    );
  }

}

Search.PropTypes = {
  debounceTimeout : PropTypes.number,
  placeholder : PropTypes.string,
  onInputChange : PropTypes.func.isRequired,
  onClick : PropTypes.func
};

Search.defaultProps = {
  debounceTimeout : 500,
  placeholder : "请输入"
};

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

库/包的依赖管理工具

库/包的依赖管理工具

在开发期间，往往需要使用别人的第三方的代码和功能。

而安装第三方库文件，理论上可以自己下载源码，自己编译得到自己要的库

但是后续的库的升级、管理依赖、维护都是个比较麻烦的事情。

所以出现了包管理工具，便于第三方库的安装和升级：

即：不同语言和环境，有不同的第三方的软件/库/包的管理工具，管理不同的版本，不同的依赖。

下面就来总结一下。

Python

pip

Javascript

npm

yarn

iOS

Cocoapods

Carthage

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

配置文件名为xxxfile

配置文件名为xxxfile

有很多技术、工具和框架，去给自己的配置文件命名的时候，用：xxxfile[.yyy]

比如：

前端开发

grunt：Gruntfile.js

gulp：guplfile.js

iOS开发

Carthage：Cartfile

Cocoapods：Podfile

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

Cheat Sheet和Handout

Cheat Sheet和Handout

Cheat sheet的含义

软件领域内的

Cheat sheet和handout的解释

－》Cheat，中文含义为：作弊，Sheet：中文含义为：表格，表单，小纸片

－》cheat sheet，中文含义为：（用于作弊）小抄

－》放在软件行业内，意思是：

就像考试作弊一样，把大量的内容，精简的，有机的排列在一张纸，一张图上

特点：

化繁为简

用途：

方便随时参考和查阅

尤其常见于，把各种软件，工具等的快捷键，主要功能等，总结后列在一张图片内，多数以图文并茂的表格，图表，图片等形式展现

概述：

某某（语言，工具等）的Cheat sheet ＝＝ 某某（语言，工具等）快速查阅的图表型的手册

handout的含义

另外的handout，中文本意：讲义；宣传册子，宣传品

－》往往有时候也可以认为：

cheat sheet == handout

Cheat sheet和handout的举例：

Cheat sheet举例

vi的cheat sheet

VI Editor / Linux Terminal Cheat Sheet (PDF) – Smashing Magazine

－》

VI-Help-Sheet-01-large2.jpg

Xcode的快捷键的cheat sheet

http://www.crifan.com/xcode_common_used_keyboard_shortcut

中的：

python的cheat sheet

python-cheat-sheet-v1.pdf

Python_qr.pdf

python:cours:mementopython3-english.pdf

Keep This Python Cheat Sheet on Hand When Learning to Code

go语言的cheat sheet

go-lang-cheat-sheet

HTML的cheat sheet

htmlcheatsheet.pdf

HTML Cheat Sheet - A Simple Guide to HTML

HTML5 Cheat Sheet - WebsiteSetup.org

HTML5 Cheat Sheet - WebsiteSetup.org

Font Awesome 的Cheatsheet

React Native折腾期间，需要利用到对应字体：‎fortawesome.github.io/Font-Awesome/icons/

-》

Font Awesome Cheatsheet

就列出了所有的字体图标

React 的cheat sheet

React Cheat Sheet

Emoji的cheat sheet

Emoji cheat sheet for GitHub, Basecamp and other services

Python的Pandas的cheatsheet

Pandas Cheat Sheet for Data Science in Python (article) - DataCamp

-》

PandasPythonForDataScience.pdf

Kotlin的cheatsheet

Kotlin 作为 Android 开发语言相比传统 Java 有什么优势？ - 知乎

Kotlin Programming Language Cheat Sheet Part 1

Kotlin Programming Language Cheat Sheet Part 2

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

awesome xxx

awsome xxx

对于很多技术，都有热心人去整理很多相关的优秀的资源，供开发者学习和使用，然后叫做awsome xxx

-> 换句话说：如果想要快速找到某个技术的优秀资源汇总，可以去google中搜awesome xxx，往往可以快速方便的找到你要的。

awsome Python

vinta/awesome-python: A curated list of awesome Python frameworks, libraries, software and resources

jobbole/awesome-python-cn: Python资源大全中文版，包括：Web框架、网络爬虫、模板引擎、数据库、数据可视化、图片处理等，由伯乐在线持续更新

awsome Django

haiiiiiyun/awesome-django-cn: Django 优秀资源大全

awesome iOS

vsouza/awesome-ios: A curated list of awesome iOS ecosystem, including Objective-C and Swift Projects

awesome Swift

matteocrippa/awesome-swift: A collaborative list of awesome Swift libraries and resources. Feel free to contribute!

Wolg/awesome-swift: A curated list of awesome Swift frameworks, libraries and software

Javascript

awesome ReactJS

enaqx/awesome-react: A collection of awesome things regarding React ecosystem

brillout/awesome-react-components: Catalog of React Components & Libraries

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

上层软件 - 数据库

上层软件 - 数据库

此处介绍上层软件领域内和数据库相关的通用知识、概念和逻辑。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

schema模式

schema模式

之前在数据库领域内就看到和提到了schema

MongoDB vs. Redis Comparison architecture - When to Redis? When to MongoDB? - Stack Overflow

想要去搞清楚，什么是schema

什么是schema

在数据库中，schema、catalog分别指的是什么？ - 知乎

对于mysql，schema和database可以理解为等价的.

As defined in the MySQL Glossary: In MySQL, physically, a schema is synonymous with a database. You can substitute the keyword SCHEMA instead of DATABASE in MySQL SQL syntax, for example using CREATE SCHEMA instead of CREATE DATABASE.

Some other database products draw a distinction. For example, in the Oracle Database product, a schema represents only a part of a database: the tables and other objects owned by a single user.

schema就是数据库对象的集合，这个集合包含了各种对象如：表、视图、存储过程、索引等。

如果把database看作是一个仓库，仓库很多房间（schema），一个schema代表一个房间，table可以看作是每个房间中的储物柜，user是每个schema的主人，有操作数据库中每个房间的权利，就是说每个数据库映射user有每个schema（房间）的钥匙。

schema是对一个数据库的结构描述。在一个关系型数据库里面，schema定义了表、每个表的字段，还有表和字段之间的关系。 catalog是由一个数据库实例的元数据组成的，包括基本表，同义词，索引，用户等等。”

Difference Between Schema / Database in MySQL - Stack Overflow

Depends on the database server. MySQL doesn't care, its basically the same thing. Oracle, DB2, and other enterprise level database solutions make a distinction. Usually a schema is a collection of tables and a Database is a collection of schemas.

Schema（数据库中的Schema）_百度百科

A schema is a collection of database objects (used by a user.). schema objects are the logical structures that directly refer to the database’s data. A user is a name defined in the database that can connect to and access objects. schemas and users help database administrators manage database security.”

数据库中Schema（模式）概念的理解

在学习数据库时，会遇到一个让人迷糊的Schema的概念。实际上，schema就是数据库对象的集合，这个集合包含了各种对象如：表、视图、存储过程、索引等。

如果把database看作是一个仓库，仓库很多房间（schema），一个schema代表一个房间，table可以看作是每个房间中的储物柜，user是每个schema的主人，有操作数据库中每个房间的权利，就是说每个数据库映射的user有每个schema（房间）的钥匙。

默认情况下一个用户对应一个集合，用户的schema名等于用户名，并作为该用户缺省schema。所以schema集合看上去像用户名。访问一个表时，如果没有指明该表属于哪个schema，系统会自动加上缺省的schema。一个对象的完整名称为schema.object，而不属user.object。

在MySQL中创建一个Schema和创建一个Database的效果好像是一样的，但是在SQL Server和Oracle数据库中效果又是不同的。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

各种编程语言领域

各种编程语言领域

此处介绍各种计算机编程语言方面的通用逻辑、知识和概念。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

print打印

print打印

在用不同语言开发时，往往会遇到，用print类的函数去打印log输出信息，用于调试。

嵌入式中常见的C等语言的打印都是printf

写Linux驱动时，Linux内核中的打印是printk

TODO： 1.把 2.2.1. 通用函数：print - - 计算机编程语言基础知识合并进来

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

log日志

log日志

在写代码开发期间，往往会涉及到打印Log日志。

在此总结log相关的内容。

日志 == log == Logger == logging

用来打印日志输出信息用于调试。

log的等级

log日志有一些常见的登记，最基本的几种有：

info: 用于输出一些阶段性的告知用户的信息，比如用户已成功登录之类的

debug: 用于调试目的，而输出一些信息，比如打印某些变量的值

warn/warning: 用于输出一些不正常的情况，需要引起用户注意了，比如app检测存储空间快满了

error: 显示一些错误级别的信息，往往意味着程序也要终止运行了。需要用户处理错误，或者退出程序之类的

其他不是很常见的几种：

finest/fine：表示程序正常级别输出的信息

trace: 类似于debug，用于输出一些追踪调试信息

verbose：事无巨细的，最详尽的信息

severe：严重的问题，类似于error

critical：关键的问题，类似于severe

log相关的库

log4xxx系列

有个通用的log的库：log4xxx

针对于不同语言的log4xxx分别是：

Java语言：Log4j

log4j

新版本：Log4j – Log4j 2 Guide - Apache Log4j 2

C语言：log4c

log4c

Go语言：log4go

alecthomas/log4go: Logging package similar to log4j for the Go programming language

微软的.NET框架（C#等语言）：log4net

Open Source Logging Tools in C#

Delphi语言：Log4Delphi

Welcome to Log4Delphi

C++: log4cpp

其他相关：

log4cplus

log4cxx

Python

Python的log库：自带的库logging

自己也整理和封装成基本的函数：

def loggingInit(filename = None,
                fileLogLevel = logging.DEBUG,
                fileLogFormat = '%(asctime)s LINE %(lineno)-4d %(levelname)-7s %(message)s',
                fileLogDateFormat = '%Y/%m/%d %I:%M:%S',
                enableConsole = True,
                consoleLogLevel = logging.INFO,
                consoleLogFormat = "%(asctime)s LINE %(lineno)-4d %(levelname)-7s %(message)s",
                consoleLogDateFormat = '%Y/%m/%d %I:%M:%S',
                ):
    """
    init logging for both log to file and console
    :param logFilename: input log file name
        if not passed, use current script filename
    :return: none
    """
    logFilename = ""
    if filename:
        logFilename = filename
    else:
        logFilename = getInputFileBasenameNoSuffix() + ".log"

    logging.basicConfig(
                    level    = fileLogLevel,
                    format   = fileLogFormat,
                    datefmt  = fileLogDateFormat,
                    filename = logFilename,
                    filemode = 'w')
    if enableConsole :
        # define a Handler which writes INFO messages or higher to the sys.stderr
        console = logging.StreamHandler()
        console.setLevel(consoleLogLevel)
        # set a format which is simpler for console use
        formatter = logging.Formatter(fmt=consoleLogFormat, datefmt=consoleLogDateFormat)
        # tell the handler to use this format
        console.setFormatter(formatter)
        logging.getLogger('').addHandler(console)

详见： https://github.com/crifan/crifanLib/blob/master/python/crifanLib.py

Flask

Python的Flask中也可以打印log

对应的代码： config.py

############################################################
# File Log
############################################################
LOG_FILE_FILENAME = "logs/sipevents.log"

LOG_FILE_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

__init__.py

import logging
from logging.handlers import RotatingFileHandler

fileHandler = RotatingFileHandler(
    app.config['LOG_FILE_FILENAME'],
    maxBytes = 2*1024*1024,
    backupCount = 3,
    encoding = "UTF-8")
fileHandler.setLevel(logging.DEBUG)

fileLogFormatterStr = app.config["LOG_FILE_FORMAT"]
fileLogFormatter = logging.Formatter(fileLogFormatterStr)
fileHandler.setFormatter(fileLogFormatter)
app.logger.addHandler(fileHandler)

run.py

from sipevents import app

if __name__ == '__main__':
    app.run(debug=True)

输出log的效果是：

[2016-09-02 16:59:25,938 DEBUG views.py:804 creat_event] requestMethod=GET

对应参数的解释是：

参数 | 输出效果
%(asctime)s | 2016-09-02 16:59:25,938
%(levelname)s | DEBUG
%(filename)s | views.py
%(lineno)d | 804
%(funcName)s | creat_event
%(message)s | requestMethod=GET

更加完整的参数解释是：

参数 | 含义解释
%(name)s | Logger的名字
%(levelno)s | 数字形式的日志级别
%(levelname)s | 文本形式的日志级别
%(pathname)s | 调用日志输出函数的模块的完整路径名，可能没有
%(filename)s | 调用日志输出函数的模块的文件名
%(module)s | 调用日志输出函数的模块名
%(funcName)s | 调用日志输出函数的函数名
%(lineno)d | 调用日志输出函数的语句所在的代码行
%(created)f | 当前时间，用UNIX标准的表示时间的浮点数表示
%(relativeCreated)d | 输出日志信息时的，自Logger创建以来的毫秒数
%(asctime)s | 字符串形式的当前时间。默认格式是"2003-07-08 16:49:45,896"。逗号后面的是毫秒
%(thread)d | 线程ID。可能没有
%(threadName)s | 线程名。可能没有
%(process)d | 进程ID。可能没有
%(message)s | 用户输出的消息

Swift

iOS的swift中也遇到过log库：XCGLogger

其中的log的定义是：

    /// Enum defining our log levels
    public enum Level : Int, Comparable, CustomStringConvertible {
        case verbose
        case debug
        case info
        case warning
        case error
        case severe
        case none

        ...
        public var description: String { get }
        public static let all: [XCGLogger.XCGLogger.Level]
    }

和基本的封装

import XCGLogger

func initLog() {
    gLog = XCGLogger.default//XCGLogger.defaultInstance()

    //var logLevel:XCGLogger.LogLevel = XCGLogger.LogLevel.debug

    var logLevel:XCGLogger.Level = XCGLogger.Level.debug
    if LogLevelIsVerbose {
        logLevel = XCGLogger.Level.verbose
    }

    var fileLogLevel:XCGLogger.Level = XCGLogger.Level.debug
    if FileLogLevelIsVerbose {
        fileLogLevel = XCGLogger.Level.verbose
    }

    gLog.setup(
        level: logLevel,
        showThreadName: true,
        showLevel: true,
        showFileNames: true,
        showLineNumbers: true,
        writeToFile: LogFile,
        fileLevel: fileLogLevel)
}

之后即可正常log了：

  gLog.info("UIScreen.mainScreen().bounds=\(UIScreen.main.bounds)")
  gLog.debug("forgetPasswordVC:\(forgetPasswordVC)”)
  gLog.warning("jpush set alias \(alias) failed")
  gLog.error("上传附件失败: \(encodingError)”)

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

async和wait

async和wait

Javascript中的async wait

JS的ES6/ES7？中有async wait

Python 3.3中也有async wait

待整理：使用 WebSocket 和 Python 编写日志查看器 | 张吉的博客

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

getter和setter

类的属性的getter和setter

之前接触计算机语言，比如C、C++等，都没有getter和setter的

后来接触到了一些语言：

C#

Swift

Python

其对象==类==Class中都有了属性Property的：

getter：读取属性的值

setter：设置（写入）属性的值

比如：

Python

Python的python - 新手学习Flask引用flask-login后登入错误原因不清 - SegmentFault 中的：

class Admin(UserMixin, db.Model):
    __tablename__ = 'admin'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True)
    password_hash = db.Column(db.String(128), unique=False)

    @property
    def password(self):
        raise AttributeError('不能直接获取明文密码！')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

编程语言 - Python

编程语言 - Python

此处介绍各种计算机编程语言中涉及Python方面的通用逻辑、知识和概念。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

adapter适配器

adapter适配器

Python开发期间，在使用第三方数据库等场景时，常会遇到apater这个概念。

driver驱动器 ≈ adapter适配器 ≈ binding粘合剂 ≈ wrapper封装

adapter/driver/binding/wrapper，指的是：

把一个别的功能，封装后，提供操作该功能的接口

起到了，作为粘合剂，把其他的库和你写的代码粘合起来效果

TODO：

1.把

【软件开发基础知识】binding和wrapper – 在路上

合并进来。

Python

Python的QT的driver

QT的库，对于Python语言来说，也有对应的driver

Python的PostgreSQL的driver

postgre的数据库，也有对应的driver

Python的MongoDB的driver

mongoDB也是有Python的driver

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

附录

附录

下面列出相关参考资料。

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17

参考资料

参考资料

学习 shell 有什么好书推荐？ - 知乎

Cheat sheet - Wikipedia, the free encyclopedia

销售易的CRM PaaS平台开发手册

log4go - GoDoc

Python - PostgreSQL wiki

MongoDB Drivers — MongoDB Ecosystem

最好用的前端开发工具之构建篇：Gulp_HTML5|CSS3_UDN技术社区

StuQ - 一个新的学习方式，提升你的IT职业技能

［已解决］Flask中输出log日志到文件且自定义输出格式

python 日志模块 logging 详解 - leejun2005的个人页面

开发者AI职业指南：CSDN《AI技术人才成长路线图V1.0》重磅发布

crifan.org，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2023-12-13 15:56:17