面包屑思维模型实战模型错题集结构手册流程手册自我检测专题模块
-
微信小程序前端微信小程序前端易错点收集查看
-
css/less/sass样式控制在开发过程中的一些样式控制bug规避查看
-
tp5开发小程序tp5开发小程序时错误积累查看
-
PHP错题集PHP在实际开发过程中遇到的问题查看
-
MySql数据库使用MySql在实际开发中遇到的错误总结查看
-
TP5错题集积累tp5框架在实际开发过程中遇到的问题查看
-
uni-app爬坑主要用于uni-app项目中遇到的一些问题查看
-
Vue.js易错收集vue.js项目常见错误收集整理查看
-
uni-app开发微信小程序uni-app开发微信小程序的一些爬坑积累查看
-
LinuxLinux在部署、开发、运维时遇见的错误积累查看
-
安全设计常见安全设计查看
-
Redis项目中使用redis的相关错误积累查看
-
前端特效前端特效相关错题集查看
最新博文
-
workerman知识简述(1)
socket一.简介
workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及libevent事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。
workerman的目标是让PHP开发者更容易的开发出基于socket的高性能的应用服务,而不用去了解PHP socket以及PHP多进程细节。 workerman本身是一个PHP多进程服务器框架,具有PHP进程管理以及socket通信的模块,所以不依赖php-fpm、nginx或者apache等这些容器便可以独立运行。
实际上Workerman类似一个PHP版本的nginx,核心也是多进程+Epoll+非阻塞IO。Workerman每个进程能维持上万并发连接。由于本身常住内存,不依赖Apache、nginx、php-fpm这些容器,拥有超高的性能。同时支持TCP、UDP、UNIXSOCKET,支持长连接,支持Websocket、HTTP、WSS、HTTPS等通讯协以及各种自定义协议。拥有定时器、异步socket客户端、异步Mysql、异步Redis、异步Http、异步消息队列等众多高性能组件。
二.运用方向
1、即时通讯类 例如网页即时聊天、即时消息推送、微信小程序、手机app消息推送、PC软件消息推送等等 [示例 workerman-chat聊天室 、 web消息推送 、 小蝌蚪聊天室]
2、物联网类 例如Workerman与打印机通讯、与单片机通讯、智能手环、智能家居、共享单车等等。 [客户案例如 易联云、易泊时代等]
3、游戏服务器类 例如棋牌游戏、MMORPG游戏等等。[示例 browserquest-php]
4、SOA服务化 利用Workerman将现有业务不同功能单元封装起来,以服务的形式对外提供统一的接口,达到系统松耦合、易维护、高可用、易伸缩。[示例 workerman-json-rpc、 workerman-thrift]
5、其它服务器软件 例如 GatewayWorker,PHPSocket.IO,http代理,sock5代理,分布式通讯组件,分布式变量共享组件,消息队列、DNS服务器、WebServer、CDN服务器、FTP服务器等等
6、中间件 例如异步MySQL组件,异步redis组件,异步http组件,异步消息队列组件,异步dns组件,文件监控组件,还有很多第三方开发的组件框架等等
三.特性
1、纯PHP开发
使用WorkerMan开发的应用程序不依赖php-fpm、apache、nginx这些容器就可以独立运行。 这使得PHP开发者开发、部署、调试应用程序非常方便。
2、支持PHP多进程
为了充分发挥服务器多CPU的性能,WorkerMan默认支持多进程多任务。WorkerMan开启一个主进程和多个子进程对外提供服务, 主进程负责监控子进程,子进程独自监听网络连接并接收发送及处理数据,由于进程模型简单,使得WorkerMan更加稳定,更加高效。
3、支持TCP、UDP
WorkerMan支持TCP和UDP两种传输层协议,只需要更改一个属性便可以更换传输层协议,业务代码无需改动。
4、支持长连接
很多时候需要PHP应用程序要与客户端保持长连接,比如聊天室、游戏等,但是传统的PHP容器(apache、nginx、php-fpm)很难做到这一点。 使用WorkerMan,只要服务端业务不主动调用关闭连接接口,便可以使用PHP长连接。WorkerMan单个进程可以支持上万的并发连接,多进程则支持数十万的甚至百万并发连接。
5、支持各种应用层协议
WorkerMan接口上支持各种应用层协议,包括自定义协议。在WorkerMan中更换协议同样非常简单,同样只是配置一个字段,协议自动切换,业务代码零改动,甚至可以开启多个不同协议的端口,满足不同的客户端需求。
6、支持高并发
WorkerMan支持Libevent事件轮询库(需要安装Libevent扩展), 使用Libevent在高并发时性能非常卓越,如果没有安装Libevent则使用PHP内置的Select相关系统调用,性能也同样非常强悍。
7、支持服务平滑重启
当需要重启服务时(例如发布版本),我们不希望正在处理用户请求的进程被立刻终止,更不希望重启的那一刻导致客户端通讯失败。WorkerMan提供了平滑重启功能,能够保障服务平滑升级,不影响客户端的使用。
8、支持文件更新检测及自动加载
在开发过程中,我们希望在我们改动代码后能够立刻生效,以便查看结果。WorkerMan提供了FileMonitor文件监控组件,只要文件有更新,WorkerMan会自动运行reload,以便加载新的文件,使之生效。
9、支持以指定用户运行子进程
因为子进程是实际处理用户请求的进程,为了安全考虑,子进程不能有太高的权限,所以WorkerMan支持设置子运行进程运行的用户,使你的服务器更加安全。
10、支持对象或者资源永久保持
WorkerMan在运行过程中只会载入解析一次PHP文件,然后便常驻内存,这使得类及函数声明、PHP执行环境、符号表等不会重复创建销毁,这与Web容器下运行的PHP机制是完全不同的。在WorkerMan中,一个进程生命周期内静态成员或者全局变量在不主动销毁的情况下是永久保持的,也就是将对象或者连接等资源放到全局变量或者类静态成员中则当前进程的整个生命周期内的所有请求都可以复用。例如只要单个进程内初始化一次数据库连接,则以后这个进程的所有请求都可以复用这个数据库连接,避免了频繁连接数据库过程中TCP三次握手、 数据库权限验证、断开连接时TCP四次握手的过程,极大的提高了应用程序效率。
11、高性能
由于php文件从磁盘读取解析一次后便会常驻内存,下次使用时直接使用内存中的opcode, 极大的减少了磁盘IO及PHP中请求初始化、创建执行环境、词法解析、语法解析、编译opcode、请求关闭等诸多耗时过程, 并且不依赖nginx、apache等容器,少了nginx等容器与PHP通信的开销,最主要的是资源可以永久保持,不必每次初始化数据库连接等等, 所以使用WorkerMan开发应用程序,性能非常高。
12、支持HHVM
支持在HHVM虚拟机上运行,可成倍提升PHP性能。尤其是在cpu密集运算业务中,性能非常优异。通过实际压力测试对比,在没有负载业务的情况下,WorkerMan在HHVM下运行比在Zend PHP5.6运行网络吞吐量提高了30-80%左右
13、支持分布式部署
14、支持守护进程化
15、支持多端口监听
16、支持标准输入输出重定向
阅读更多风口下的猪2020-02-06【socket】
-
PCB(进程控制块)包含信息
计算机操作系统1.程序ID(PID、进程句柄):它是唯一的,一个进程都必须对应一个PID。PID一般是整型数字
2.特征信息:一般分系统进程、用户进程、或者内核进程等
3. 进程状态 :运行、就绪、阻塞,表示进程现的运行情况
4.优先级:表示获得CPU控制权的优先级大小
5.通信信息:进程之间的通信关系的反映,由于 操作系统 会提供 通信信道
6.现场保护区:保护阻塞的进程用
7.资源需求、分配 控制信息
8.进程实体信息,指明程序路径和名称,进程数据在物理内存还是在 交换分区 (分页)中
9.其他信息:工作单位,工作区,文件信息等
在Unix系统中进程由三部分组成,分别是进程控制块、正文段和数据段。Unix系统中把进程控制块分成proc结构和user结构两部分
proc存放的是系统经常要查询和修改的信息,需要快速访问,因此常将其装入内存
阅读更多风口下的猪2020-02-05【计算机操作系统】
-
串行、并行、并发
计算机操作系统并行和串行:
- 串行:一次只能取得一个任务并执行这一个任务
- 并行:可以同时通过多进程/多线程的方式取得多个任务,并以多进程或多线程的方式同时执行这些任务
- 注意点:
- 如果是单进程/单线程的并行,那么效率比串行更差
- 如果只有单核cpu,多进程并行并没有提高效率
- 从任务队列上看,由于同时从队列中取得多个任务并执行,相当于将一个长任务队列变成了短队列
- 如果是单进程/单线程的并行,那么效率比串行更差
并发:
- 并发是一种现象:同时运行多个程序或多个任务需要被处理的现象
- 这些任务可能是并行执行的,也可能是串行执行的,和CPU核心数无关,是操作系统进程调度和CPU上下文切换达到的结果
- 解决大并发的一个思路是将大任务分解成多个小任务:
- 可能要使用一些数据结构来避免切分成多个小任务带来的问题
- 可以多进程/多线程并行的方式去执行这些小任务达到高效率
- 或者以单进程/单线程配合多路复用执行这些小任务来达到高效率
- 可能要使用一些数据结构来避免切分成多个小任务带来的问题
更详细内容,推荐链接:https://www.cnblogs.com/f-ck-need-u/p/11161481.html
阅读更多风口下的猪2020-02-05【计算机操作系统】
- 串行:一次只能取得一个任务并执行这一个任务
-
多进程、多线程
计算机操作系统一、多线程是什么?
说起多线程,那么就不得不说什么是线程,而说起线程,又不得不说什么是进程。
进程可以简单的理解为一个可以独立运行的程序单位,它是线程的集合,进程就是有一个或多个线程构成的。而线程是进程中的实际运行单位,是操作系统进行运算调度的最小单位。可理解为线程是进程中的一个最小运行单元。
那么多线程就很容易理解:多线程就是指一个进程中同时有多个线程正在执行。
为什么要使用多线程?
- 在一个程序中,有很多的操作是非常耗时的,如数据库读写操作,IO操作等,如果使用单线程,那么程序就必须等待这些操作执行完成之后才能执行其他操作。使用多线程,可以在将耗时任务放在后台继续执行的同时,同时执行其他操作。
- 可以提高程序的效率。
- 在一些等待的任务上,如用户输入,文件读取等,多线程就非常有用了。
多线程的缺点:
- 使用太多线程,是很耗系统资源,因为线程需要开辟内存。更多线程需要更多内存。
- 影响系统性能,因为操作系统需要在线程之间来回切换。
- 需要考虑线程操作对程序的影响,如线程挂起,中止等操作对程序的影响。
- 线程使用不当会发生很多问题。
总结:多线程是异步的,但这不代表多线程真的是几个线程是在同时进行,实际上是系统不断地在各个线程之间来回的切换(因为系统切换的速度非常的快,所以给我们在同时运行的错觉)。
二、多进程是什么?
进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。凡是用于完成操作系统的各种功能的进程就是系统进程,而所有由你启动的进程都是用户进程。 同理,多进程就是指计算机同时执行多个进程,一般是同时运行多个软件。
三、多线程与多进程,选择谁?
下面是本人从知乎-pansz上转载的一个答案,非常通俗地回答了这个问题。
- 单进程单线程:一个人在一个桌子上吃菜。
- 单进程多线程:多个人在同一个桌子上一起吃菜。
- 多进程单线程:多个人每个人在自己的桌子上吃菜。
多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。。。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
1。对于 Windows 系统来说,【开桌子】的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜。因此 Windows 多线程学习重点是要大量面对资源争抢与同步方面的问题。
2。对于 Linux 系统来说,【开桌子】的开销很小,因此 Linux 鼓励大家尽量每个人都开自己的桌子吃菜。这带来新的问题是:坐在两张不同的桌子上,说话不方便。因此,Linux 下的学习重点大家要学习进程间通讯的方法。
开桌子的意思是指创建进程。开销这里主要指的是时间开销。
可以做个实验:创建一个进程,在进程中往内存写若干数据,然后读出该数据,然后退出。此过程重复 1000 次,相当于创建/销毁进程 1000 次。在我机器上的测试结果是:
UbuntuLinux:耗时 0.8 秒 Windows7:耗时 79.8 秒 两者开销大约相差一百倍。
这意味着,在 Windows 中,进程创建的开销不容忽视。换句话说就是,Windows 编程中不建议你创建进程,如果你的程序架构需要大量创建进程,那么最好是切换到 Linux 系统。大量创建进程的典型例子有两个,一个是 gnu autotools 工具链,用于编译很多开源代码的,他们在 Windows 下编译速度会很慢,因此软件开发人员最好是避免使用 Windows。另一个是服务器,某些服务器框架依靠大量创建进程来干活,甚至是对每个用户请求就创建一个进程,这些服务器在 Windows 下运行的效率就会很差。这"可能"也是放眼全世界范围,Linux 服务器远远多于 Windows 服务器的原因。
再次补充:如果你是写服务器端应用的,其实在现在的网络服务模型下,开桌子的开销是可以忽略不计的,因为现在一般流行的是按照 CPU 核心数量开进程或者线程,开完之后在数量上一直保持,进程与线程内部使用协程或者异步通信来处理多个并发连接,因而开进程与开线程的开销可以忽略了。
另外一种新的开销被提上日程:核心切换开销。 现代的体系,一般 CPU 会有多个核心,而多个核心可以同时运行多个不同的线程或者进程。当每个 CPU 核心运行一个进程的时候,由于每个进程的资源都独立,所以 CPU 核心之间切换的时候无需考虑上下文。 当每个 CPU 核心运行一个线程的时候,由于每个线程需要共享资源,所以这些资源必须从 CPU 的一个核心被复制到另外一个核心,才能继续运算,这占用了额外的开销。换句话说,在 CPU 为多核的情况下,多线程在性能上不如多进程。
因而,当前面向多核的服务器端编程中,需要习惯多进程而非多线程。
阅读更多风口下的猪2020-02-05【计算机操作系统】
-
js前端面向对象编程实际项目经验(6)--处理逻辑与功能
软件开发函数对象模块内部,必然会涉及到内部各功能函数之间的相互调用。
我们在设计模块功能时,一定要注意一个大原则:
逻辑不能放在功能模块里写,即对象里面不能做功能间的相互调用。
阅读更多风口下的猪2020-02-04【软件开发】
-
js前端面向对象编程实际项目经验(5)--面向对象编程核心三要素:数据池、函数对象模块、入口函数
软件开发面向对象编程的核心三要素是
- 数据池
- 函数对象模块
- 入口函数
一.数据池
我们都知道图灵机,是控制器按照规则表,对一条无限长的数据带进行读写修改,并生成符合运算规则的结果。数据是程序和算法的核心,特别是业务逻辑,其根本是围绕数据展开的。
数据池在面向对象编程中的作用,就是那条图灵机的无限数据带。
(1)其提供必要的数据格式、数据字段。使我们的业务逻辑在它的基础上逆向形成;
(2)开发过程中,作为各个模块公共耦合的要素。(所以一般情况下数据池里面的数据格式和类型不会更改,只有项目升级不得不改时,才更改);
例如:在页面入口文件开始,便要申明数据池,供全部模块使用
var data={
"userName":"",
"userUid":"",
"isSystem":false,
"chatContent":"",
"isOnline":false
}
二.函数对象模块
函数对象模块,作为项目管理的最小单位,是程序开发设计的基石。
优良的面向对象编程设计,要满足高内聚、低耦合、复用性强、易于维护、性能较好等基本特征。
三.入口函数
入口函数,是业务逻辑的主调官,相当于后端的主方法。我们在初始化入口函数方法中定义逻辑。
eg:
init();
function init(){
var $user=new User();
$user.getUserName();
var $login=new Login();
$login.login();
}
阅读更多风口下的猪2020-02-04【软件开发】
-
js前端面向对象编程实际项目经验(4)--原型链
软件开发原型链的作用是:为了对象实例化时,避免其内部所有代码都跑一遍影响性能。
原型链申明函数对象的方法和属性时,将其提出对象内部。因为构造函数实例对象(new Class时,该class便是构造函数的原型对象,其便有了prototype属性)有prototype熟悉,该属性是一个指针,指向被实例的原型对象。
那么此时实例化对象时,里面没有代码,不会所有代码都跑一遍,只有使用该功能方法或者属性时才会跑。
eg:
function User(){}
User.prototype.saveUserName=function($userName){
data.userName=$userName;
}
User.prototype.getUserName=function(){
if(data.userName){
return data.userName;
}
}
阅读更多风口下的猪2020-02-04【软件开发】
-
js前端面向对象编程实际项目经验(3)--多态性
软件开发多态的使用前面继承性提到了。
设计模块内功能函数时,要考虑项目整体。看有哪些业务板块会用到这个功能函数,收集起来整理。
(1)交集部分,便是功能函数通用部分。
(2)不同部分,看是因为哪些不同的输入造成的。以此来设计传入哪些参数、如何使用if-else、switch来做这些不同的部分的多态
多态势必涉及到多态的识别、管理,也就是说判断在多态中非常常见。这里考虑的主要是多态在实际项目中的一些技巧。为了简化代码或者提升性能
1.return false、return 、return 0的提前
为了性能,一些判断return false提前;
2.三目运算||
eg:
data.userName=$username||"";
3.三目运算?:
eg:
data.userName=(isget):$username:"";
阅读更多风口下的猪2020-02-04【软件开发】
-
js前端面向对象编程实际项目经验(2)--继承性
软件开发继承性,节省了重复造轮子。
一.实际开发场景中继承性的目的
(1)避免重复制造轮子,节省开发时间成本,精简代码便于管理;
(2)实际开发场景中的继承性不是停留在拿给外部用,我们要考虑的是该模块函数对象功能并不能满足业务时,怎么办? 这就要围绕“开闭” 和 “多态” 了。在不改变模块内部业务的同时,满足业务逻辑的定制化调用。
二.继承性设计的习惯
(1)很多个页面都会用到该函数对象时,将其写成类,放在项目公共目录,供所有页面实例化调用;
(2)设计模块内功能函数时,要考虑项目整体。看有哪些业务板块会用到这个功能函数,收集起来整理。
交集部分,便是功能函数通用部分。
不同部分,看是因为哪些不同的输入造成的。以此来设计传入哪些参数、如何使用if-else、switch来做这些不同的部分的多态
(3)开闭,也就是私公问题。
但凡涉及到安全、隐私等不想被外部调用的情况,考虑用protected。
该功能函数被外部多处调用,且有多态需求的,考虑用public。
阅读更多风口下的猪2020-02-04【软件开发】
-
js前端面向对象编程实际项目经验(1)--封装性
软件开发js封装的对象,其实是一个特殊的函数。每个函数对象按照单一职责、高内聚、低耦合等原则,会封装多个功能函数,形成一个处理某个或某类业务模块的唯一函数对象。
一.实际开发场景中封装性的目的
封装性的目的是
(1)为了适应多人开发场景,避免变量、函数等命名冲突;
(2)为了避免重复造轮子。专人专用,某类业务逻辑就调用处理该类业务对象的方法或属性来处理;
(3)便于项目管理、节点控制、维护升级。由于各函数对象隔离,也就是互不影响,那么项目管理就支持并非管理而不是流管理。某类业务需要升级优化,则只改动该模块部分,不需要改动大面积的代码。
二.函数对象封装的习惯
(1)函数对象命名首字大写(和后端的类一样);
(2)内部申明变量和方法,是挂在this关键字下面;
(3)执行方法不是直接执行,而是通过new关键字来创建实例来调用或者重构;
(4)函数命名用动名结构。
例如:eg:
function User($name){
this.name=$name;
this.getUserName=function(){
return data.name;
}
}
var $user=new User('张三');
$user.getUserName();
总结:
(1)函数对象封装,其实借用的是一种“命名空间”的隔离性。因为在堆内存中各份引用数据是隔离的(后端用的是class类和目录来形成命名空间);
(2)现在的js,特别是ES6出来后,前端越来越像后端,有class类。通过import和export,引入到具体的开发逻辑中。但为了性能(因为每实例化一个对象,这个对象下面的代码都会跑一遍),项目中主要还是用对象函数,es6的class更多地还是为了做AOP片层去处理某一大类业务,例如前端验证、公共模块调用。即编程模式是“面向过程+面向对象+AOP片层”
阅读更多风口下的猪2020-02-04【软件开发】
-
浅谈js中的深拷贝与浅拷贝
JavaScript什么是深拷贝,什么是浅拷贝
说到深浅拷贝,就不得不提到另外一个知识点,那就是引用类型和基本类型以及堆和栈的区别。
再复习一遍~
1)堆比栈大,栈比堆速度快;
2)基本数据类型比较稳定,而且相对来说占用的内存小;
3)引用数据类型大小是动态的,而且是无限的,引用值的大小会改变,不能把它放在栈中,否则会降低变量查找的速度,因此放在变量栈空间的值是该对象存储在堆中的地址,地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响;
4)堆内存是无序存储,可以根据引用直接获取;基本类型:undefined、null、string、number、boolean、symbol(es6)
引用类型:Object及各种Object的衍生类型,Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。
记住这一点:基本数据类型值不可变。对于基本类型,其实是不存在深拷贝与浅拷贝的区别的。基本类型保存在栈内存中,复制变量值时,基本类型会在变量对象上创建一个新值,再复制给新变量。此后,两个变量的任何操作都不会影响到对方。
而引用类型保存在堆内存中,在创建一个对象类型时,计算机会在内存中开辟一个空间来存放值,我们要找到这个空间,需要知道这个空间的地址,这个地址是存放在栈内存中的,变量存放的就是这个地址,复制变量时其实就是将地址复制了一份给新变量,两个变量的值都指向存储在堆中的一个对象,也就是说,其实他们引用了同一个对象,改变其中一个变量就会影响到另一个变量。因此,深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象的。
那么再来定义一下深拷贝与浅拷贝。
浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放对象,且修改新对象不会影响原对象。
阅读更多风口下的猪2020-02-04【JavaScript】