iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP多进程开发面试的常见问题怎么解决
  • 428
分享到

PHP多进程开发面试的常见问题怎么解决

2023-07-04 20:07:38 428人浏览 独家记忆
摘要

本篇内容介绍了“PHP多进程开发面试的常见问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP多进程开发先介绍一些简单命令ech

本篇内容介绍了“PHP多进程开发面试的常见问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

PHP多进程开发

先介绍一些简单命令

echo $$ //输出当前bash进程strace -s 65500 -p 进程号    //打印进程系统调用kill -s 10 pid //发送信号kill -s SIGUSR2 pid //发送信号pstree -ap //查看进程树ps -ajx //查看进程信息ps 命令字段解析:PPID:父进程IDPID:进程IDPGID:进程组IDSID:会话IDTTY:所在终端STAT:进程状态 R运行 Z僵尸 S睡眠 T停止 D睡眠无法被唤醒UID:unix用户IDCOMMAND:启动命令

什么是程序?

一般指可执行文件,在 linux 系统中它按 ELF 格式进行存储,没有后缀可言,file 命令可以查看 elf 文件的具体类型

ELF 全程 Executable Linkable FORMat 可执行可链接格式

ELF 分为四大种类

  • EXEC 可执行文件

  • REL 可重定位文件,也称为静态库文件,链接器链接之后成为动态库文件,比如 event.so Sockets.so curl.so

  • Shared Object File 共享目标文件

  • core dump 存储进程产生的异常信息

可通过 objdump/readelf 命令查看 ELF 文件相关信息

什么是终端?

  • tty 物理终端

tty 是最令人熟悉的了,在 Linux 中,/dev/ttyX 代表的都是上述的物理终端,其中,/dev/tty1~/dev/tty63 代表的是本地终端,也就是接到本机的键盘显示器可以操作的终端

/dev/console 当前焦点终端

  • pts 伪终端

通过 tcp/ip 协议实现的终端,比如用 ssh 进行的登录,或者 telnet, 那么你将得到一个叫做 /dev/pts/X 的伪终端同时在

/proc/bash pid/fd 生成三个标识符指向当前的 /dev/pts/X

0 标准输入 鼠标,键盘

1 标准输出 显示器

2 标准错误 显示器

PHP多进程开发面试的常见问题怎么解决

什么是进程?

进程退出

  • 运行到最后一行语句

  • 运行时遇到 return 时

  • 运行时遇到 exit () 函数的时候

  • 程序异常的时候

  • 进程接收到中断信号

进程结束时并不会真的退出,还会驻留在内在中,pcntl_wait (pcntl_waitpid) 函数来获取进程的终止状态码同时该函数会释放终止进程的内存空间,如果不这么做,会产生很多僵尸进程占用大量的内存空间

孤儿进程

父进程运行完,子进程在运行,则子进程会被头号进程 init 接管,这类型的进程成为孤儿进程

僵尸进程

子进程运行完,父进程没有调用 pcntl_wait () 回收,进程状态变成 Z+

守护进程

父进程是 init 进程,一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户(root)权限运行,因为它们要使用特殊的端口(1-1024)或访问某些特殊的资源。

什么是进程组?

多个进程组成一个进程组,每个进程组只有一个组长,组长的 PID 就是进程组的 ID;组内所有进程退出时,进程组才会消失,可以通过 ps -ajx 命令查看 pgid

PHP多进程开发面试的常见问题怎么解决

什么是会话?

多个进程组组成一个会话,每个会话都有一个会话首进程。会话的特点

1) 使用 setsid () 函数可以创建一个新的会话

2) 会话首进程无法调用 setsid,会报错

3) 非会话首进程进程可调用 setsid 创建出一个新的会话,这个行为会导致该进程会创建一个新的进程组且自身为该进程组组长,该进程会创建出一个新的会话组且自身为该会话组组长,该进程会脱离当前命令行控制终端

