PHP基础和中等面试题

1 以下代码会输出啥
<?php
    class a{
        var $abc="ABC";
    }
    $b=new a;
    $c=$b;
    $b->abc="DEF";
    echo $c->abc;
?>

会输出啥内容?

A. ABC
B. DEF
C.其它
D. 我不知道

答案:B
解析:考察对象复制问题。对象的复制都是引用复制

2.输出多少?
$a=2;
$b=1;
function test(&$a){
    $a=$a+100;
}
test($b);
echo $b;
//输出多少?

A. 102
B. 1
C.101
D.其它

答案:C
解析:考察引用复制问题。加取地址符后,在函数内操作,会改变原变量的值,test( b ) , b), b),b是实参,因为函数内对 a 这 个 形 参 的 操 作 , 会 改 变 a这个形参的操作,会改变 ab的值,$b原来是1,在函数内加100后,输出为101

3PHP抽象类可以实例化吗?

A. 可以
B. 不可以

答案:B
解析:抽象类不能实例化

4以下关于接口和抽象说明,正确的是哪些?

A. 抽象类中的方法可以有方法体
B. 抽象类的方法前加abstract
C.接口中的方法能定义为protect
D.一个类可以实现多个接口
E.类可以不实现接口中的所有方法

答案:AD
解析:

5写一个email和手机号的正则表达式
email正则

/^[a-zA-Z0-9-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]){1,3}$/

手机号正则

/^1[346789]\d{9}$/
6PHP有哪些数据类型
基础类型:布尔、整形、浮点型、字符串

复合类型:数组、对象

特殊类型:资源、null
7isset() 和 empty() 区别?

isset() 判断变量是否设置

empty()判断变量是否为空

8请说明 PHP 中传值与传引用的区别。什么时候传值什么时候传引用?

传值:把变量的值传给另一个变量,会开辟内容空间存储

传引用:把变量的地址传给另一个变量,改变当前变量,另一个变量也会改变

9foo()和@foo()之间有什么区别?

@是PHP提供的错误信息屏蔽的专用符号。

使用@foo不会出现Warning,而原来foo 在遇到错误时会在页面上访提示Warning。

10常见的php的预定义变量有哪些?
$_GLOBAL

$_POST

$_GET

$_REQUEST

$_ENV

$_FILE

$_SESSION

$_COOKIE
11TCP怎么建立连接?

tcp是传输层协议,使用三次握手建立连接。当主动方发出SYN连接请求后,等待对方回答SYN,ACK。这种建立连接的方式可以防止产生错误的连接。TCP使用的流量控制协议是可变大小的滑动窗口协议。第一次握手,建立连接时,客户端发送SYN包(SEQ= x)到服务器,并进入SYN_SEND状态,等待服务器确认。第二次握手:服务器收到SYN包,确认客户的SYN(ACK=x+1),同时自己也送一个SYN包(SEQ=y),即SYN+ACK包,此时服务器进入SYN_RECV状态。第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=y+1),此包发送完毕,客户端和服务器进入established状态,完成三次握手。

TCP的三次握手、四次挥手详见以下链接:
https://blog.csdn.net/weixin_41882200/article/details/114713348

12 | 代表什么呢? 3 | 6 = 多少?

1是位或操作

3 | 6 = 7, 3转成二进制是11,6转成二进制是110,位或操作后结果是111,转成十进制就是7

13简述 private、 protected、 public修饰符的访问权限

private:只有本来才可以访问
protected:本类和继承类可以访问
public:完全公开,没有访问限制

14常用的魔术方法有哪些?举例说明
1、__get、__set

这两个方法是为在类和他们的父类中没有声明的属性而设计的

__get( $property )       当调用一个未定义的属性时访问此方法
__set( $property, $value )    给一个未定义的属性赋值时调用
这里的没有声明包括访问控制为proteced,private的属性(即没有权限访问的属性)

2、__isset、__unset

