B asic
📦 Package Manager
?
composer 下载composer.pharsudo mv composer.phar /usr/local/bin/composer
npm npm install some_garbage
pip
-
🔍📦 Search Packages
?
packagist.org
npmjs
pypi
📄 Package Configure File
?
composer.json
package.json
-
Create Configure File
?
Automatic generate when install package
npm init (-y)
# 创建虚拟环境 python3 -m venv venv#激活虚拟环境 source venv/bin/activate# 取消激活 deactivate # 生成配置文件 pip freeze > requirements.txt
🔩 Install Package By Configure file
?
php composer.phar install sudo composer install
npm install | npm i
pip install -r requirements.txt
🔩 Install Package
?
php composer.phar require geoip2/geoip2:~2.0 or composer require geoip2/geoip2
npm i vuenpm i -g typescript typescript 强调type,类型检查 -g: Global --save-dev或-D 开发时依赖 --save(默认) 生产环境运行时依赖 npm uninstall vuenpm update vuenpm view vuenpm view vue versions
(linux)sudo pip install pymysql (win)python -m pip install pymysql (mac)pip install geoip2
Print Version
gcc -v
composer -V
node -vnpm -v vue -V
python3 -V python3 -m pip -V pip -V
Upgrade Package Manager
?
composer self-update
npm install npm -g
(linux)sudo pip install -U pip (win)python -m pip install -U pip
块分隔符
{ }
{ }
{ }
用缩进
if关闭fi do关闭done
语句分隔符
;
;
newline 或 ;
newline
newline 或 ;
单行注释
// comment
// comment
// comment
# comment
# comment
多行注释
/* comment line another line */
/* comment line another line */
/* comment line another line */
""" comment line another line """
-
资源(组件/模块)引用 include, import, require, source...
#include <stdio.h>
include|include_once|require|require_once
include 和 require 语句是相同的,除了失败:
require将产生致命错误 (E_COMPILE_ERROR) 并停止脚本
include只会产生警告(E_WARNING)并且脚本会继续
获取指定文件中的代码,并将其复制 到使用 include 语句的文件中(代码拼接,没独立作用域)
_once 表示只拼接一次,再次引用忽略
spl_autoload_register 注册自动加载函数,在使用未定义的类时触发自动加载,不再需要写include了
<script type="text/javascript" src="1.js"></script >模块化开发Demo <script type="module" src="m.js"></script > 浏览器对于带有 type="module" 的 script,都是异步加载 <script type="module">import { a, funca } from "./mymodule.js"funca (); </script > A web-page opened via the file:// protocol cannot use import / export.
import math # math.py脚本 math.pifrom math import pi,ceil #可以只导入pi或某些函数 pi #3.141592653589793 ceil (2.4) #3 Python的import并非像php include, 查看wiki
source other.sh
Namespace组织代码和避免命名冲突的技术
-
namespace GeoIp2\Database; ...class Reader implements ProviderInterface {}function Myfun() {}const MY_CONSTANT = 12;
没有命名空间概念,可使用模块化 的方式来实现类似的效果。每个模块都是一个独立的作用域// MyNamespace.js module.exports = MyNamespace
没有命名空间概念,Module实现命名空间效果# mymodule.py myvar = 12def myfunc():
-
使用命名空间
-
use GeoIp2\Database\Reader;use function GeoIp2\Database\Myfun;use const GeoIp2\Database\MY_CONSTANT; $reader = new Reader('xx'); Myfun(); echo MY_CONSTANT;
const MyNamespace = require ('./MyNamespace') MyNamespace.myFunction ()
import mymodule print(mymodule.myvar) mymodule.myfunc ()
V alue & Type
命名
区分大小写,可使用中文命名
变量常量名区分大小写,函数class名不区分,变量需$开头,可使用中文命名,比如 $数量=300
区分大小写,可使用中文命名
区分大小写,可使用中文命名
区分大小写,不可使用中文命名
基础数据类型
int i = 1; // 2 或 4 bytes 65536-4294967296 i = 2;float f; // 4 bytes f = 5.99;double lf = 5.99; // 8 bytes char c = 'M'; // 1 bytes printf ("%d-%f-%lf-%c\n", i, f, lf, c); // 2-5.990000-5.990000-M printf ("%d-%.2f-%.2lf-%c\n", i, f, lf, c); // 2-5.99-5.99-M printf ("%p-%p-%p-%p\n", &i, &f, &lf, &c); // 0x7ff7b3d0161c-0x7ff7b3d01618-0x7ff7b3d01610-0x7ff7b3d0160f printf ("%lu-%lu-%lu-%lu\n", sizeof (i), sizeof (f), sizeof (lf), sizeof (c)); // 4-4-8-1 单位bytes 基本格式说明符:对于int %d和%i都行,%p 打印内存地址, %s 用来打印字符串
int * p_i = &i;bool b = false
隐式/显式类型转换 float f = 8; // 隐式类型转换 编译器自动将8 转化为 8.000000 float r = 5 / 2;printf ("%f", r); // 2.000000 ,因为5 和 2 是int,5 / 2 结果也是int 为2,float隐式类型转换成2.000000 float r2 = (float ) 5 / 2; // 显示类型转换 int to float printf ("%f", r2); // 2.00000
整型 $i = 1;浮点型 $f = 1.234string $str = '';Boolean $b = FALSE ;null $v = NULL ;Object $bar = new foo ;
number型 var x = 0; // typeof(x)的值是"number" BigInt型 String (BigInt (1)+BigInt (Math.pow (2,53)))string型 var str = "";boolean型 var b=false;undefined型 var a = undefined object型 var car = null ; // typeof(car)的值是"object",null值是一个空的对象指针 var obj = {}; // 同= new Object();typeof值object var arr = []; // 同= new Array(); typeof值object var re=/regexp/g; // typeof值Object 同= new RegExp("regexp","模式修饰符g全局模式应用所有字符串,i区分大小写,m多行匹配") var foo = function () {} // typeof值function 引用(reference)值 分配给变量时,空间需要在堆(heap)上分配, 引用值不能像原始(primitive)值 直接分配在栈(stack)上,因为它没有固定的尺寸,所以它将内存地址存在栈上, 作为一个指针TypeScript let isDone: boolean = false let list: number[] = [1, 2, 3] // 数组 let list: Array<number> = [1, 2, 3] // 数组另一种表达 let x: [string, number] = ['s', 9]// 元组 enum Status { enable, disable }
let s = Status.enable
number型 x=0string型 str=""Boolean型 b = True # True/False 空型 NoneObject型 Ferrari458 = Car ('Ferrari',570)
bash中的所有变量都是string ,无论有没有加引号 有些变量被shell环境和OS环境来存储一些特殊的值,叫环境变量echo $PWD 还有PATH,USER,SHELL,HOME,UID(root为0)等常用环境变量
数据类型判断
-
echo gettype ("mark"); // string
typeof value==="undefined"var theHobbit = new Book ('07122-4', 'The Hobbit', 'J. R. R. Tolkein'); theHobbit instanceof Book; //值为true, 某类的实例
print (type (value))print (isinstance (12, int)) # True print (isinstance ('hi', str))print (isinstance ([1,2], list))
都是string
🌍 作用域
PHP是文件拼接 文件之间不是独立作用域 函数内不能读函数外的非全局变量 global 关键字可实现在函数内使用外部变量 $a=1;function b() { global $a; echo $a; } b(); 超全局变量$GLOBALS $GLOBALS['a'] = 1; 超全局变量还有$_SESSION $_SERVER $_GET $_POST $_REQUEST $_FILES $_COOKIE $_ENV
无var 申明, 都是全局的
window/self/globalThis (browser); self/globalThis (web worker);global/globalThis (Node.js) myglobal="hello"; myglobal; // 值为hello this .myglobal; // 值为hello window.myglobal // 值为hello
有var 局部变量,函数内可以沿着作用域链 调用外层变量
let, const 设置的变量/常量可限制在块级作用域 内使用 块级作用域围墙有{} | while (){} | if (){} | try {} catch (e){}| for (let i=0;i<10;i++){ 每一个循环都是一个作用域 }
var a = []for (let i = 0; i < 10; i++) { a[i] = function () { console.log (i); }; } a[6](); // output: 6 如果上面的let 改成var 他的结果就是10
如果没有let 怎么办 -->值变参分割变量作用域 for (var i = 0; i < 10; i++) { (function (i) { a[i] = function () { console.log (i); } })(i) }
执行上下文
local (默认): 局部变量nonlocal : 非局部变量,用于闭包 global : 全局变量
没有作用域,函数内外可互相访问 a="好"function display(){ b='玩' echo $a } display # 好 echo $b # 玩
闭包(closure) 闭包就是能够读取其他函数内部变量的函数
-
使用 use 关键词function counter () { $i = 0; return function () use (&$i) { return ++$i."\n"; } } $nays = counter()echo $nays()echo $nays()
var counter = function () { var i=0; return function () { return ++i; }; };var nays = counter(); console.log (nays()); // output: 1 console.log (nays()); // output: 2
def counter (): i=0 def foo (): nonlocal i # 申明非局部变量 i += 1 return i return foo nays = counter ()print (nays ()) # output: 1 print (nays ()) # output: 2
内存回收♻️
手动回收 malloc calloc等申请内存 free 释放内存
自动回收 以前引用计数(无法解决循环引用) 现在标记清除
自动回收以前引用计数(无法解决循环引用) 现标记清除+碎片🧩 整理
自动回收 先引用计数,定期标记清除(循环引用) 两种结合
判断变量是否存在
if (!empty ($v)){}//null 或未定义或''或0 或FALSE 为TRUE if (is_null ($v)){}//null 或未定义为TRUE if (isset ($v)) {}// 非null或已定义为TRUE
if (typeof (var_name)=='undefined') { //不存在 }
a='mark'print ('a' in globals ()) # True print ('a' in locals ()) # True print ('b' in globals ()) # False
if [ ! -n "$1" ]; then # 变量是否存在
获取资源类型
get_resource_type()
-
- -
变量的变量
$a='hello'; $$a='world';echo ${$a}; //等同于echo $hello; - - -
const常量是在程序运行时不会被修改的量 用大写字母是很好的做法
const float PI = 3.1416;
define定义的常量可跨脚本跨函数define ("PI", 3.14); // define()在函数里定义的常量在外面依然可使用 const PI='3.1416'; //const定义的必须处于最顶端的作用区域
const PI = 3.1416; PI = 3; // TypeError: Assignment to constant variable. const foo;// Uncaught SyntaxError: Missing initializer in const declaration if (true ) { const MAX = 5; } console.log (MAX) // Uncaught ReferenceError: MAX is not defined const的作用域与let相同,只在声明所在的块级作用域内有效 const a = {}; a.a = 1; 对象的属性能改变,const只能保证这个指针是固定的
没有常量
-
enum通常用来表示如color, type, status等数目有限、形式离散、表达明确的量
enum Level { LOW, MEDIUM, HIGH };enum Level myVar = MEDIUM;printf ("%d", myVar); // 1
enum LogLevel { ERROR, WARN, INFO, DEBUG, }
-
set value
$v = 1;$a=$b=3; var v = 1;var a=b=3建议使用下面的single var模式 a=1;b=c=3 myname=mark 注意等号=两边不能有空格,不然会被当成命令,如果值中间有空格就要加引号如"mark li" echo $myname echo 后面的字符中有空格可以不加引号
并行set value
list ($y,$z)=array (2,3); //把数组中的值赋给一些变量
var x=1,y=2,z=3字符串解构赋值 let [a, b, , c, d] = 'abcde'; // d == 'e' 数组解构赋值 let [, b, c] = [1, 2, 3]; // c == 3 Set数据解构赋值 let [a,,c]=new Set ([1,2,3]); // c == 3 对象解构赋值 let {x,y} = {z:2,y:3,x:4} // x == 4 y == 3 属性的解构赋值 let {length : len} = 'hello'; // len == 5 let [head, ...tail] = [1, 2, 3, 4];// tail=>[2,3,4]
a, b = b, a+b它不等于a=b;b=a+b或b=a+b;a=b -
🤹♀️ swap
list ($x, $y) = array ($y, $x);
var temp=a a=b b=temp [a,b]=[b,a];
-
-
Proxy 拦截
?
?
拦截对象 getter setter flashvim = {} Object.defineProperties (flashvim, { cmd: { configurable: true, get() { console.log ('拦截读值') return cmd }, set(newval) { cmd = newval console.log ('拦截设值') } } }) flashvim.cmd = 3 // 拦截设值
单个属性 Reflect.defineProperty (flashvim, "cmd", { configurable: true... // Object.defineProperty 官方建议弃用
拦截对象 getter setter
flashvim = new Proxy ({}, { get(target, key) { console.log ('拦截取',key, '的值') return target[key] }, set(target, key, newval) { console.log ('拦截设', key, '的值', newval) return target[key] = newval } }) flashvim.cmd = 3 // 拦截设 cmd 的值
拦截数组 getter setter
arr = [1,2,3]
proxyarr = new Proxy (arr, { get(target, key) { console.log ('拦截取',key, '的值') return target[key] }, set(target, key, newval) { console.log ('拦截设', key, '的值', newval) return target[key] = newval } }) proxyarr[3] = 4 // 拦截设 cmd 的值
?
-
copy
默认深拷贝
原始值拷贝的是数据
数组/对象默认浅拷贝
-
数组/对象copy
线拷贝是拷贝指针char str1[10] = "mark";char str2[10];strcpy (str2, str1);printf ("%s", str2);
$a = array (1,2,array (3,4)); $a2 =& $a; //浅拷贝 $a4 = $a; //深拷贝
引用值拷贝的是指针地址,所以两个对象指向相同的堆 var a = [1,2,[3,4]];var a2=a; //浅拷贝 var a3=JSON.parse (JSON.stringify (a)) //深拷贝
a = [1,2,[3,4]] b=a#地址拷贝 c=a.copy ()#深拷贝
-
🧊 Freezes an object
-
var day = ['Mon','Thu','Wed', 'Thu', 'Fri', 'Sat', 'Sun'];var d = day;Object .freeze (day); d[0]='Monday'; console.log(day[0]); // output: Mon console.log(d[0]); // output: Mon
frozenset ()
-
charCode 字符编码
char c = 'A';printf ("%d\n", (int ) c); // 65 int i = 97;printf ("%c\n", (char ) i); // a
String .fromCharCode (97) // 'a' 'A'.charCodeAt () // 65
N umber and Operators
逻辑运算符
┏━━⁄ ━━━━🔋━┓ and
┗━━⁄ ━💡━━━━┛
┏━⁄ ━┓ or
┣━⁄ ━┻━━━🔋━┓
┗━━💡━━━━━━━┛
电阻
┏━⁄ ━━⬇━━━━┓ not
┣━━━━━▭━━🔋━┫
┗━━💡━━━━━━━┛
&& || !
&& || !
&& || ! (1 && 2) === 2 (2 && 1) === 1 (1 && 0) === 0 (0 && 1) === 0 (0 && false ) === 0 (false && 0) === false (1 && 'm') === 'm' (1 || 3) === 1 (0 || 3) === 3 (true || 3) === true (false || 3) === 3算术运算符 +-*/ 比较运算符 === 的优先级高于逻辑运算符所以带括号 ⚠️ (1 || 2 && 3) === 1&& 优先级高于||
and or not
if [ $env != "dev" ] && [ $env != "test" ];then exit fi % echo 1 && echo 2 1 2% echo 1 || echo 2 1% echoo 1 || echo 2 command not found: echoo 2% echoo 1 && echo 2 command not found: echoo
位运算符
按位与 按位或 按位异或 按位取反
101 101 101
&1100 |1100 ^1100 ~0101
━━━━━ ━━━━━ ━━━━━ ━━━━━
0100 1101 1001 1010
11111111 11111111 11111111 11111110 -2<<1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
11111111 11111111 11111111 11111100 零填充左位移 -4
11111111 11111111 11111111 11111110 -2>>1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1 1111111 11111111 11111111 11111111 有符号右位移
填充符号位(32位最左侧的一位,正数为0 负数为1)
11111111 11111111 11111111 11111110 -2>>>1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
0 1111111 11111111 11111111 11111111 零填充右位移 -1
C 没有零填充右位移
printf ("%d\n", 5 << 20); // 5242880 相当于5 * 2的20次方
printf ("%d\n", -2 >> 0); // -2 即二进制-10 printf ("%d\n", -2 >> 1); // -1 printf ("%d\n", -2 >> 2); // -1 printf ("%d\n", -2 << 1); // -4 即二进制-100; warning: shifting a negative signed value is undefined ;C 建议使用无符号整数unsigned int左位移
a&b a|b a^b ~a a<<b a>>b a>>>bvar CHUNK_SIZE = 5 << 20 // 5M,FF=256=8个0,1K=1024=10个0 1M=20个0,1M Bytes=2²⁰ 1Byte=8bits=2⁸种值=256
if (~'markbuild'.indexOf ('mark')) {}
比较运算符等于,不等于,大于,小于,不小于,不大于
== != > < >= <=
== != > < >= <=<>也可以表示不等于
== != > < >= <====全等(值和类型)
== != > < >= <=
对于数字 -eq -ne -gt -lt -ge -le 对于字符串 = 和 !=
算术运算符加,减,乘,除,余数
+ - * / %/ 没有类型转换
+ - * / %/ 整除则是整数,否则小数
+ - * / %/ 整除则是整数,否则小数
+ - * / %/ 至少保留一位小数位
echo $[m+n] + - * / %/整型
整除÷
int r = 13 / 5
(int ) (13 / 5) parseInt (13/5)13//5 floor整除
divmod (除÷法的余数)
int r = 10 / 3;int remainder = 10 % 3;
$d=(int )(10/3); $m=10%3; d=(parseInt )(10/3); m=10%3; divmod (10,3)#输出(3,1)
赋值运算符x=y,x=x+y,x=x-y,x=x*y,x=x/y,x="x""y",x=x%y
= += -= *= /= %= &= |= ^= >>= <<=
= += -= *= /= .= %= = += -= *= /= += %= 同Javascipt
递增++递减--
++x; x++; --x; x--;
++x; x++; --x; x--;
++x; x++; --x; x--;
无,用+=1
$[--i] $[i--] let i++
乘方2⁴, 三次方根 ∛8
#include <math.h>printf ("%d\n", (int ) pow (2, 4)); // 16 pow 的返回值是 double 类型的 printf ("%lf\n", pow (8, (double ) 1/3 )); // 2.000000
pow (2, 4)pow (8, 1/3)
Math.pow (2,4) Math.pow (8, 1/3)
2**4 #输出16 或pow (2, 4)pow (8, 1/3)
开方求平方根(二次方根) √
#include <math.h>printf ("%d\n", (int ) sqrt (16)); // 4 sqrt 的返回值是 double 类型的
sqrt (4)Math.sqrt (4) import math math.sqrt (4)
浮点转换round四舍五入或银行家舍入法(奇进偶舍) ceil(天花板)入 floor(地板)舍
printf ("%f\n", ceil (1.1)); // 2.000000 printf ("%f\n", floor (1.9)); // 1.000000 printf ("%f\n", round (1.1)); // 1.000000 printf ("%f\n", round (1.5)); // 2.000000 四舍五入
(int )$xround ($x) // 四舍五入 ceil ($x)floor ($x)
Math.round (x) // 四舍五入 Math.ceil (x) Math.floor (x) parseInt (x)
int (x)round (x) // 奇进偶舍 math.floor (x + 0.5) // 四舍五入 round (5.5) == round (6.5) // True import math math.ceil (x) math.floor (x)
保留 n 位小数
number_format (6, 1)
(6).toFixed (1) // 6.0 返回字符串,toFixed 是 Number 类型的方法
最小值最大值
min (1, 2, 3);max (1, 2, 3); $a = array (1, 2, 3);min ($a);max ($a);
Math.min (1,2,3); Math.max (1,2,3); Math.min (...arr) // ES6
min (1, 2, 3);max (1, 2, 3); arr = [1, 2, 3];min (arr);max (arr);
绝对值
#include <math.h>printf ("%f\n", fabs (-4.2)); #include <stdlib.h>printf ("%d\n", abs (-4));
abs ($x)Math.abs (x) abs (x)
-
随机数 🎲
⚀⚁⚂⚃⚄⚅
rand (0,99)Math.random () 0.0 ~ 1.0 之间的一个伪随机数 import random random.random ()echo $((RANDOM % 100 +1))echo $(jot -r 1 1 100) # jot 还可以生成随机字符串
进制转换十进制与10根手指👐 有关
bindec ('101')hecdec ('aa')decbin (5)dechex (170)
dec to hex/bin Number (n).toString (16)Number (n).toString (2)hex/bin to dec Number (0xaa)Number ('0xaa')Number ('0b101')Number (0b101)
int ('101', 2)int ('aa', 16)bin (5)hex (170)
-
S tring
字符串数据
char str[] = "don't say \"no\"";char str2[] = {'d', 'o', 'n', '\'', 't', ' ', 's', 'a', 'y', ' ', '\"', 'n', 'o', '\"', '\0'}; // \0 指向null 代表字符串结束
┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━━┓
┃d┃o┃n┃'┃t┃ ┃s┃a┃y┃ ┃"┃n┃o┃"┃\0┃
┗━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━━┛
$str = "don't say \"no\"";echo 'don\'t say "no"';
str = "don't say \"no\""; console.log ('don\'t say "no"')
s = "don't say \"no\""print ('don\'t say "no"')
echo "hi,$var\!" echo 'hi,mark!'变量不能用于单引号中,!用不能直接用在双引号中
变量in字符串
-
$count = 3; $item = "ball";echo "$count ${item}s\n";
const count=3const item = "ball" str = `${count} ${item}s`或 str = String.raw `$(count) ${item}s` `foo ${fn()} bar`// 函数in 字符串,`` 字符串支持换行
-
echo "hi,$var\!"
格式化输出
printf ("%s\n", str);
echo sprintf ("lorem %s %d %f","ipsum", 13, 3.7);
-
print ('Hi, %s, you have $%d.' % ('Mark', 1000000))
printf "%-5s %-10s %-4.2f\n" 3 Mark 61.563
📐 length
#include <string.h>char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";strlen (alphabet) // 26 字符串长度 sizeof (alphabet) // 27 bytes 字符串内存字节长度,多一个\0 char alphabet[50] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";strlen (alphabet) // 26 字符串长度 sizeof (alphabet) // 50 bytes 字符串内存字节长度 <
strlen ("lorem")
str.length len (str)
echo ${#varname}
get字符串中第n个☝ 字符
str[6] *(str + 6)
$s[6]
s[6] s.charAt (6)
s[6] s[-1] # 倒数第一个字符 s[6:-1] # 输出ipsu 还有s[6:]和s[:-1}
echo ${a:5:1} # 第6个字符
set字符串中第n个☝ 字符
str[0] = 'D' *(str + 0) = 'D';
$s = "bar"; $s[2]="z";echo $s; //输出baz
s.slice(0, index) + 'z' + s.slice(index+1) ❌ s[0] = 'M' // JS 中字符串是不可变的(immutable)数据类型,一旦创建了一个字符串,就不能修改它的内容
Python 中的字符串是不可变对象,你不能直接修改字符串的某个字符。可以通过创建一个新的字符串来达到修改字符串的效果
-
字符串遍历
char str[] = "markbuild";使用指针遍历 char * ptr = str;while (*ptr != '\0') { printf ("%c\n", *ptr); ptr++; }使用数组下标遍历 for (int i = 0; str[i] != '\0'; i++) { printf ("%c\n", str[i]); }使用指针数组结合循环遍历 for (int i = 0; i < strlen (str); i++) { printf ("%c\n", *(str + i)); }
for ($i = 0; $i < strlen ($str); $i++) { echo $str[$i];
for (let char of 'foo') {
for char in "mark": print (char)
-
字符串是否包含/在字符串中的位置
if(strpos ('mark li', " ")===false)右边字符串在左边字符串中首次出现的位置,没有返回false 注意有可能在第一个位置返回0
var st = "do re re"; if (st.indexOf ("re") >= 0 )// lastIndexOf()从未尾开始查找 "mark".includes ("ar") // output: true url.startsWith ("https://markbuild.com") location.hostname.endsWith ('markbuild.com')
用正则的 re.findall (r're',st) 'm' in 'mark'
echo "$str" | grep -q "$substr"if [ $? -eq 0 ]; then   echo "包含子字符串"else echo "不包含子字符串"fi
合并字符串
#include <string.h>char str1[20] = "mark"; // 预留足够的内存长度,否则illegal hardware instruction非法硬件指令 char str2[] = "build";strcat (str1, str2);printf ("%s", str1);
$s2 = $s ."World!"; $s .= "World!";
s += 'World!' s = s.concat ('World')
'hello' + 'world' c=$a$b
repeat
str_repeat ('+---', 3)
'+---'.repeat (3).concat ('+') // +---+---+---+ 3 * '+---' + '+'
-
✂ 字符串定位切割子字符串 (slice,sub string)
substr ("lorem ipsum", 6, 5)第6+1个字符串起,往后切5个
str.slice (6,11)保留str[6]~str[11-1] str.substr (6,5)官方不建议使用
s[6:11]
str=mark.echo ${str: -1} # 获得最后一个字符 显示. ⚠️注意空格 echo ${str: :-1} # 去掉最后一个字符 显示mark ⚠️注意空格 echo ${str:0:4} # 显示mark echo ${str:4} # 显示.
全部大小写
strtoupper ("lorem")strtolower ("LOREM")"lorem".toUpperCase () "LOREM".toLowerCase () s.upper () s.lower ()
-
字符串首,单词首大写
ucfirst ("lorem")ucwords ("lorem ipsum")
-
s.capitalize () s.title ()
-
去掉两边的空格(默认),或其它字符(非串)
trim (" lorem ")ltrim ("/category/page/5","/")rtrim ("12,4,6,",",") 同 chop ("12,4,6,",",")
" lorem ".trim() .trimLeft () .trimStart () .trimRight () .trimEnd ()
" lorem ".strip()
-
Reverse 🔁
echo strrev('mark');// kram
str.split ('').reverse ().join ('')
print (str[::-1]) ''.join(arrB)
echo "mark"| rev # kram
数字转字符串
"value: ". 8 String (num) num.toString ()
str (4)
-
字符串转数字
7 + "12" 73.9 + ".037" Number ("73.9")
int ('4')
-
[Array ] 数组转字符串
┏━━━┳━━━┳━━━┓
┃ do┃ re┃ mi┃
┗━━━┻━━━┻━━━┛
┏━━━━━━━━━━┓ ↵
┃ do,re,mi ┃
┗━━━━━━━━━━┛
$arr = array ("do",re","mi","fa");implode (",", $arr) ["do", "re", "mi", "fa"].join (","); ["do", "re", "mi", "fa"].toString (); // Output: "do,re,mi,fa" lista=["do","re","mi","fa"] s = ','.join (lista) listb=[1,2,3] s=','.join (str (i) for i in b)
[Array ] 字符串转数组
┏━━━━━━━━━━┓
┃ do,re,mi ┃
┗━━━━━━━━━━┛
┏━━━┳━━━┳━━━┓ ↵
┃ do┃ re┃ mi┃
┗━━━┻━━━┻━━━┛
explode (",","do,re,mi,fa")\n是指换行符
var arr = "do,re,mi,fa".split (',');// str.split(',',3) 只保留前3段 'm d z'.split (/\s+/) // 支持正则字符
s="do,re,mi,fa" arr=s.split (',')list ('123') [s[i] for i in range (len (s))] py的.split ()和js不一样,py不支持.split ('')为空字符串,要用上面的list (str)
-
[Array ] 字符串中每一个字符分割到数组
┏━━━━━━┓
┃ abcd ┃
┗━━━━━━┛
┏━━━┳━━━┳━━━┳━━━┓ ↵
┃ a ┃ b ┃ c ┃ d ┃
┗━━━┻━━━┻━━━┻━━━┛
str_split ("abcd")str.split (''); l=list (s)
-
非正则替换
echo str_replace ('world', "sun", "hello world");
'hello world world'.replace ('world', 'sun') // hello sun world 'hello world world'.replaceAll ('world', 'sun')// hello sun sun
"hello world world".replace ("world", "sun") # hello sun sun
-
eval
?
?
eval ('alert("mb")')
eval ('print("mb")')
?
R egular Express 🧩
正则替换
$s = "do re mi mi mi"; $s2 = preg_replace ('/mi/', "ma", $s);
var s="do re mi mi mi";var s2=s.replace (/mi/g,"ma"); _val.replace (/([^<]+)<\/font>/g,"$1"); image2.replace (/\.([^.]+$)/,function ($0) { return '_360x'+$0 })
s="do re mi mi mi" re.sub (r'mi',r'ma',s)
sed '1,2s/mark/mk/' file # 替换1,2 行的第一个mark sed '1,2s/mark/mk/g' file # 替换1,2行每行上的所有mark sed -in-place 's/mark/mk/g' file # 替换所有行上的所有mark, 并保存到原文件
匹配
if (preg_match ('/1999/', $s)) { echo "party!\n"; }
if (s.match (/1999/)) { console.log ("party!"); } "<i>markli".search (/>M/i) //2 ,如果没有匹配则返回-1
/\sli/g.exec ("mark li") // [" li", index: 4, input: "mark li"], 不匹配则返回null
全局匹配,⚠️ 如果非//g 的正则会死循环
reg=/http[^\s]+/g
while (res = reg.exec (data)) { console.log (res[0]) } // 全局匹配,直到res 为 null
"2 3 4 5".split (/\s+/); // ["2", "3", "4", "5"]
import relen (re.findall (r'1999',s2))>0
[[ "$1" =~ ^[0-9]{0,2}$ ]] && echo "yes"
捕获
$regex = '/^type=(9)&code=([0-9]{6})$/'; $matches = array ();if (preg_match ($regex, $str, $matches)){ echo 'type='.$matches[1]; echo 'code='.$matches[2];
/page=([0-9]+)/.exec ('&page=52&')[1] // 52 if(/page=([0-9]+)/.test ('&page=52&')){alert (RegExp .$1*1+1);} // 53
match = re.compile (r'\d+').search ('123mark456') print(match.) print(match.group())
动态构造正则
new RegExp (str+'$')
A rray/Set
定义/申明
int arr[] = { 1, 2, 3, 4 };int arr2[4]; arr2[1] = 1;int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };
$arr = array (1, 2, 3, 4);
var arr=[1, 2, 3, 4]; arr = new Array(10).fill ().map ((itm, idx) => idx) arr = Array.from ({ length: 10 }).map ((itm, idx) => idx)var set1=new Set()var set2=new Set([1,2,3])WeakSet 的成员只能是对象且不能forEach,并且和WeakMap一样是弱引用,如果存储的对象被GC, 它在WeakSet 里自动释放 前端常见内存泄漏及解决方法
TypedArray 比Array省内存,长度是固定的,开了空间就不能改,他的值他存的是实际数据而不是指针Int8Array 存-128~127范围的数字,超出范围取模后余数Uint8ClampedArray 和 Uint8Array 都是用来存0~255的数字,Unit8Array超出范围取模余数, 对于260和-10转化为4和246,Clamped对于260和-1转化为255和0,适合图像颜色计算Uint16Array 存0~65535范围ArrayBuffer TypedArray 和 DataView
l=[1, 4] # list t=('东','西','南','北') # tuple 不可修改元素值,元素个数 s=set(['python','java'])# set 无序不重复 arr=[arr1,arr2] 或 arr=[[1,2,3],['x','y']] # nest
arr=(1 2 3 4 5)
📐 length/size
printf ("%lu", sizeof (arr)); // 数组内存字节长度 获得数组元素个数没有内置方法,可通过遍历计数获得
count ($arr)count ($d)
arr.length set1.size
len (squares) len(tel)
echo ${#arr[*]}
Get value by index☝
arr[0]
$arr[0]
arr[0] arr.at (-1) Array.from(set1)[0] // 先转化成数组
squares[0] arr[1][1]
echo ${arr[0]}
Set value by index☝
arr[0] = 8;
$arr[0] = "lorem";
arr[0]="lorem"; set1.add (1)
squares[0]="lorem" squares[2:4]=[99,100]
arr[0]="hi"
Fill 填充
['vscode', 'notepad++', 'xmind', 'postman'].fill ('terminal')
value是否存在 于arrayindex of array elementcount 在array中出现的次数
if (in_array (2, $a)){} $i = array_search ("y", $arr);
['mark','emy'].indexOf ('mark')>=0; ['mark','emy'].includes ('mark') // ES5+ set1.has (3)
'm' in ['a', 'b', 'c'] # True/False try : idx = ["x","y","z"].index ("y") print ("y第1次出现的位置", idx)except ValueError: print ("not in list") ['m', 'li', 'm'].count ('m') > 0: # 返回2 统计出现的次数
✂ 数组slice切片选择第3,4个元素
┏━┳━┓✂┏━┳━┓ ✂┏━┓
┗━┻━┛ ┗━┻━┛ ┗━┛
array_slice ($arr, 2, 2)
arr.slice (2,4) // 切取 arr[2] ~ arr[4-1] arr.slice (-2,-1) // 获得倒数第2个
squares[2:4]
✂ slice to end 数组切到底 选择从第2个到尾部
┏━┓✂┏━┳━┳━┳━┓
┗━┛ ┗━┻━┻━┻━┛
array_slice ($arr, 1)
arr.slice (1)
squares[1:]
数组首部操作,追加与删除元素
┏━┓ +┏━┳━┳━┳━┓
┗━┛ -┗━┻━┻━┻━┛
?
var arr = [6, 7, 8] arr.unshift (5) arr.shift ()
?
数组尾部操作,追加与删除元素
┏━┳━┳━┳━┓ +┏━┓
┗━┻━┻━┻━┛ -┗━┛
$arr = array (6, 7, 8);array_push ($arr, 9); $arr[] = 9; # 与array_push相同 array_pop ($arr);删除尾部元素
var arr = [6, 7, 8] arr.push (9) arr.pop () 或 arr.length--
list1.append (9) list1.pop ()
Insert an item into an array at a specific index☝
arr.splice (_index, 0, item)
删除元素by index☝
unset ($arr[_index]);//数组将不会重建索引,若要重建索引用array_values($arr)
arr.splice (_index,1)//前面一个参数数是删除的index,后面一参数表示删除后面的几个元素 delete arr[_index];//仍会占据一个长度,值为undefined
del a[0] squares[2:4]=[]#删除2个 squares[:]=[]全部删除或 squares.clear ()
删除元素by value
arr.splice(arr.indexOf('v'), 1)
合并
┏━┳━┳━┳━┓ +┏━┳━┳━┳━┓
┗━┻━┻━┻━┛ +┗━┻━┻━┻━┛
$arr = array (1, 2, 3); $arr2 = array (1, 2, 3);print_r (array_merge ($arr,$arr2));
var arr = [1,2,3], arr2=[4,5,6]; console.log (arr.concat (arr2));... 扩展(Spread)运算符 console.log ([...arr,...arr2])
squares+[2,4,'mark']扩展数组 list1.extend (list2) mergedTel=dict(tel,**tel2)
数组遍历
ↆ
┏━┳━┳━┳━┳━┓
┗━┻━┻━┻━┻━┛
int arr[4] = {1, 2, 3, 4};for (int i = 0; i < 4; i++) { printf ("%d\n", arr[i]); }
foreach ($arr as $s) { echo "$s\n"; }foreach ($arr as $i => $s) { echo "$s at index $i"; }
⚠️ for in 中的index 不是数字,是字符串,而forEach中的index 是数字
for (idx in ['v']) { console.log(8+idx) } // 输出80
arr.forEach ((item, index) => {})
forEach 无法用break 跳出可以用every 或some或find
every是遇到false就终止并返回false,some是遇到true就终止并返回true,find/findIndex是遇到true就终止并返回那个满足条件的item/index
arr.every ((item, index) => { if (条件) { return false /* 相当于break */ } return true })
arr.some ((item, index) => { // 或arr.find( if (条件) { return true /* 相当于break */ } return false })
for (let item of arr) {
for v in squares:
将范围转成数组
$a = range (1, 10);
-
l.list (range (1,10))
Reverse
┏━━━┳━━━┳━━━┳━━━┓
┃ M ┃ a ┃ r ┃ k ┃ 🔁
┗━━━┻━━━┻━━━┻━━━┛
┏━━━┳━━━┳━━━┳━━━┓ ↵
┃ k ┃ r ┃ a ┃ M ┃
┗━━━┻━━━┻━━━┻━━━┛
$a = array (1, 2, 3); $a = array_reverse ($a);print_r ($a);
var a = [1, 2, 3]; a.reverse (); console.log (a); a.reverse ().join(' ')===a.join(' ') 一定为真,reverse 操作数组本身
l=[1,2,3] l.reverse ()print (l)
Sort
default by ASCII code
┏━━━┳━━━┳━━━┳━━━┓
┃ M ┃ a ┃ r ┃ k ┃ 📶
┗━━━┻━━━┻━━━┻━━━┛
┏━━━┳━━━┳━━━┳━━━┓ ↵
┃ M ┃ a ┃ k ┃ r ┃
┗━━━┻━━━┻━━━┻━━━┛
$a = array ("b","A","a","B");sort ($a);print_r ($a);
.sort原数组排 .toSorted产生新数组 [15,6,5].toSorted () // [15, 5, 6] 按字符串排序, 15会排在5前,因为起始字符是1 [15,5,6].toSorted ((a,b)=>a-b) // 数字排序
sort compare回调返回的必须是数字,不是true 或 false,否则出错
['ab','aa','bb'].sort ((a,b) => a<b) // ❌['ab','aa','bb']
['ab','aa','bb'].sort ((a,b) => a<b?-1:1) // ['aa','ab','bb']
字符个数相同,则按照ASCII码由小到大排序输出Object .keys (obj).sort ((a,b) => {   if (obj[a] === obj[b]) { return a.charCodeAt () - b.charCodeAt () } else { return obj[b] - obj[a] } })
Array .from (set).sort () // Set 没有数组方法
.sort原数组排 sorted产生新数组sorted ([15,6,5]) [5, 6, 15] 跟js不一样 ListA.sort (key =lambda x: (-x[1], x[0]))sorted (ListA, key =lambda x: x[1], reverse =True)
重复数据删除(去重)
┏━━━┳━━━┳━━━┳━━━┓
┃ M ┃ o ┃ o ┃ n ┃
┗━━━┻━━━┻━━━┻━━━┛
┏━━━┳━━━┳━━━┓ ↵
┃ M ┃ o ┃ n ┃
┗━━━┻━━━┻━━━┛
$a = array (1, 2, 2, 3); $a=array_unique ($a);
arr = [1,2,3,3] Array .from (new Set (arr)) 或者 [...new Set (arr)]
-
洗牌和取样
⚀⚁⚂⚃⚄⚅
$a = array (1, 2, 3, 4);shuffle ($a);//洗牌 $sa=array_rand ($a, 2);//随机截取
-
-
过滤
┏━━━┳━━━┳━━━┳━━━┓
┃ ( ┃ { ┃ [ ┃ ? ┃
┗━━━┻━━━┻━━━┻━━━┛
┏━━━┳━━━┳━━━┓ ↵
┃ ( ┃ { ┃ [ ┃
┗━━━┻━━━┻━━━┛
arr.filter (item=>item>10)设置过滤后长度为0时的默认值 filter (condition).concat ({ field: 'default' })[0].field
按条件查找
[88, 93, 95].find (item=>item>90) // 93 [88, 93, 95].findIndex (item=>item>90) // 1
Reducer
arr.reduce ((acc, item) => { ...; return acc }, acc初始值)
Map
collections.map ((item)=> item.title)// ['title1', 'title2', 'title3'] // 获得数组中数字为奇数项的index [1,2,3,4,5] .map ((itm, idx) => itm % 2 ? idx : -1) .filter (item => item !== -1)
扁平化Flat
[1,2,[3,4],[[5,6]],[[[7,8]]],[[[[9,10]]]]].flat (2) // [1, 2, 3, 4, 5, 6, Array(2), Array(1)] [1,2,[3,4],[[5,6]],[[[7,8]]],[[[[9,10]]]]].flat (Infinity) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ['May the force', 'be with you'].flatMap (item=>item.split (' ')) // ['May', 'the', 'force', 'be', 'with', 'you']
O bject/Map/Dict/struct
定义/申明
struct myStructure { int myNum; char myLetter; char myString[30]; };struct myStructure s1; s1.myNum = 13; s1.myLetter = 'B'; // s1.myString = "hi"; // Error strcpy (s1.myString, "hi")struct myStructure s2 = {13, 'B', "mark"}; // 更简单的语法 struct myStructure s3; s3 = s1; // 深拷贝
$d = array ("t" => 1, "key" => 0);
var obj={t:1,key:0}const map1=new Map(); b={a:1} map1.set (b, 'v') map1.get (b)const map2=new Map([["k1","v1"],["k2","v2"]]);map2.get ("k1") // v1
WeakMap的key 必须为引用值,当这个key不被引用,会被GC 回收,从而从WeakMap 里自动释放, WeakMap且不能被forEach。Map 的 key 啥类型都行,但影响GC 回收该key 导致内存泄漏,Map支持forEach wmap = new WeakMap()前端常见内存泄漏及解决方法
d = {"state": 4, "action": "VO"} # dict
declare -A tel tel=([Mark]=6015 [Emy]=0755)
📐 length/size
map1.size
Get value by key🔑
s1.myNum
$d["t"]
_obj.t 或 _obj["t"]
d['jack']
echo ${tel[Mark]}
Set value by key🔑
s1.myNum = 14;strcpy (s1.myString, "Something else");
?
map2.set("k3","v3"); theHobbit.stars = 4 // stars set to 4
d['jack'] = 5 Ferrari458.brand
tel[Mark]=6016
key🔑是否存在
if (array_key_exists ("key", $d))
'key' in obj map1.has ('key')
if 'jack' in tel:#还可以使用not in
删除元素by key🔑
unset ($d["t"]);
delete _obj.t;
del tel['sape']
合并覆盖Object
?
Object.assign (default_opt, opt)... 扩展(Spread)运算符 option = { ...default_opt, ...opt}
对象遍历
foreach ($d as $k => $v) {echo $k.'=>'.$v;}
for (let key in arr_obj){ console.log (arr_obj[key]); }
for v in d:
Get all keys🔑🔑 & Get all values 转成数组
array_keys ($d)array_values ($d)
Object.keys (obj) // Output ['t', 'key'] Object.values (obj) // Output [1, 0] Object.entries (obj) // Output [['t', 1], ['key', 0]] 注意对象输出是按插入顺序而不是名称排序 obj = {} obj.B = 1,obj.A = 2 Object.keys (obj)[0] === 'B' // true
list (tel.keys ())list (tel.values ())
F unction
定义函数
void myFunction (char name[]) { printf ("Hello %s\n", name); }int main () { myFunction ("World"); return 0; } 不能在申明前调用函数, 函数可以先申明后定义void myFunction (char []);void main () {}void myFunction (char name[]) {
function add3 ($x1, $x2, $x3) { return $x1 + $x2 + $x3; }
function add3 (x1, x2, x3) { return x1 + x2 + x3; }function add3 ([x1,x2,x3]) { return x1+x2+x3;}function myfun ({x,y,z}) { return x*y-z;}
def add3(x1,x2,x3): return x1+x2+x3 function add3 (){echo $[$1+$2+$3] }
Arrow Function有点像pipeline,箭头前的输出是箭头后的输入
-
-
箭头函数可省去return (param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression// 等价于: => { return expression; } 只返回{}, 应当用()将其包起来, 否则当statements处理而不是当expression处理 params => ({foo: bar})如果只有一个参数,可以不加圆括号: singleParam => { statements }无参数的箭头函数需要使用圆括号或者下划线 () => { statements } 或 _ => { statements }箭头函数的this始终继承父级作用域的,且不能作为构造函数
-
-
调用函数
?
add3 (1, 2, 3);
add3 (1, 2, 3)add3 ([1,2,3]);myfun ({x:3,z:2,y:1});// output: 1
add3 (1, 2, 3)add3 2 3 8 #打印结果13
数组作参数
?
$arr = array (1, 2, 3);function foo ($ar){}echo foo ($arr);
... 扩展(Spread)运算符 arr = [1,2,3] foo = (x,y,z)=> x*y*z console.log (foo (...arr)) Math.max (...arr)
l=[1,2,3]def foo (arr): for v in arr: print (v)foo (l)
rest参数
?
-
function add (...values) {for let v of values){ ...add (2,5,7)
函数作参数
?
function add ($x,$y,$f){   return $f($x)+$f($y); }function add (x,y,f ){ return f (x)+f (y) }def add (x, y, f ): return f (x) + f (y)
默认参数
?
function my_log ($x, $base=10) { return log ($x) / log ($base); }my_log (42);my_log (42, M_E);
function my_log (x, base) { base = arguments[1] ? arguments[1]:10; return Math.log (x) / Math.log (base); }my_log (42);my_log (42, Math.E);function my_log (x, base=10)
import mathdef my_log (x, base=10): return math.log (x) / math.log (base)my_log (42);my_log (42, math.e)
可变数目的参数
?
function first_and_last () { $arg_cnt = func_num_args (); if ($arg_cnt >= 1) { $first = func_get_arg (0); echo "first: " . $first . "\n"; } if ($arg_cnt >= 2) { $arr = func_get_args (); $last = $arr[$arg_cnt-1]; echo "last: " . $last . "\n"; } }function howManyArgs (){ console.log (arguments.length); console.log ("Hello"+arguments[0]+","+arguments[1]); }howManyArgs ("string", 45);Python可变参数
传地址参数
?
function foo (&$x, &$y) { $x += 1; $y .= "ly"; } $n = 7; $s = "hard";foo ($n, $s);
-
-
匿名(Anonymous)函数
?
$sqr = function ($x) { return $x * $x; };echo $sqr(3);
IIFE(Immediately-Invoked Function Expression)立即调用函数表达式 自调用函数(self-invoking function) 有两种写法,没实际区别 (function () {})() (function () {}())
lambda用于创建匿名函数
回调模式 Callback
?
call_user_func ('myfun')call_user_func ('myfun','myparam')function call_func (function_param) { function_param (); }function myfunc () { // ... }call_func (myfunc); 例:requestAnimationFramedef callback (fun): fun ()def myfun (): print('hi,mark')callback (myfun)
sync and async
//异步1: Callback
getData (a => {
getMoreData (a, b => {
getMoreData (b, c => {
})
})
})
//异步2: Promise
function getData () {
return new Promise((resolve, reject) => {
fs.readFile (fileName, (error, data) => {
if (error) { reject (error) }
else { resolve (data) }
})
})
}
getData ()
.then (a => getMoreData (a))
.then (b => getMoreData (b))
.then (c => {})
.catch (err => {})
//异步3: async/await, async 是Generator 的语法糖
const foo = async function () {
try {
let a = await this .apis.getData ()
let b = await this .apis.getMoreData (a)
} catch (err) {}
}
定义类
-
class Book { private $isbn; public $title; public $author; public function __construct ($isbn, $title = null, $author = null) { // 构造函数 $this->isbn = $isbn; $this->title = $title; $this->author = $author; } public function display () { echo $this->isbn; } }
var Book = /** @class */ function (isbn, title, author) { if (isbn == undefined) throw new Error('Book constructor requires an isbn.'); this .isbn = isbn; this .title = title || 'No title specified'; this .author = author || 'No author specified'; } Book.prototype .display = function () { ... };//或者 Book.prototype = { checkIsbn : function (isbn) { ... }, display : function () { ... } };ES6 的类是基于原型语法的语法糖 class Book { constructor (isbn, title, author) { if (isbn == undefined) throw new Error ('Book constructor requires an isbn.'); this .isbn = isbn; this .title = title || 'No title specified'; this .author = author || 'No author specified'; } display () { console.log (this .isbn) } get stars () { return 5 } set stars (newval) { console.log('stars set to ', newval) } }
class Car: def __init__ (self,brandname,horsepower): self.brand = brandname self.power = horsepower def drive (self): print ('Run with %s horsepower' % self.power)也可以这样玩 class Car: pass LamborghiniAventador = Car() LamborghiniAventador.brand = 'Lamborghini' LamborghiniAventador.power = 700
Using a Class to Instantiate an Object
$theHobbit = new Book ('isbn', 'The Hobbit', 'mark')
var theHobbit = new Book ('isbn', 'The Hobbit', 'mark')
?
method
$theHobbit->display ();
theHobbit.display ();
Ferrari458.drive()
value
$theHobbit->isbn; // Cannot access private property Book::$isbn $obj->$param; // 动态 $obj->{$param . 's'}
theHobbit.isbn
Ferrari458.brand
访问修饰符实现封装,减少耦合
public :全开protect :仅同一个类或子类能访问private :仅同一个类能访问 class默认访问修饰符为 public
js
self.__privateattr 要让内部属性不被外部访问,可把属性名称前加__ 但某些版本的解析器中你依然可以用obj._classname__privateattr来访问,也就是Python本身没有任何机制阻止你干坏事,一切靠自觉养成好习惯
继承
class ITBook extends Book { public $technology; public function __construct ($isbn, $title, $author, $technology) { parent:: __construct ($isbn, $title, $author); $this->technology = $technology; } }
A对象应用B对象的方法 B.apply (A, arguments); B.call (A, args1,args2);class ITBook extends Book { constructor (isbn, title, author, technology) { super (isbn, title, author); this .technology = technology; } }
class Dog(Animal):狗继承动物类,获得动物类的全部功能财产
重载(Overloading) & 重写(Overriding)
php
-
子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run() 静态语言需要重载解决调用灵活性,而Python这种灵活的语言可以用其它方式实现
多态同一个接口,使用不同的实例而执行不同操作 实现多态的必要条件继承+重写+父类引用指向子类对象
php
js
?
C ontrol Flow
if
if (条件1 ){ 执行1 } else if (条件2 ){ 执行2 } else { 执行3 }
第一种方式同java 第二种方式将else if替换成elseif, 据说这个更有效率 第三种方式用:代替大括号,不能用else if if (条件1 ): 执行1 elseif (条件2 ): 执行2 else : 执行3 endif ;
if (条件1 ){ 执行1 } else if (条件2 ){ 执行2 } else { 执行3 }
if 条件:elif 条件2:else:
if [ $1 -gt 30 ];then echo 'Not kid any more'elif [ $1 -gt 20 ];then echo 'Become mature'else echo 'you are young'fi 注意[ ]两边都得要有空格 if [ ! -n "$1" ]; then # 变量是否存在 if [ ! -d "web-cms" ]; then # 目录是否存在 if [ ! -f "spm.zip" ]; then # 文件是否存在 if [[ "" =~ ^[0-9]{0,2}$ ]]; then # 正则条件双括号[[ ]]
三元运算符
x=(x > 0 ? x :-x);
$x > 0 ? $x : -$x
x=(x > 0 ? x :-x)
-
-
switch
switch (n) {case 0: printf ("no hits\n"); break ;case 1: printf ("one hit\n"); break ;default : printf ("%d hits\n", n); }
switch (n) {case 0: echo "no hits"; break ;case 1: echo "one hit"; break ;default : echo n." hits"; }
switch (n) {case 0: console.log ("no hits"); break ;case 1: console.log ("one hit"); break ;default : console.log (n+" hits"); }
为什么Python没有switch? 少量用if elif 大量用字典 func = functions[value]func ()
case $1 in 男|M)echo "小少爷" ;; 女|F)echo "小公主" ;; *)echo "有没有搞错" ;;esac
while 🔁
1┏━▶⚙━━┓
━━▶while◀━━┛
0┗━━━━━▶
a period of time.
while ( i < 100 ) { i++; }
while ( i < 100 ) { i++; }
while ( i < 100 ) { i++; }
while i < 100 : i+=1;
while [ $i -lt 10 ]; do let i=i+1done while true; do # 无限循环用Exit跳出
do while 🔁
━━▶⚙◀━━━┓1 0
┗━━while━━▶
和while循环十分类似, 不过至少执行一次 代码
do { sum=sum+i; i++; }while (i<=100);
do { sum=sum+i; i++; }while (i<=100);
do { sum=sum+i; i++; }while (i<=100);
无,用break跳出
for循环 🔁
for (int i=1;i<=5;i++) { sum=sum+i; }
for (i=1;i<=5;i++) { sum=sum+i; }
for (i=1;i<=5;i++) { sum=sum+i; }
for i in range (1,6): # range为遍历辅助 sum+=i
for i in `seq 1 3`;do echo $i;done for i in 1 2 3;do echo $i;done
break, continue跳出最近一层 的for,for-in,while,do-while循环, 或跳出switch continue只结束本次循环,直接进入下一轮 break则是结束整个循环 ✍ 遇到难题停止继续做下一题: continue,撕卷子: break
break , continue
break , continue
break , continue
break , continue
break , continue
goto
-
if(1) goto end; ... end: ...不能跨函数使用.This is not a full unrestricted goto,The target label must be within the same file and context
-
-
-
exit
exit (); // 别名die, 输出一个消息并且退出当前脚本
-
os._exit () # 终止程序 sys.exit () # 会引发一个异常,如果异常没被捕获,python解析器将会退出,如果被捕获,还可以执行后面的代码,用于做清理工作 一般情况下使用sys.exit ()即可,一般在fork出来的子进程中使用os._exit ()
exit
Sleep 🚦⏱
sleep (5)
const sleep = sec => new Promise (resolve => setTimeout (resolve, sec * 1000));await sleep(5)
import time time.sleep(5)
sleep 5
异常的抛出与捕获无论异常是否发生,在程序结束前,finally中的语句都会被执行
//主动抛出异常 function checkNum ($number){ if ($number>1){ throw new Exception("不能使用大于1的值"); } return true; }try { checkNum (2); } catch (Exception $e){ echo '错误描述: ' .$e->getMessage (); } finally { echo "always excute"; }
//被动抛出异常 try { adddlert ("Welcome!"); } catch (err){ alert (err);//ReferenceError: adddlert is not defined }//主动抛出异常 try { throw "抛出错误" } catch (err){ alert (err);//抛出错误 }finally {console.log ("always excute")}
# 被动抛出 import systry : f = open ('myfile.txt') s = f.readline () i = int (s.strip ())except OSError as err: print ("OS error: {0}".format (err))except ValueError: print ("Could not convert data to an integer.")except : print ("Unexpected error:", sys.exc_info ()[0])finally : print ("always excute")# 主动抛出 try : raise ValueErrorexcept : print ("value error")
npm run build || (echo '编译失败';exit 1) npm run buildif [ $? -ne 0 ];then echo '编译失败'exit 1else echo '编译成功'fi
CL I
命令行
gcc main.c // 编译 ./a.out // 运行 objdump -D a.out 查看指令
php -f index.phpphp -r "echo 'mark';"
node bgt.js fileTypeScript tsc main.ts // 编译成main.js
python3 cmd.py ip 116.6.65.67
Method 1: bash backupdb.sh arg1 arg2Method 2: ./backupdb.sh # need shebang and X permission
REPL Read-Eval-Print Loop Interactive shell
-
php -a > 1+2 > exit
node > 1+2 >.exit
python3 >>> 1+2 >>> exit()
-
参数
int main (int argc, char *argv[]) { // (参数个数,参数数组) printf ("共有%d个参数\n", argc); printf ("第一个参数是%s\n", argv[0]); // 第一个参数是./a.out return 0; }
$argv 数组 $argv[0]是脚本名 $argv[1]是第一个参数
Node.js const args = process .argv.slice (2)process.argv[0] 是node程序地址,process.argv[1] 是脚本名
import sys#需要模块:sys sys.argv[0]#脚本名:cmd.py sys.argv[1]#参数1:ip
脚本中$1 的值便是arg1, $2 便是arg2, $@ 值是所有参数arg1 arg2
输入
char input[10];int num;printf ("指令>>");scanf ("%9s", input); // 最大长度9个字符,否则溢出 printf ("%s\n", input);printf ("数字>>");scanf ("%d", &num); // 这里需要是指针,而上面的input数组本身是指针 printf ("%d\n", num);
fwrite (STDOUT, "M>>");echo fgets (STDIN);
const readline = require ('readline').createInterface ({ input: process.stdin, output: process.stdout }); readline.question ('M>> ', taskid => { console.log(taskid)  // readline.close(); });
command = input ("M>>")print (command)
read -p "M>> " taskidecho $taskid
调用命令行
import os os.system('start https://x.com')
-
D isk I/O
判断目录/文件是否存在
if (file_exists ('dirNameOrFileName')) { echo "文件或目录存在"; }
const fs = require ('fs')if (fs.existsSync ('/path/dir')){if (fs.existsSync ('/path/file.txt')){
import osif not os.path.exists (aim_dir+'\\'+name):# 如果文件/目录不存在 os.path.isdir (ori_dir+'\\'+name):# 是否是目录 os.path.isfile (ori_dir+'\\'+name):# 是否是文件
if [ ! -d "web-cms" ]; then # 目录是否存在 if [ ! -f "spm.zip" ]; then # 文件是否存在
Create/Remove directory/file, write/read file
FILE *fptr; fptr = fopen ("filename.txt", "w");fprintf (fptr, "Some text\n");fclose (fptr); fptr = fopen ("filename.txt", "r");char myString[100];while (fgets (myString, 100, fptr)) { printf ("%s", myString); }
mkdir ("/path/to/my/dir", 0700); $f = fopen ("f.txt", "w");fwrite ($f, 'content');fclose ($f);
带Sync的函数都是同步方法,没有回调 fs.mkdirSync ('/path/newdir') fs.rmdir ('/path/dir',()=>{console.log('callback')})INSERT: fs.appendFileSync ('./txtdb/db1.tb1.csv', 'Ryan,5\n') // 追加加入 SELECT: fs.readFile ('./txtdb/db1.tb1.csv', (err,data) => { console.log (data.toString ().split ('\n').filter (item => item)[1].split (',')[0]) })REPLACE: fs.writeFileSync ('./txtdb/db1.tb1.csv', tb1.map (item => item.join (',')).join ('\n')) // 不存在则新建文件 fs.unlinkSync ('/path/file.txt')// 删除文件
import os os.makedirs (aim_dir) f=open ('f.txt','w') f.write ('content') f.writelines (['content\n','content2\n']) f.close ()
mkdir wwwtouch fileecho 'content' >> file
获得文件扩展名
const path = require ('path'); console.log(path.extname ('/path/file.txt')) // .txt
import os os.path.splitext ('a.b.txt') # ('a.b', '.txt')
file=a.b.txtecho "${file%.*}" # a.b echo "${file##*.}" # txt
遍历文件
带Sync的函数都是同步方法,没有回调 const fs = require ('fs');const path = require ('path');function traverseDir (dir) { const files = fs.readdirSync (dir); // 读取目录 for (let file of files) { const filepath = path.join(dir, file); const stats = fs.statSync (filepath); // 获取文件信息   if (stats.isDirectory ()) { traverseDir (filepath); } else { console.log(filepath);   } } }traverseDir ('/path/dir')
import osfor dirpath, dirnames, filenames in os.walk (path): print (dirpath) print (filenames)
-
netW ork I/O
HTTP Data
?
$_POST $_GET $_COOKIE $_REQUEST(包含$_POST+$_GET+$_COOKIE 数据的数组) $_SERVER['HTTP_IF_NONE_MATCH'] 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] 判断协议,别忘记考虑负载均衡
window.location, document.cookieconst urlParams = new URLSearchParams (location.hash.replace (/^.*\?/, '')) urlParams.get ('param')
?
-
HTTP Server
?
header ()setcookie ()
Node.js
python3 -m http.server [port] // 适合HTML页面 Simple Server Demo
HTTP Client
?
cURL
Fetch fetch (url, { headers: { 'content-type': 'application/json' }, body: JSON.stringify(params), method: 'POST', credentials: 'include' }).then (res => res.json ()) .then (response => {}) .catch (err => {})跨域请求默认不会带上cookie,credentials设置为include 则会带上
-
curl wget
T ime
Get Time
#include <time.h> time_t current_time;time (¤t_time);printf ("%ld\n", (long)current_time); // 1684367117 time_t current_time;time (¤t_time);struct tm* time_info;char time_string[20]; time_info = localtime (¤t_time);strftime (time_string, sizeof (time_string), "%Y-%m-%d %H:%M:%S", time_info);printf ("%s\n", time_string); // 2023-05-18 15:38:43
echo date ("Y-m-d H:i:s");//Output: 2018-05-03 01:06:54 //Other format date (m);date (H);echo time ();//Output: 1525309469
var d=new Date(); console.log (d.toLocaleString ())//Output: 5/2/2018, 2:18:36 PM Date.parse (new Date())/1000//Output: 1525242393 parseInt (new Date().getTime ()/1000) //Output: 1525242680parseInt ((new Date()).valueOf ()/1000)//Output 1525243045
import time;print (time.strftime ("%Y-%m-%d %H:%M:%S", time.localtime ()))#Output: 2018-05-03 10:17:01 print (int (time.time ()))#Output: 1525310230
echo `date`#Output: Wed May 2 13:54:46 2018 echo "[`date +%Y-%m-%d\|%T\|%A`]"#Output: [2018-05-02|14:14:20|Wednesday] echo `date +%s`#Output: 1525242150
Datetime to Timestamp
char datetime_str[] = "2023-05-18 10:38:43";struct tm datetime; time_t timestamp;strptime (datetime_str, "%Y-%m-%d %H:%M:%S", &datetime); timestamp = mktime (&datetime);printf ("%ld\n", (long)timestamp); // 1684373923
echo strtotime ("2018-10-06 02:00:00");//Output: 1538791200
Date.parse (new Date("2018-10-06 02:00:00"))/1000
import datetimeimport timeprint (time.mktime (datetime.datetime.strptime ("2021-05-12 02:37:29", "%Y-%m-%d %H:%M:%S").timetuple ()))// output: 1620758249.0
-
Timestamp to Datetime
time_t timestamp = 1684373923;struct tm* datetime = localtime (×tamp);char datetime_str[20];strftime (datetime_str, sizeof (datetime_str), "%Y-%m-%d %H:%M:%S", datetime); // 2023-05-18 09:38:43 printf ("%s\n", datetime_str);
echo date ("Y-m-d H:i:s",'1538791200000'/1000); // output:2018-10-06 02:00:00
function formatDate (_timestamp) { let date = new Date (+_timestamp), year = date.getFullYear (), month = String (date.getMonth () + 1).padStart (2, '0'), day = String (date.getDate ()).padStart (2, '0'), hour = String (date.getHours ()).padStart (2, '0'), min = String (date.getMinutes ()).padStart (2, '0'), sec = String (date.getSeconds ()).padStart (2, '0'); return `${year}-${month}-${day} ${hour}:${min}:${sec}` }formatDate (1538791200*1000)
from datetime import datetimeprint (datetime.fromtimestamp (1620758249))// output: 2021-05-12 02:37:29
-
其他
new Date(new Date(2023,2,0).getTime () + (24 * 3600 - 1) * 1000) // Tue Feb 28 2023 23:59:59 ... 获得月底最后一天的最后一秒
E ncryption
base64
?
echo base64_encode ("mark李"); // bWFya+adjg== echo base64_decode ("bWFya+adjg=="); // mark李
window.btoa (unescape (encodeURIComponent ("mark李"))); //'bWFya+adjg==' decodeURIComponent(escape(window.atob ('bWFya+adjg=='))); // 'mark李'
import base64print (base64.b64encode ("mark李".encode ("utf-8")).decode ("utf-8")) // bWFya+adjg== print (base64.b64decode ("bWFya+adjg==").decode ("utf-8")) // mark李
echo -n mark李|base64 // bWFya+adjg== 加-n 来确保字符串不包含行末换行符 echo bWFya+adjg==|base64 -d // mark李% echo mark李|base64 // bWFya+adjgo= echo bWFya+adjgo=|base64 -d // mark李
Hash: md5, sha1, sha256, sha512
?
echo md5 ("mark李"); // 8ef85f394180bc4a79a47b033440d7fd
md5 calculate(.trans.) md5 ("mark李"); // 8ef85f394180bc4a79a47b033440d7fd
import hashlib print(hashlib.md5 (bytes ('mark李',encoding='utf-8')).hexdigest ()) // 8ef85f394180bc4a79a47b033440d7fd import os hashlib.sha1 (open ('C:\\Users\\m\\Desktop\\file.exe','rb').read ()).hexdigest () hashlib.sha256 (... hashlib.sha512 (...
echo -n mark李|md5sum # 8ef85f394180bc4a79a47b033440d7fd - echo -n mark李|openssl md5 # 8ef85f394180bc4a79a47b033440d7fd cat file|md5sum cat file|openssl sha1 cat file|openssl sha256 cat file|openssl sha512
对称加密: aes
$iv=''; $str = openssl_decrypt (hex2bin ($key), "aes-128-ecb", $aeskey, OPENSSL_RAW_DATA, $iv);openssl_encrypt
在线AES加解密工具
?
?
非对称加密: RSA
?
?
?
?
ssh-keygen -t rsa -f ~/.ssh/markli_rsa -N ""read -p "输入目标IP>> " ipscp ~/.ssh/markli_rsa.pub root@$ip:~/markli_rsa.pubssh root@$ip "cat ~/markli_rsa.pub >> ~/.ssh/authorized_keys"ssh root@$ip "rm ~/markli_rsa.pub"