现实上的比喻就是除了老板之后,员工都可以调用 我上我也行 () 这个函数变成老板且不受原公司的控制

什么是信号?

信号是进程间通信的其中一种方式,平时用到的 kill -9 pid, 指的不是用第九种方式杀死进程,而是发送信号值为 9 的信号给进程,而刚好信号 9 是 SIGKILL, 功能是停止进程,查看操作系统支持的信号命令: kill -l

PHP多进程开发面试的常见问题怎么解决

一般使用 1-31, 注意看没有 32,33 这两个信号

信号的产生来源可能是:

  • 键盘上按了 Ctrl+C 会产生 SIGINT 信号,关闭终端会产生 SIGHUP 信号

  • 硬件也能产生信号

  • 使用 kill 命令

  • 软件产生,比如在管道里当一侧准备写管道时可能会产生 SIGPIPE 信号

当一个进程收到一个信号时,三个可选操作

  • 操作系统默认的方式,比如 SIGKILL 就是杀死进程

  • 忽略掉这个信号,pcntl_signal (SIGKILL, SIG_IGN, false); 进程收到 SIGKILL 命令时将不为所动

  • 有自己的想法,pcntl_signal (SIGKILL, function ($signal){// 自己的想法}, false); 这样将会触发自定义回调

pcntl_signal () 信号处理器是会被子进程继承的,所以 fork () 之前最后先行处理信号处理器

posix 命令

//需要安装posix扩展posix_getpid();    //获取进程IDposix_getppid();//获取父进程IDposix_getpgid(posix_getppid());//获取进程组IDposix_getpgrp());//同上posix_getsid(posix_getpid()));//获取会话IDposix_getuid();//获取当前登录用户UIDposix_getgid();//获取当前登录用户组UIDposix_geteuid();//获取当前有效用户UIDposix_getguid();//获取当前有效用户组UIDposix_kill();//发送信号

pcntl 命令

//创建一个计时器,在指定的秒数后向进程发送一个SIGALRM信号。每次对 pcntl_alarm()的调用都会取消之前设置的alarm信号。如果seconds设置为0,将不会创建alarm信号。 pcntl_alarm(int $seconds);//在当前进程当前位置产生子进程,子进程会复制父进程的代码段和数据段(Copy on write 写时复制,当子进程要修改内存空间时,操作系统会分配新的内存给子进程),ELF文件的结构,如果父进程先退出,子进程变成孤儿进程,被pid=1进程接管pcntl_fork();//安装一个信号处理器pcntl_signal(int $signo, callback $handler);//调用等待信号的处理器,触发全部未执行的信号回调pcntl_signal_dispatch()//设置或检索阻塞信号pcntl_sigprocmask(int $how, array $set[, array &$oldset])//等待或返回fork的子进程状态,wait函数挂起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数。用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将被释放。pcntl_wait($status)//加个WNOHANG参数,不挂起父进程,如果没有子进程退出返回0,如果有子进程退出返回子进程pid,如果返回-1表示父进程已经没有子进程pcntl_wait($status, WNOHANG)//基本同pcntl_wait,waitpid可以指定子进程idpcntl_waitpid ($pid ,$status)pcntl_waitpid ($pid ,$status, WNOHANG)//检查状态代码是否代表一个正常的退出。参数 status 是提供给成功调用 pcntl_waitpid() 时的状态参数。pcntl_wifexited($status)//返回一个中断的子进程的返回代码  当php exit(10)时,这个函数返回10,这个函数仅在函数pcntl_wifexited()返回 TRUE.时有效pcntl_wexitstatus($status)//检查子进程状态码是否代表由于某个信号而中断。参数 status 是提供给成功调用 pcntl_waitpid() 时的状态参数。pcntl_wifsignaled($status)//返回导致子进程中断的信号pcntl_wtermsig($status)//检查子进程当前是否已经停止,此函数只有作用于pcntl_wait使用了WUNTRACED作为 option的时候pcntl_wifstopped($status)//返回导致子进程停止的信号pcntl_wstopsig($status)//检索由最后一个失败的pcntl函数设置的错误数pcntl_errno() pcntl_get_last_error()//检索与给定errno关联的系统错误消息pcntl_strerror(pcntl_errno())

pcntl_fork () 执行之前先与 Redis 建立一个连接,然后再开 3 个子进程之后多少个 Redis 连接?

<?php$o_Redis = new Redis();$o_redis->connect( '127.0.0.1', 6379 );// 使用for循环搞出3个子进程来for ( $i = 1; $i <= 3; $i++ ) {  $i_pid = pcntl_fork();  if ( 0 == $i_pid ) {    // 使用while保证三个子进程不会退出...    while( true ) {      sleep( 1 );    }  }}// 使用while保证主进程不会退出...while( true ) {   sleep( 1 );}netstat -ant |grep 6379

PHP多进程开发面试的常见问题怎么解决

说明父进程和三个子进程一共四个进程,实际上共享了一个 Redis 长连接

上面这种写法会有什么问题?

因为 Redis 是一个单进程单线程服务器,所以接收到的命令都是顺序执行顺序返回的,所以当客户端多个进程共享一个 redis 连接时,当有四个进程向 Redis 服务端发起请求,返回四个结果,谁先抢到就是谁的,正确的做法是每个子进程创建一个 Redis 连接,或者用连接池

孤儿进程怎么产生?

$i_pid = pcntl_fork();if (0 == $i_pid) {    // 子进程10秒钟后退出.    for ($i = 1; $i <= 10; $i++) {        sleep(1);        echo "我的父进程是:" . posix_getppid() . PHP_EOL;    }} else if ($i_pid > 0) {    // 父进程休眠2s后退出.    sleep(2);}

僵尸进程怎么产生?

$i_pid = pcntl_fork();if (0 == $i_pid) {    // 子进程10s后退出,变成僵尸进程    sleep(10);} else if ($i_pid > 0) {    // 父进程休眠1000s后退出.    sleep(1000);}

子进程怎么回收?

$i_pid = pcntl_fork();if (0 == $i_pid) {    // 在子进程中    for ($i = 1; $i <= 10; $i++) {        sleep(1);        echo "子进程PID " . posix_getpid() . "倒计时 : " . $i . PHP_EOL;    }} else if ($i_pid > 0) {    $i_ret = pcntl_wait($status);    echo $i_ret . ' : ' . $status . PHP_EOL;    // while保持父进程不退出    while (true) {        sleep(1);    }}

子进程怎么回收?非阻塞版本

<?php// fork出十个子进程for ($i = 1; $i <= 10; $i++) {    $i_pid = pcntl_fork();    // 每个子进程随机运行1-5秒钟    if (0 == $i_pid) {        $i_rand_time = mt_rand(1, 5);        sleep($i_rand_time);        exit;    } // 父进程收集所有子进程PID    else if ($i_pid > 0) {    }}while (true) {    // sleep使父进程不会因while导致CPU爆炸.    sleep(1);    //设置WNOHANG参数不会阻塞,就是需要外层包个循环    $pid = pcntl_wait($status, WNOHANG);    if ($pid == 0) {   //目前还没有结束的子进程        continue;    }    if ($pid == -1) { //已经结束啦 很蓝的啦        exit("所有进程均已终止" . PHP_EOL);    }    // 如果子进程是正常结束    if (pcntl_wifexited($status)) {        // 获取子进程结束时候的 返回错误码        $i_code = pcntl_wexitstatus($status);        echo $pid . "正常结束,最终返回:" . $i_code . PHP_EOL;    }    // 如果子进程是被信号终止    if (pcntl_wifsignaled($status)) {        // 获取是哪个信号终止的该进程        $i_signal = pcntl_wtermsig($status);        echo $pid . "由信号结束,信号为:" . $i_signal . PHP_EOL;    }    // 如果子进程是[临时挂起]    if (pcntl_wifstopped($status)) {        // 获取是哪个信号让他挂起        $i_signal = pcntl_wstopsig($status);        echo $pid . "被挂起,挂起信号为:" . $i_signal . PHP_EOL;    }}

如何创建守护进程?

$pid = pcntl_fork();if ($pid > 0) { //1)在父进程中执行fork并exit推出    exit();} elseif ($pid == 0) {    if (posix_setsid() < 0) {   //2)在子进程中调用setsid函数创建新的会话        exit();    }    chdir('/'); //3)在子进程中调用chdir函数,让根目录 ” / ” 成为子进程的工作目录    umask(0);   //4)在子进程中调用umask函数,设置进程的umask为0    echo "create success, pid = " . posix_getpid();    //5)在子进程中关闭任何不需要的文件描述符    fclose(STDIN);    fclose(STDOUT);    fclose(STDERR);}//可以把上面封装成函数daemon();while (true) {} //具体业务如何修改进程名?for ($i = 1; $i <= 4; $i++) {    $i_pid = pcntl_fork();    if (0 == $i_pid) { //子进程        cli_set_process_title("Worker Process"); //修改子进程的名字        while (true) {            sleep(1);        }    }}cli_set_process_title("Master Process");    //修改父进程的名字while (true) {    sleep(1);}

PHP多进程开发面试的常见问题怎么解决

进程怎么接收信号?

// 信号处理回调function signal_handler($signal){    switch ($signal) {        case SIGTERM:            echo "sigterm信号." . PHP_EOL;            break;        case SIGUSR2:            echo "sigusr2信号." . PHP_EOL;            break;        case SIGUSR1:            echo "sigusr1信号." . PHP_EOL;            break;        default:            echo "其他信号." . PHP_EOL;    }}// 给进程安装3个信号处理回调pcntl_signal(SIGTERM, "signal_handler");pcntl_signal(SIGUSR1, "signal_handler");pcntl_signal(SIGUSR2, "signal_handler");while (true) {    posix_kill(posix_getpid(), SIGUSR1);//发送一个信号给当前进程    posix_kill(posix_getpid(), SIGUSR1);    pcntl_signal_dispatch(); //调一次分发一次信号,调用之前,信号累积在队列里    posix_kill(posix_getpid(), SIGUSR2);    posix_kill(posix_getpid(), SIGUSR2);    sleep(1);   //稍微休息一下}

PHP多进程开发面试的常见问题怎么解决

其中第 1,2 行与第 3,4,5,6 行中间隔了一秒,体会一下 pcntl_signal_dispatch 这个函数

进程怎么接收信号 (不阻塞版本)?

//php7.1及以上才能用这个函数pcntl_async_signals(true);// 信号处理回调function signal_handler($signal){    switch ($signal) {        case SIGTERM:            echo "sigterm信号." . PHP_EOL;            break;        case SIGUSR2:            echo "sigusr2信号." . PHP_EOL;            break;        case SIGUSR1:            echo "sigusr1信号." . PHP_EOL;            break;        default:            echo "其他信号." . PHP_EOL;    }}// 给进程安装信号...pcntl_signal(SIGTERM, "signal_handler");pcntl_signal(SIGUSR1, "signal_handler");pcntl_signal(SIGUSR2, "signal_handler");while (true) {    posix_kill(posix_getpid(), SIGUSR1);//发送一个信号给当前进程    posix_kill(posix_getpid(), SIGUSR2);    sleep(1);   //稍微休息一下}

进程怎么阻塞信号

pcntl_async_signals(true);// 信号处理回调function signal_handler($signal){    switch ($signal) {        case SIGTERM:            echo "sigterm信号." . PHP_EOL;            break;        case SIGUSR2:            echo "sigusr2信号." . PHP_EOL;            break;        case SIGUSR1:            echo "sigusr1信号." . PHP_EOL;            break;        default:            echo "其他信号." . PHP_EOL;    }}// 给进程安装信号...pcntl_signal(SIGTERM, "signal_handler");pcntl_signal(SIGUSR1, "signal_handler");pcntl_signal(SIGUSR2, "signal_handler");//把SIGUSR1阻塞,收到这个信号先不处理pcntl_sigprocmask(SIG_BLOCK, [SIGUSR1], $a_oldset);$counter = 0;while (true) {    posix_kill(posix_getpid(), SIGUSR1);//发送一个信号给当前进程    posix_kill(posix_getpid(), SIGUSR2);    sleep(1);   //稍微休息一下    if ($counter++ == 5) {        //解除SIGUSR1信号阻塞,并立刻执行SIGUSR1处理回调函数        pcntl_sigprocmask(SIG_UNBLOCK, [SIGUSR1], $a_oldset);    }}

“PHP多进程开发面试的常见问题怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: PHP多进程开发面试的常见问题怎么解决

本文链接: https://www.lsjlt.com/news/347331.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP多进程开发面试的常见问题怎么解决
    本篇内容介绍了“PHP多进程开发面试的常见问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP多进程开发先介绍一些简单命令ech...
    99+
    2023-07-04
  • php开发框架常见报错问题怎么解决
    这篇文章主要介绍了php开发框架常见报错问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php开发框架常见报错问题怎么解决文章都会有所收获,下面我们一起来看看吧。语法错误PHP语言是一种弱类型语言,虽...
    99+
    2023-07-05
  • Java开发技术面试常见问题:numpy是什么?
    在Java开发领域中,numpy是一个非常重要的工具。它是Python科学计算的核心库之一,提供了大量的高效、快速的数学函数和工具,用于解决科学计算、数据分析、数据挖掘、机器学习等领域的问题。本篇文章将介绍numpy的基本概念、用法及一些...
    99+
    2023-10-08
    开发技术 面试 numpy
  • PHP Redis扩展常见问题解答:解决开发难题
    1. 如何连接Redis服务器? $redis = new Redis(); $redis->connect("127.0.0.1", 6379); 2. 如何设置键值对? $redis->set("key", "value...
    99+
    2024-02-07
    PHP Redis 扩展 常见问题解答
  • PHP开发缓存的常见问题及解决方案
    PHP开发缓存的常见问题及解决方案在PHP开发过程中,为了提高网站性能和用户体验,使用缓存是常见的优化手段。然而,使用缓存也会遇到各种问题,本文将介绍PHP开发中常见的缓存问题,并提供相应的解决方案和具体代码示例。一、缓存命中率低问题描述:...
    99+
    2023-11-07
    解决方案 PHP缓存 常见问题
  • Go 开发者必备:面试中常见的缓存问题及解决方案
    在 Go 开发中,缓存是一个非常常见的话题。在面试中,面试官经常会问及缓存相关的问题。这篇文章将介绍 Go 开发中常见的缓存问题及解决方案。 一、缓存的概念 缓存是一种数据存储方式,它通过将常用的数据存储在内存中,以提高数据的访问速度。缓...
    99+
    2023-06-13
    面试 缓存 linux
  • Python中多进程编程的常见问题及解决策略
    Python中多进程编程的常见问题及解决策略引言:随着计算机硬件的不断发展,多核处理器已经变得越来越常见。为了充分利用硬件资源,提高程序的执行效率,多进程编程成为了一个重要的技术。但是在使用多进程编程时,我们也常常会遇到一些问题,比如进程间...
    99+
    2023-10-22
    多进程编程 常见问题 解决策略
  • Python中多进程编程的常见问题及解决方案
    Python中多进程编程的常见问题及解决方案摘要:随着计算机硬件的发展,多核处理器已成为计算机的常态。因此,充分利用多核处理器的能力是提高程序性能的关键。在Python中,多进程编程是一种利用多核处理器的有效方法。然而,多进程编程也会面临一...
    99+
    2023-10-22
    结束和通信等问题。
  • PHP 函数开发中的常见问题和解决方案
    php函数开发中的常见问题包括:不遵循命名约定、参数验证缺失、过度使用全局变量、缺乏文档注释、不处理异常。解决方案包括:遵循命名约定、验证参数、谨慎使用全局变量、添加文档注释、使用try...
    99+
    2024-04-12
    php 函数开发 作用域
  • redis多进程并发问题怎么解决
    在处理Redis多进程并发问题时,可以考虑以下几种解决方案: 使用分布式锁:可以使用Redis的SETNX命令来实现分布式锁,确...
    99+
    2024-04-09
    redis
  • ASP 类常见问题:解决开发中的棘手问题
    1. 性能低下 问题:页面加载缓慢或响应不及时。 解决方法: 优化数据库查询,使用索引和适当的连接。 使用缓存机制,如 ASP.NET Output Caching。 优化代码,避免不必要的循环和重新计算。 使用性能分析工具,如 dot...
    99+
    2024-04-02
  • 你了解 PHP 面试中常见的索引问题吗?
    PHP 是一种广泛使用的服务器端编程语言,因其易于学习和使用而受到广泛欢迎。在 PHP 面试中,常常会问到与索引相关的问题。在本文中,我们将介绍一些 PHP 面试中常见的索引问题,并提供相应的代码演示。 一、什么是索引? 在数据库中,索引是...
    99+
    2023-08-19
    面试 索引 开发技术
  • 解决PHP打开500错误的常见问题
    解决PHP打开500错误的常见问题,需要具体代码示例 在开发PHP应用程序的过程中,经常会遇到500内部服务器错误,这种错误常常令人头疼。500错误是指服务器在处理请求时发生了无法识别...
    99+
    2024-03-08
    php错误排查 错误日志分析 代码调试技巧 php脚本
  • JAVA有哪些常见的多线程面试题
    本文小编为大家详细介绍“JAVA有哪些常见的多线程面试题”,内容详细,步骤清晰,细节处理妥当,希望这篇“JAVA有哪些常见的多线程面试题”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是线程线程是操作系统能够进...
    99+
    2023-06-04
  • php使用composer常见问题怎么解决
    这篇文章主要介绍php使用composer常见问题怎么解决,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php有什么特点1、执行速度快。2、具有很好的开放性和可扩展性。3、PHP支持多种主流与非主流的数据库。4、面向...
    99+
    2023-06-14
  • C++ 函数异常常见问题解答:解决开发中的难题
    要解决 c++++ 函数异常问题,可遵循以下步骤:使用 try-catch 块或 noexcept 指定符处理异常。当函数确实不会引发任何异常时,才使用 noexcept。使用 thro...
    99+
    2024-05-02
    c++ 异常
  • 基于多线程并发的常见问题(详解)
    一 概述1.volatile保证共享数据一旦被修改就会立即同步到共享内存(堆或者方法区)中。2.线程访问堆中数据的过程线程在栈中建立一个数据的副本,修改完毕后将数据同步到堆中。3.指令重排为了提高执行效率,CPU会将没有依赖关系的指令重新排...
    99+
    2023-05-31
    多线程 并发 线程并发
  • 微信小程序开发常见问题有哪些及怎么解决
    这篇“微信小程序开发常见问题有哪些及怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“微信小程序开发常见问题有哪些及怎么...
    99+
    2023-06-26
  • PHP ZipArchive 扩展的常见问题解答:解决常见疑问
    PHP ZipArchive 扩展为处理 ZIP 压缩文件提供了强大且易于使用的功能。然而,在使用该扩展时可能会遇到一些常见问题。本文旨在解决这些常见问题并提供相应的解决方案。 问题 1:创建 ZIP 文件时无法向其中添加文件 解决方案...
    99+
    2024-03-08
    ZipArchive PHP 压缩 解压 常见问题
  • 常见的前端开发CSS面试题有哪些
    这篇文章主要讲解了“常见的前端开发CSS面试题有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“常见的前端开发CSS面试题有哪些”吧!1 你用 CSS 多...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作