__isset( $property ) 当在一个未定义的属性上调用isset()函数时调用此方法
__unset( $property ) 当在一个未定义的属性上调用unset()函数时调用此方法
与__get方法和__set方法相同,这里的没有声明包括访问控制为proteced,private的属性(即没有权限访问的属性)
3、__call

__call( $method, $arg_array ) 当调用一个未定义(包括没有权限访问)的方法是调用此方法

4、__autoload

__autoload 函数,使用尚未被定义的类时自动调用。通过此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

注意: 在 __autoload 函数中抛出的异常不能被 catch 语句块捕获并导致致命错误。

5、__construct、__destruct

__construct 构造方法,当一个对象被创建时调用此方法,好处是可以使构造方法有一个独一无二的名称,无论它所在的类的名称是什么,这样你在改变类的名称时,就不需要改变构造方法的名称
__destruct 析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法
默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源.,析构函数允许你在使用一个对象之后执行任意代码来清除内存,当PHP决定你的脚本不再与对象相关时,析构函数将被调用.,在一个函数的命名空间内,这会发生在函数return的时候,对于全局变量,这发生于脚本结束的时候,如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值,通常将变量赋值勤为NULL或者调用unset。

6、__clone

PHP5中的对象赋值是使用的引用赋值,使用clone方法复制一个对象时,对象会自动调用__clone魔术方法,如果在对象复制需要执行某些初始化操作,可以在__clone方法实现。

7、__toString 

__toString方法在将一个对象转化成字符串时自动调用,比如使用echo打印对象时,如果类没有实现此方法,则无法通过echo打印对象,否则会显示:Catchable fatal error: Object of class test could not be converted to string in,此方法必须返回一个字符串。

在PHP 5.2.0之前,__toString方法只有结合使用echo() 或 print()时 才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符),但 不能用于非字符串环境(如使用%d修饰符)。从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。

8、__sleep、__wakeup

__sleep 串行化的时候用
__wakeup 反串行化的时候调用
serialize() 检查类中是否有魔术名称 __sleep 的函数。如果这样,该函数将在任何序列化之前运行。它可以清除对象并应该返回一个包含有该对象中应被序列化的所有变量名的数组。

使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。

相反地,unserialize() 检查具有魔术名称 __wakeup 的函数的存在。如果存在,此函数可以重建对象可能具有的任何资源。使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。

9、__set_state

当调用var_export()时,这个静态 方法会被调用(自PHP 5.1.0起有效)。本方法的唯一参数是一个数组,其中包含按array(’property’ => value, …)格式排列的类属性。

10、__invoke

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。PHP5.3.0以上版本有效
11、__callStatic

它的工作方式类似于 __call() 魔术方法,__callStatic() 是为了处理静态方法调用,PHP5.3.0以上版本有效,PHP 确实加强了对 __callStatic() 方法的定义;它必须是公共的,并且必须被声明为静态的。同样,__call() 魔术方法必须被定义为公共的,所有其他魔术方法都必须如此。

15 请列举几个php数组函数?
1.获取数组所有的键或值:array_keys() array_values()
2.交换数组中键和值的位置,若重复前面的会被后面的覆盖:array_flip()
3.给定的值是否在数组中:in_array(value,array)
4.在数组中搜索某个值,在则返回它的键,不在则返回FALSE:array_search()
5.给定键是否存在数组中:isset(array[key])和array_key_exists(key,array)
6.获取数组元素的个数:count(array,mode),mode为1时表示递归地对数组进行计数,默认为0。别名sizeof()
7.将数组中的键名改为全小写或大写:array_change_key_case(array,case)
8.统计数组中所有的值出现的次数:array_count_value(array)。返回一个数组,键是原数组的值,值是这个元素在原数组出现的次数
9.得到数组的第一个或最后一个键名:array_key_first(array)、array_key_last(array)
10.弹出数组的最后一个元素:array_pop($array);
11.将数组反序:array_reverse(array)
16session与cookie的区别?

1、cookie 和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。

2、两个都可以用来存私密的东西,bai同样也都有有效期的说法,区别在于session是放在服务器上的,过期与否取决于服务期的设定,cookie是存在客户端的,过去与否可以在cookie生成的时候设置进去。

(1)、cookie数据存放在客户的浏览器上,session数据放在服务器上 ;

(2)、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session ;

(3)、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE ;

(4)、单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K;

(5)、所以将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。

3、cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。

4、cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据。

17php中=区别

===不光比较值还比较类型

==只比较值

18请说说对php中final 关键字的理解

final—用于类、方法前。

final类—不可被继承。

final方法—不可被覆盖。

如果我们不希望一个类被继承,我们使用final来修饰这个类。这个类将无法被继承。

19.以下执行,会输出啥?
<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";
?>

答案:
0.2
Caught exception:Division by zero.

20、你用过哪些PHP设计模式?

答案:
1.工厂模式
建立一个工厂(一个函数或者类方法)来制造新的对象
工厂模式是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不用直接new.这样,如果你想要更改所创建的对象类型,只需要更改改工厂即可。使用该工厂的所有代码会自动更改。

2.单例模式
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。
单例模式分3种:懒汉式单例、饿汉式单例、登记式单例。
单例模式的三个特点
(1)只能有一个实例
(2)必须自行创建这个实例
(3)必须给其他对象提供这一实例
为什么要使用PHP单例模式?
PHP一个主要应用场合就是应用程序与数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库句柄链接数据库的行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗系统和内存资源。

3.观察者模式
(1)观察者模式(observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
(2)场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要更改事件的主体代码。
(3)观察者模式实现了低耦合,非侵入式的通知与更新机制。定义一个事件触发抽象类。

4.适配器模式

将各种截然不同的函数接口封装成统一的API。PHP中的数据库操作有MYSQL,MYSQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。

5.策略模式

策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。
策略模式指的是程序中涉及策略控制的一种模式。策略模式功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多态性思想。
策略模式的三个角色:
(1)抽象策略角色
(2)具体策略角色
(3)环境角色(对抽象策略角色的引用)
实现步骤:
(1)定义抽象角色类(定义好各个实现的共同抽象方法)
(2)定义具体策略类(具体实现父类的共同方法)
(3)定义环境角色类(私有化申明抽象角色变量,重载构造方法,执行抽象方法)
在编程领域之外,有很多例子是关于策略模式的,如:
早晨从家去上班,可以乘坐地铁,坐公交、走路、打车等等。每个策略可以得到相同的结果,但使用了不同的资源。

6.注册模式
注册模式,解决了全局共享和交换对象。已经创建好的对象,挂在了某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上,任何地方直接去访问。

21、socket 连接步骤?

答案:
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远程主机的IP地址,远程主机的协议端口。
socket连接过程
建立socket连接至少需要一套套接字,其中一个运行于客户端,成为clientSocket,另一个运行于服务器端,称为ServerSocket
套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述他要连接的服务器的套接字,指出服务器的套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,他就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

22、如何解决超卖问题

答案:
1.悲观锁
2.乐观锁
3.队列
4.分布式锁

23、怎么实现第三方登录?

答案:
第三方登录主要是基于auth协议来实现的,下面简单说一下流程:

  1. 首先我们需要以开发者的身份像第三方登录平台申请接入应用,申请成功后,我们会获得一个appID和一个secretID.
  2. 当我们的网站需要接入第三方登录时,会引导用户跳转到第三方的授权登录页面,此时把之前申请的appID和secretID带给登录授权页面。
  3. 用户登录成功后即得到授权,第三方会返回一个临时的code给我们的网站。
  4. 我们的网站接受到code后,再次向我们的第三方发起请求,并携带接受的code,从第三方获取access_token.
  5. 第三方处理请求后,会返回一个access_token给我们的网站,我们的网站获取到access_token后就可以调用第三方提供的接口了,比如获取用户的信息等。最后把用户的信息存入到我们站点的数据库,并把信息保存到session中,实现用户的第三方登录。
24、谈谈对MVC的认识?

核心思想:
视图和用户交互通过事件导致控制器改变,控制器改变导致模型改变,或者控制器同时改变两者。模型改变导致视图改变,或者视图改变潜在的从模型里面获取参数来改变自己。他的好处是可以将界面和业务逻辑分离。

model(模型),是程序的主体部分,主要包含业务数据和业务逻辑。在模型层,还会涉及到用户发布的服务,在服务中会根据不同的业务需求,更新业务模型中的数据

view(视图),是程序呈现给用户的部分,是用户和程序交互的接口,用户会根据具体的业务需求,在view视图层输入自己特定的业务数据,并通过界面的事件交互,将对应的输入参数提交给后台控制器进行处理。

controler(控制器),是用来处理用户输入的数据,已经更新业务模型的部分。控制器中接收用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。

25、Laravel 中 insert () 和 insertGetId () 函数之间的显著区别是什么?

insert()函数仅用于将记录插入到数据库,不返回自增ID
insertGetId()会在表中插入一条记录,但当ID字段自动递增时使用(插入记录并返回自增的ID)

26、说下你对PHP中trait的理解

自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait.
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

<?php
trait  Trait_a {
     function    getReturnType(){ /*1*/ }
     function    getReturnDescription() { /*2*/ }
 }
 traitTrait_b {
     function    getReturnType() { /*1*/ }
     function    getReturnDescription() { /*2*/ }
 }
class  class1   extend   sparent_class1 {
	useTrait_a;
	/* ... */
}
class   class2   extends parent_class2 {
	useTrait_a,Trait_b;
	/* ... */
}

使用use语句利用这个特性。通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。

从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法.

27、请你说说对OOP思想的理解

面向对象编程是一钟计算机编程架构。OOP的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。
核心思想:封装、继承、多态
OOP达到了软件工程的三个主要目标:重用性、灵活性、扩展性。
为了实现整体运算,每个对象都能够接受到信息、处理数据和向其它对象发送信息

28、一个100G的大文件,里面存储了电话号码,文件格式如下:

15112345678
15112345679
15112345680
15112345681
15112345682

如何确认电话号码15112345680是否在文件中?

答案:
方法一:用shell_exec(“grep 15112345680 文件名.txt”)【说明】:这个是用linux层面去读取,直接交给操作系统去处理

方法二:fseek+fread函数进行检索,【说明】:原理:fseek可以定位文件读取的指针位置,而fread可以从指针位置处取出指定长度的字符串。注意这个指针是基于磁盘文件的,文件无需先读入内存,所以适合大文件读取。

29、请写一个工厂模式的示例代码
*简单工厂模式(静态工厂方法模式)*//**- 

Interface people 人类*/
interface  people  {
	public function say();  
}
/**- Class man 继承people的男人类*/

class	man	implements	people  {
// 具体实现people的say方法
	public	function	say()      
	{
		echo'我是男人<br>';     
	} 
}
/**- Class women 继承people的女人类*/
class	women	implements	people  {
// 具体实现people的say方法
	public	function	say()      
	{
	echo'我是女人<br>';     
	 }  
 }
 
 /**- Class SimpleFactoty 工厂类*/
 class	SimpleFactoty  {
	 // 简单工厂里的静态方法-用于创建男人对象
	 static	function	createMan()      
 	{
 		return	new man();      
 	}
 	// 简单工厂里的静态方法-用于创建女人对象
 	static	function	createWomen()     
 	 {
 	 return	new  women();     
 	  }  
  }
  
 /**- 具体调用*/
 $man=SimpleFactoty::createMan();
 $man->say();

$woman=SimpleFactoty::createWomen();
$woman->say();

30、PHP实现协程的方式是什么?

yield

31、谈谈你对TCP连接是如何建立和断开的

三次握手四次挥手
三次握手:
(1)首先客户端向服务器端发送一段TCP报文,其中:标记位为SYN,表示“请求建立新连接”;序号为Seq=X(X一般为1);随后客户端进入SYN-SENT阶段。
(2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);序号为Seq=y;确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段。
(3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;随后客户端进入ESTABLISHED阶段。

四次挥手:
(1)首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:标记位为FIN,表示“请求释放连接“;序号为Seq=U;随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
(2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:标记位为ACK,表示“接收到客户端发送的释放连接的请求”;序号为Seq=V;确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;随后服务器端开始准备释放服务器端到客户端方向上的连接。客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
(3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中: w o m a n = S i m p l e F a c t o t y : : c r e a t e W o m e n ( ) ; woman=SimpleFactoty::createWomen(); woman=SimpleFactoty::createWomen();woman->say();
标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。序号为Seq=W;确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
(4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:标记位为ACK,表示“接收到服务器准备好释放连接的信号”。序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。随后客户端开始在TIME-WAIT阶段等待2MSL

32、TCP和UDP的区别是什么?

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

简约的回答:

  • TCP 是面向连接的,UDP 是面向无连接的
  • UDP程序结构较简单TCP 是面向字节流的,UDP 是基于数据报的
  • TCP 保证数据正确性,UDP 可能丢包
  • TCP 保证数据顺序,UDP 不保证
33、构造函数和析构函数的理解

构造函数:
PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作析构函数:
PHP 5 引入了析构函数的概念。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行

34、PHP如何获取客户端/服务端 IP,以及客户端真实IP

客户端IP: $_SERVER[‘REMOTE_ADDR’]
服务端IP: $_SERVER[‘SERVER_ADDR’]
客户端IP(代理透传): $_SERVER[‘HTTP_X_FORWARDED_FOR’]

35、如何解决PHP内存溢出问题?

1、ini_set(‘memory_limit’,‘500M’);
2、unset使用完毕的变量
3、分批处理,避免生成大数组

36、PHP的垃圾回收机制中的zval变量容器是干啥用的?

引用计数器,如果安装了xdebug,可以打印出

<?php
	$a="new string";
	$c=$b=$a;
	xdebug_debug_zval( 'a' );
	unset( $b, $c );
	xdebug_debug_zval( 'a' );
?>
以上程序输出:
a: (refcount=3, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'

PHP5

typedef	unsigned	int	zend_object_handle;
typedef	struct	_zend_object_value {				
	zend_object_handlehandle;
	zend_object_handlers*handlers;
} 	zend_object_value;

typedef	union	_zvalue_value {
longlval;                                      /* long value */
doubledval;                            /* double value */
struct {
	char*val;
	intlen;       
 } str;
 HashTable	*ht;                          /* hash table value */
 zend_object_valueobj;
} zvalue_value;

struct_zval_struct {
/* Variable information */
zvalue_valuevalue;             /* value */
zend_uintrefcount__gc;
zend_uchartype;        /* active type */
zend_ucharis_ref__gc;

PHP7

typedef	union	_zend_value {
	zend_long	lval;                         /* long value */
	double	dval;                         /* double value */
	zend_refcounted	*counted;
	zend_string	*str;
	zend_array	*arr;
	zend_object	*obj;
	zend_resource	*res;
	zend_reference	*ref;
	zend_ast_ref	*ast;
	zval	*zv;
	void	*ptr;
	zend_class_entry	*ce;
	zend_function*func;
	struct {
		uint32_tw1;
		uint32_tw2;       
	 } ww;
} zend_value;

struct_zval_struct {
	zend_value	value;                        /* value */
	union {
		struct {
			ZEND_ENDIAN_LOHI_4(
				zend_uchar	type,                     /* active type */
				zend_uchar	type_flags,
				zend_uchar	const_flags,
				zend_uchar	reserved)     /* call info for EX(This) */                
		} v;
  		uint32_ttype_info;        
   } u1;
   union {
	  	uint32_t	var_flags;
	  	uint32_t	next;                 /* hash collision chain */
	  	uint32_t	cache_slot;           /* literal cache slot */
	  	uint32_t	lineno;               /* line number (for ast nodes) */
	  	uint32_t	num_args;             /* arguments number for EX(This) */
	  	uint32_t	fe_pos;               /* foreach position */
	  	uint32_t	fe_iter_idx;          /* foreach iterator index */        
   } u2;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我峰兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值