이 기사는 기본 지식을 정리하는 데 도움이 되는 28개의 PHP 인터뷰 질문(공유할 답변 포함)을 정리하고 공유합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
관련 추천 : 2023년 PHP 면접 질문 모음(모음)
새해 이후 새로운 취업 기회를 찾아볼 계획인데, 기본적인 면접에 대한 이해와 공부가 많았다. 이전에는 충분히 깊지 않았습니다. 앞으로 나아갈 수 있도록 격려하기 위해 최근 포럼과 검색 엔진에서 관련 지식을 배우고 요약하기 시작했습니다. 질문 중 일부는 포럼에서 선배들이 공유하는 질문이나 답변이며 일부는 질문입니다. 최근 인터뷰에서 접한 내용을 바탕으로 제가 이해한 부분과 선배님들의 공유를 모아서 다른 친구들에게도 도움이 되었으면 하는 마음으로 공유합니다. 오해는 앞으로 계속 업데이트하겠습니다
1 기본 구현은 해시 테이블(해시 테이블) + 이중 연결 리스트(해시 충돌 해결)를 통해 이루어집니다.
연결 목록: 큐, 스택, 이중 연결 목록,
1, 코드 구현
$arr = [2, 4, 1, 5, 3, 6]; for ($i = 0; $i < (count($arr)); $i++) { for ($j = $i + 1; $j < (count($arr)); $j++) { if ($arr[$i] <= $arr[$j]) { $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; } } } result : [6,5,4,3,2,1]
1차: 배열의 첫 번째 요소를 다른 모든 요소와 비교 . 어느 요소가 더 큰지 순서를 변경한 다음 첫 번째 요소를 버블링합니다. 하나의 (가장 큰) 요소
O(n^2)
; 최적의 시간 복잡도: O(n)
, 첫 번째 루프에서 교환이 없으면 점프해야 합니다. 루프에서 직접 빠져나옴
O( 1)
, 요소 교환 시 임시 변수가 차지하는 공간 최적의 공간 복잡도: O(1)
, 정렬 , 위치 교환 필요 없음O(n^2)
;
最优时间复杂度:O(n)
,需要加判断,第一次循环如果一次都没有交换就直接跳出循环
空间复杂度:O(1)
,交换元素的时候的临时变量占用的空间
最优空间复杂度:O(1)
3. 시간 복잡도 및 공간 복잡도
시간 복잡도: 전체 프로세스는 점근적 시간 복잡도로 프로세서의 효율성을 추정합니다(알고리즘의 효율성 추세를 설명하는 것은 특정 항목을 참조하지 않음). 알고리즘이 사용하는 시간, 서로 다른 기계의 성능이 일관되지 않기 때문에 일반적인 효율성 계산 방법) 표현 방법: Big O 표기법 복잡도 수준:선형 순서 O(n)
제곱 순서 O(n²)
3차 순서 O(n³)
K번째 순서 O(n^k)
지수 순서( 2^ n)
대수 순서 O(logN)
선형 로그 순서 O(nlogN)
시간 복제 유형:
최고의 시간 복잡도
최악의 시간 복잡도
평균 시간 복잡도
분할 시간 복잡도
공간 복잡도: 전체 점근적 공간 복잡도, 컴퓨터 메모리 사용량 추정(알고리즘이 차지하는 저장 공간의 추세를 기술함, 실제 점유 공간이 아님, 위와 같음)
참고자료:
애플리케이션 계층, 프리젠테이션 계층, 세션 계층, 전송 레이어, 네트워크 레이어, (데이터) 링크 레이어, 물리 레이어
메모리 루틴:
첫 번째 단어: 테이블 간 전송(사물 체인 네트워크)
첫 번째 단어: 애플리케이션 레이어(발생 횟수(더 많음, 쉽게 발생) 기억하세요)
처음 4개의 정방향: 표현되어야 함 - 전송될 것입니다
마지막 3개의 역방향: 사물 인터넷의 동음이의어는 사물 인터넷보다 기억하기 더 쉽습니다
1. 모두 전송 계층 프로토콜입니다
2. TCP
는 연결 지향적이므로 일대일
만 가능합니다. 전송
데이터는 안정적이며 손실되지 않습니다
전이중 통신
3. UDP(TCP 특성에 따라 역방향)
연결 없음, 일대일 지원 , 일대다, 다대다
열 보존 전송을 지향합니다
헤더 오버헤드가 작고 데이터가 반드시 신뢰할 수 있는 것은 아니지만 속도는 빠릅니다
1. 3방향 핸드셰이크:
1) 처음: 클라이언트가 SYN = 1, seq = client_isn
을 보냅니다. 기능:
클라이언트: 없음
서버: 자신의 수신 기능과 클라이언트의 송신 기능을 확인
2) 두 번째: 서버가 SYN = 1을 보냅니다. SEQ = Server_ISN, ACK = Client_isn +1
:
3) 세 번째: 클라이언트가 보냅니다. SYN = 0, ACK = server_isn+1,seq =client_isn+1
2. 4번 웨이브
1) 첫 번째: 클라이언트가 FIN
2) 두 번째: 서버가 ACK
3) 세 번째 : 서버가 FIN을 보냅니다
4) 네 번째 : 클라이언트가 ACK를 보냄
1. 상태 코드 분류
2, 공통 상태 코드
401 무단: 클라이언트에 권한이 없습니다
403 금지됨: 서버가 클라이언트 요청을 거부합니다
404 찾을 수 없음: 클라이언트가 요청한 리소스가 존재하지 않습니다
500 내부 서버 오류: 서버 내부 오류
502 불량 게이트웨이: 게이트웨이 또는 프록시로 작동하는 서버가 요청 수행을 시도할 때 업스트림 서버에서 잘못된 응답을 수신합니다.
503 서비스를 사용할 수 없는 과부하 또는 시스템 유지 보수
504 게이트웨이 시간 초과: 게이트웨이 시간 초과
3, 502
원인: nginx가 예외를 처리하기 위해 게이트웨이(php-fpm)에 요청을 제출하여
1) fastcgi 버퍼 설정은 다음과 같습니다. 너무 작음
fastcgi_buffers 8 16k; code><code>fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
2)php-cgi的进程数设置过少
查看FastCgi进程数:netstat -anpo | grep "php-cgi"| wc -l
调整参数最大子进程数:max_children
一般按照单个进程20M计算需要需要设置的子进程数
3)max_requests(内存溢出或频繁重启)
参数指明每个children最多能处理的请求数量,到达最大值之后会重启children。
设置过小可能导致频繁重启children:
php将请求轮询给每个children,在大流量的场景下,每一个children 到达最大值的时间差不多,如果设置过小可能多个children 在同一时间关闭,nginx无法将请求转发给php-fpm,cpu降低,负载变高。
设置过大可能导致内存泄露
4)php执行时间超过nginx等待时间
fastcgi_connect_timeout
fastcgi_send_timeout
fastcgi_read_timeout
5)fastcgi执行时间
max_execution_time
하위 프로세스의 최대 수를 조정합니다.
일반적으로 하위 프로세스의 수는 설정해야 하는 값은 단일 프로세스당 20M을 기준으로 계산됩니다. 매개변수는 각 하위 항목이 처리할 수 있는 최대 요청 수를 나타냅니다. 최대값에 도달한 후 하위 항목이 다시 시작됩니다. . PHP는 각 하위 항목에 대한 요청을 폴링합니다. 트래픽이 많은 시나리오에서는 설정이 너무 작으면 각 하위 항목이 거의 동시에 최대값에 도달합니다. , 여러 하위 항목이 동시에 있을 수 있습니다. 시간이 꺼져 있고 nginx가 요청을 php-fpm으로 전달할 수 없으며 CPU가 감소하고 로드가 높아집니다.致 너무 많이 설정하면 메모리 누수가 발생할 수 있습니다.max_children
FastCGI_CONNECT_TIMEOUT
FastCGI_TIMEOUT
Eout
5) fastcgi 실행 시간
>
7. http와 HTTPS의 차이점
1. 포트: http 80; https: 443
2. http는 stateless이며, https는 암호화된 전송이 가능한 http + SSL로 구축된 프로토콜입니다.
3. http 일반 텍스트 전송, https 암호화 전송
4. http는 3개의 패키지로 더 빠른 3방향 핸드셰이크, https에는 12개의 패키지가 필요합니다(3개의 tcp 패키지 + 9개의 SSL 핸드셰이크 패키지)
8. redis 분산 잠금 및 문제잠금: setnx
잠금 시간 초과: 만료
2 가능한 문제1) nx 설정 및 만료는 비원자적입니다. 문제(잠금 후 설정을 사용할 수 있게 되면 중단됨)
Redis 2.6.12 이상에서는 SET 명령에 대한 선택적 매개 변수를 추가합니다. 이는 setnx 명령을 대체할 수 있습니다.
2) 다른 프로세스 잠금은 다음과 같습니다. 시간 초과 후 실수로 삭제되었습니다. (프로세스 A의 실행 시간이 초과되어 잠금이 해제됩니다. 이때 프로세스 B는 잠금을 획득하고 요청 처리를 시작합니다. 이때 프로세스 A는 처리를 완료하고 프로세스 B의 잠금은 삭제됩니다. 실수로)
해결 방법: 자신의 프로세스 잠금만 삭제할 수 있습니다(lua 스크립트 만료된 잠금을 획득한 후 프로세스 B가 실수로 프로세스 A의 잠금을 삭제하는 것을 방지)
3) 동시성 시나리오, 실행 시간 초과 프로세스 A는 잠금을 해제하고 프로세스 B는 이때 잠금을 획득합니다.참고 :
해결 방법: 데몬 프로세스를 시작하고 현재 프로세스가 만료되도록 잠금을 지연합니다.
은 Redis
추천 자료: https://www.php.cn/redis/475918.html
10 redis
🎜🎜1의 데이터 유형 및 적용 시나리오: 🎜🎜🎜 일반 키/값. 저장공간🎜🎜🎜2, 해시:🎜🎜해시맵: 객체 정보를 저장하는 키-값 팀 모음
3. 목록:
이중 연결 목록: 메시지 대기열
4. 세트:
값이 항상 null인 해시맵: 순서가 지정되지 않음 집합 및 반복 없음: 교집합, 합집합, 차이 집합, 중복 제거 값 계산
5, zset:
중복 없이 정렬된 집합: hashMap(중복 제거) + Skiplist 점프 테이블(순서 보장): 순위 목록
참고 :
1. RDB Persistence(스냅샷): 지정된 시간 간격 내에서 작성 디스크에 설정된 메모리 데이터의 스냅샷
1) 하위 프로세스를 포크하고 스냅샷 콘텐츠를 임시 RDB 파일(dump.rdb)에 씁니다. 하위 프로세스가 스냅샷 콘텐츠를 쓰면 새 파일이 이전 파일을 대체합니다. 파일
2 ) 전체 Redis 데이터베이스에는 하나의 백업 파일만 포함됩니다
3) 성능을 극대화하려면 지속성 작업을 완료하는 데 포크 하위 프로세스만 필요하므로 디스크 IO가 줄어듭니다
4) 지속성이 유지되기 전 가동 중지 시간으로 인해 데이터 손실이 발생할 수 있습니다.
2. AOF 지속성: 서버의 모든 쓰기 및 삭제 작업을 로그 형식으로 기록합니다
1) 쓰기 명령을 받을 때마다 쓰기 기능을 사용하여 파일에 추가합니다.appendonly.aof
2 ) 영구 파일은 점점 더 커지고 중복 로그가 많이 있습니다(0은 100으로 100배 증가, 100개의 로그 레코드가 생성됩니다)
3) 다양한 fsync 전략을 설정할 수 있습니다
appendfsync Everysec: 1초에 한 번 최대 1초의 데이터가 손실됩니다(기본값)
appendfsync Always : 변경 시마다 한 번 실행
appendfsync no : 처리되지 않음
4) AOF 파일이 다음과 같은 경우 다시 작성됩니다. 너무 큽니다: AOF 파일 크기를 압축합니다.
fork 프로세스, redis 로컬 데이터 개체의 최신 상태를 AOF 임시 파일에 씁니다(RDB 스냅샷과 유사).
기본 프로세스에서 받은 변경 사항이 먼저 (다시 쓰기가 실패한 후에도) 데이터 무결성을 보장할 수 있습니다.)
하위 프로세스가 다시 쓰기를 완료한 후 메모리의 새로운 변경 사항을 메모리에 동기적으로 추가합니다. 임시 AOF 파일
상위 프로세스는 임시 AOF 파일을 새 AOF 파일로 바꾸고 이름을 바꿉니다. 나중에 받은 새 명령은 새 파일에 기록됩니다
참조:
1. 정적 캐시
2. nginx 로드 밸런싱
세 가지 방법: DNS 폴링, IP 부채 밸런싱, CDN
3 , 현재 제한 메커니즘
방법: IP 전류 제한, 인터페이스 토큰 전류 제한, 사용자 현재 제한, 헤더 동적 토큰(프런트 엔드 암호화, 백엔드 암호 해독)
4. 분산 잠금
방법:
setnx + 만료(비원자성, set은 redis2.6 이후 원자성을 보장함)
릴리스 잠금 시간 초과(데몬 자동 갱신 활성화)
만료된 잠금으로 인해 실수로 다른 스레드가 삭제됨(requestId 확인 또는 lua 스크립트 보장 검색 원자성 + 삭제)
5. 캐시 데이터
방법:
캐시 분석: 캐시 데이터 워밍업 + 블룸 필터/캐시 비우기
캐시 눈사태: 캐시 설정 만료를 방지하기 위한 무작위 만료 시간 동시에
6. 재고 및 주문
재고 공제
redis 자체 감소 재고로 인해 동시 시나리오에서 음수가 발생하고 재고 반환에 영향을 미칠 수 있습니다. 원자성을 보장하려면 lua 스크립트를 사용하세요.
redis가 재고를 보류한 후 비동기 메시지를 사용하여 주문을 생성하고 재고 변경 사항을 업데이트합니다.
데이터베이스는 낙관적 잠금을 사용하여 재고를 업데이트합니다. 여기서 stock_num - Sell_num > 0
메시지 전송 기록 테이블을 추가하고 비동기 메시지 손실을 방지하기 위한 재시도 메커니즘
주문 생성
프런트 엔드는 웹소켓 연결을 설정하거나 주문 상태를 폴링하고 모니터링합니다.
반복 소비를 방지하기 위해 소비 확인 기록 상태
창고 반품
주문 생성 후 지연 메시지를 보내 주문 결제 상태 및 재고 반품 여부를 확인합니다.
1. 특수문자 필터링
2. 데이터베이스 키 워드 필터링
3. 데이터 유형 및 형식 확인
4. 미리 컴파일된 모드 및 바인드 변수 사용
1. 표준 SQL 격리 수준 구현 원칙
커밋되지 않은 다른 트랜잭션을 직접 읽을 수 있습니다. data: Dirty reading
트랜잭션은 현재 읽은 데이터를 잠그지 않습니다.
트랜잭션이 종료되고 해제될 때까지 업데이트 순간에 행 수준 공유 잠금을 추가합니다.
Commit Read: 데이터 읽기 트랜잭션의 시작과 끝 사이에 일관성이 없을 수 있습니다. 트랜잭션의 다른 트랜잭션이 데이터를 수정했습니다. non-repeatability
트랜잭션에 현재 읽은 데이터에 대한 행 수준 공유 잠금이 있습니다(읽을 때). read 완전 릴리스
트랜잭션 종료 시까지 업데이트 시점에 행 수준의 배타적 잠금을 추가하여 릴리스합니다
반복 읽기: 트랜잭션 시작과 종료 전에 읽은 데이터가 일치하며, 및 트랜잭션의 다른 트랜잭션은 데이터를 수정할 수 없습니다. 반복 읽기
트랜잭션은 트랜잭션 시작부터 현재 읽은 데이터에 행 수준 공유 잠금을 추가합니다.
행 수준 배타적 잠금을 추가합니다. 업데이트 순간에 트랜잭션이 끝나면 해제됩니다
다른 트랜잭션은 트랜잭션을 진행합니다. 새로운 데이터로 인해 유령 읽기가 발생할 수 있습니다
직렬화
트랜잭션 시 테이블 수준 공유 잠금 추가 데이터 읽기
트랜잭션이 데이터를 업데이트할 때 테이블 수준 배타적 잠금 추가
2. innodb의 트랜잭션 격리 수준 및 구현 원리(!! 위와는 달리 하나는 격리 수준이고 다른 하나는 는 트랜잭션!! 격리 수준)
1) 기본 개념
mvcc : 다중 버전 동시성 제어: 실행 취소 로그 및 읽기 보기에 의존
데이터를 잠그지 않고 데이터를 읽을 수 있습니다. 데이터베이스의 동시 처리 기능 향상
쓰기 작업만 잠깁니다
한 데이터에 여러 버전이 있으며, 트랜잭션이 데이터를 업데이트할 때마다 새로운 데이터 버전이 생성됩니다. 이전 데이터가 유지됩니다. 실행 취소 로그
트랜잭션이 시작되면 제출된 모든 트랜잭션 결과만 볼 수 있습니다
현재 읽기: 최신 버전 읽기
스냅샷 읽기: 기록 버전 읽기
Gap 잠금: 간격 잠금은 범위 내의 인덱스를 잠급니다
업데이트 ID가 10에서 20 사이입니다.
전체 범위는 범위에 데이터가 존재하는지 여부에 관계없이 잠깁니다. 삽입 ID = 15는 방지됩니다
반복 읽기 격리 수준에만 갭 잠금이 있습니다
다음 키 잠금:
레코드 잠금 + 인덱스 레코드의 갭 잠금(인덱스 값과 이전 인덱스 값 사이의 갭 잠금)
open 및 close
팬텀 읽기 방지
2) 트랜잭션 격리 수준
커밋되지 않은 읽기
트랜잭션은 현재 읽은 데이터를 잠그지 않고 현재 읽은 데이터입니다
A 행 수준 공유 잠금은 업데이트 순간에 추가되고 트랜잭션이 끝나면 해제됩니다
Commit read
트랜잭션은 현재 읽은 데이터를 잠그지 않고 스냅샷 읽기입니다
트랜잭션이 해제될 때까지 업데이트 시점에 행 수준 배타적 잠금이 추가됩니다
Repeatable 읽기
트랜잭션은 현재 읽은 데이터를 잠그지 않습니다. 스냅샷 읽기입니다
특정 데이터가 업데이트되는 순간 행 수준의 배타적 잠금(Record Record Lock, GAP Gap Lock, Next-Key Lock)을 추가해야 하며, 트랜잭션 종료 시 해제됩니다
Gap 잠금은 팬텀 읽기 문제를 해결합니다
마스터-슬레이브 복제의 경우 간격 잠금이 없으면 마스터 라이브러리의 A 및 B 프로세스
A 프로세스 삭제 ID < ; 커밋 없음
B 프로세스 삽입 ID = 3, commit
A 프로세스가 커밋을 제출합니다
이 시나리오에서는 기본 라이브러리에 ID =3인 레코드가 있지만 binlog에는 Deleting first가 포함되어 있습니다. 그런 다음 이를 추가하면 슬레이브 데이터베이스에 데이터가 없어 마스터와 슬레이브 간의 데이터가 일치하지 않게 됩니다
MVCC의 스냅샷은 반복 불가능한 읽기 문제를 해결합니다
직렬화
트랜잭션 읽기 데이터를 가져올 때 테이블 수준 추가, 현재 읽을 때 테이블 수준 배타적 잠금 추가
참조:
인덱스는 데이터베이스가 데이터를 효율적으로 찾을 수 있도록 도와주는 저장 구조이며 디스크 IO
1.myisam은 테이블 잠금을 지원합니다. 인덱스와 데이터를 분리합니다. 서버 간 마이그레이션에 적합합니다.
2. 인덱스 유형
해시 인덱스
16. 테이블 파티셔닝 ( 샤딩 전략
2. 수평 분할
필드를 기준으로 여러 테이블로 수평 분할각 테이블의 구조는 동일합니다
하위 테이블의 동일한 관련 행이 완전한 데이터
중복 방법: 공통 필드가 중복됨
1.
서버 레이어: 커넥터->캐시->분석기(전처리기)->옵티마이저->Executor
엔진 레이어: 데이터 쿼리 및 저장
2, 실행 프로세스 선택
클라이언트가 요청을 보내고 연결을 설정합니다
서버 계층에서 캐시를 검색하여 적중되면 직접 반환하고 그렇지 않으면 계속합니다
SQL 문 및 전처리에 대한 7가지 분석 분석(필드 적법성 및 유형 등 확인)
옵티마이저는 실행 계획을 생성합니다
실행자는 엔진 API를 호출하여 결과를 쿼리합니다.
쿼리 결과를 반환합니다
3. 실행 프로세스 업데이트
기본 개념
버퍼 풀(캐시 풀)은 메모리에 있습니다. 다음에 동일한 페이지의 데이터를 읽을 때 버퍼 풀(innodb의 클러스터형 인덱스)에서 직접 반환할 수 있습니다.
데이터 업데이트 시 버퍼를 업데이트하세요. pool 먼저 풀고 디스크 업데이트
더티 페이지: 메모리의 버퍼 풀은 업데이트되지만 디스크는 업데이트되지 않습니다
더티 브러싱: inndb에는 버퍼의 데이터를 쓰는 특별한 프로세스가 있습니다. 때때로 더 많은 데이터가 디스크에 기록됩니다. 각 수정 사항은 한 번에
redo 로그 및 binlog
redo 로그(redo 로그), innodb의 고유합니다. 로그, 물리적 로그, 기록 수정
redo 로그는 반복적으로 작성되며, 공간이 고정되어 사용되어 이전 로그를 덮어쓰게 됩니다.
binlog는 서버 계층에서 공유하는 로그, 논리적 로그입니다.
binlog는 특정 크기에 추가되어 다음 로그로 전환되며 이전 로그를 덮어쓰지 않습니다.
redo 로그는 주로 충돌 복구, bin에 사용됩니다. 로그는 보관된 바이너리 로그를 기록하는 데 사용됩니다
redo 로그는 짧은 기간 동안만 데이터를 복구할 수 있으며, binlog는 설정을 통해 더 큰 데이터를 복구할 수 있습니다
WAL(write-ahead-logging) write-ahead- 로깅 방식이 먼저
로깅은 순차 IO
디스크에 직접 쓰는(플러싱)은 데이터가 무작위이고 다른 위치에 분산될 수 있으므로 랜덤 IO입니다. 섹터
순차 IO가 더 효율적입니다. 플러시 기회를 지연시키고 처리량을 향상시킬 수 있는 수정 로그를 먼저 삭제하세요.
redo 로그 플러시 메커니즘, 체크 포인트
redo 로그 크기 고정, 순환 쓰기
redo 로그는 원형과 같습니다. 앞쪽에 체크포인트(기존 로그는 덮어쓰기 됨), 뒤쪽에 쓰기포인트(현재 쓰여진 위치), 쓰기포인트와 체크포인트가 겹칠 경우 리두로그가 꽉 찼다는 것을 증명하며, Redo 로그를 디스크에 동기화 시작
업데이트 조건을 분석하고 필요한 데이터를 찾습니다. 업데이트됩니다(캐시 사용)
서버가 엔진 레이어의 API를 호출하고 Innodb가 데이터를 메모리에 업데이트한 다음 redo 로그를 작성한 다음 prepare
엔진 알림에 들어갑니다. 서버 레이어가 시작됩니다. 데이터 제출
서버 계층은 binlog 로그를 작성하고 innodb 인터페이스를 호출하여 커밋 요청을 발행합니다
엔진 계층은 요청을 받은 후 커밋을 제출합니다
리두 로그 상태가 커밋이면 직접 제출
리두 로그 상태가 준비이면 빈로그에 있는 트랜잭션이 커밋되었는지 판단하고, 그렇다면 커밋하고, 그렇지 않으면 롤백한다
먼저 Redo 로그를 작성한 후 binlog에 기록
3. Bin 로그 로그에 기록이 없습니다. 데이터를 복원해야 하는 경우 값 = 9
Redo Log를 작성하기 전에 먼저 binlog를 작성하세요
1. binlog 작성이 완료되었으나 redo log가 완료되지 않습니다
3. 언제 데이터를 복원해야 하는 경우 binlog가 완료되고 값이 10
undo 로그로 업데이트됩니다.
형식 (바이너리 파일):
1) 문
1 각 SQL 문의 원본 텍스트를 기록합니다.
2. 테이블 삭제는 SQL 문만 기록하면 되며, 각 행의 변경 사항을 기록할 필요가 없으므로 IO 절약, 성능 향상, 로그 양 감소
3. -슬레이브 불일치가 발생할 수 있음(저장 프로시저, 함수 등)
4. RC 격리 수준(읽기 커밋), binlog 기록 순서가 트랜잭션 커밋 순서에 기록되므로 마스터-슬레이브 불일치가 발생할 수 있음 복제. 이는 반복 읽기 수준에서 간격 잠금을 도입하여 해결할 수 있습니다.
2) 행
1. SQL 문의 컨텍스트 레코드를 기록하지 않고 각 레코드의 수정 사항을 기록합니다.
2. 대량의 binlog 로그가 생성됩니다.
3. 테이블 : 삭제되는 각 레코드의 상황을 기록합니다
3) 혼합
1. 처음 두 형식의 혼합 버전
2 명령문에 따라 사용할 형식을 자동으로 선택합니다.
1 문제 해결
2. 지원되는 복제 유형(binlog의 세 가지 형식)
1) 기본 개념
라이브러리에서 두 개의 스레드 생성
I/O 스레드
SQL 스레드
log dumo 스레드
1 .from 노드가 슬레이브 시작 명령을 시작한 후 마스터 노드에 연결하기 위한 IO 프로세스를 생성합니다
2. 마스터 노드는 로그 덤프 스레드를 생성합니다(마스터 노드는 각 슬레이브 노드에 대한 로그 덤프 스레드를 생성합니다)
3. binlog가 변경되면 마스터 노드의 덤프 로그 스레드는 bin-log 내용을 읽고 다음으로 보냅니다. 슬레이브 노드
4. 마스터 노드의 덤프 로그 스레드가 bin-log 내용을 읽으면 이를 마스터 노드로 보냅니다. bin-log는 잠겨 있으며, 이후 슬레이브 노드로 보내기 전에 잠금이 해제됩니다. 읽기 완료
5. 슬레이브 노드의 IO 스레드는 마스터 노드가 보낸 binlog 내용을 받아 로컬 릴레이 로그 파일에 씁니다
6. -binlog 파일 + 위치 오프셋을 통한 슬레이브 동기화 슬레이브 노드는 수신된 위치 오프셋을 저장합니다. 슬레이브 노드가 다운되고 다시 시작되면 위치 위치에서 자동으로 동기화가 시작됩니다
7. 노드의 SQL 스레드에서 로컬 릴레이 로그를 특정 작업으로 구문 분석하고 실행하여 마스터-슬레이브 데이터 일관성을 보장합니다
1) 비동기 모드(기본 모드) )
1. 마스터-슬레이브 불일치(마스터-슬레이브 지연)가 발생할 수 있습니다.
2. 마스터 노드는 클라이언트가 제출한 트랜잭션을 받은 후 직접 트랜잭션을 제출하고 클라이언트에 반환합니다.
3 마스터 노드 트랜잭션이 제출된 후 로그 덤프가 기록되기 전에 로그 덤프가 충돌하면 마스터-슬레이브 데이터가 일치하지 않게 됩니다.
4. 마스터-슬레이브 동기화 작업을 걱정하려면 성능이 최고입니다
2) 전체 동기화 모드
1 더 안정적이지만 메인 라이브러리의 응답 시간에 영향을 미칩니다
2. 메인 노드는 클라이언트가 제출한 트랜잭션을 받은 후 binlog가 슬레이브 라이브러리로 전송될 때까지 기다려야 하며 모든 슬레이브 라이브러리가 실행된 후에만 트랜잭션이 클라이언트에 반환됩니다.
3) 세미 -동기 모드
1. 메인 데이터베이스의 일부 신뢰성을 높이고 응답 시간을 일부 증가시킵니다.
2. 마스터 노드가 클라이언트가 제출한 트랜잭션을 수신한 후 binlog가 전송될 때까지 기다립니다. 하나 이상의 슬레이브 라이브러리에 전송하고 로컬 릴레이 로그에 성공적으로 저장됩니다. 이때 메인 라이브러리는 트랜잭션을 제출하고 클라이언트에 반환합니다
4) server-id 및 server-uuid 구성
1. server-id는 연결된 마스터-슬레이브 및 다중 마스터-슬레이브 토폴로지
2에서 SQL 문의 무한 루프를 방지하기 위해 데이터베이스 인스턴스를 식별하는 데 사용됩니다. server-id의 기본값은 0이고 바이너리 로그입니다. 호스트에 대해서는 계속 기록되지만 모든 슬레이브 연결은 거부됩니다.
2. server-id = 0은 슬레이브에 대한 다른 인스턴스 연결을 거부합니다.
3. server-id는 전역 변수이므로 수정 후 서비스를 다시 시작해야 합니다.
4. library 슬레이브 라이브러리의 서버 ID와 동일한 경우
기본 복제-동일 서버 ID = 0, 슬레이브 라이브러리는 모든 마스터-슬레이브 동기화 데이터를 건너뛰어 마스터-슬레이브 데이터 불일치가 발생합니다
replicate-same-server-id = 1. 무선 루프 실행 sql
두 개의 슬레이브 라이브러리(B, C)에서 서버 ID가 중복되면 마스터-슬레이브 연결이 비정상적으로 발생하고 연결이 간헐적으로 끊어지기 전에
마스터 라이브러리(A)가 동일한 서버 ID를 찾아서 연결이 끊어집니다. 연결, 새 연결을 다시 등록합니다
B와 C 슬레이브 라이브러리의 연결이 계속해서 다시 연결됩니다
MySQL 서비스 자동으로 server-uuid 구성을 생성하고 생성합니다
마스터-슬레이브 동기화 시 마스터-슬레이브 인스턴스의 server-uuid가 동일하면 오류가 보고되고 종료되지만 설정을 통해 오류를 피할 수 있습니다. Replicate-same-server-id=1 (권장하지 않음)
5. 읽기-쓰기 분리
1) 코드 구현 기반, 하드웨어 비용 절감
2) 중간 프록시 구현 기반
3) 마스터-슬레이브 지연
슬레이브 라이브러리의 성능이 메인 라이브러리보다 나쁩니다
쿼리 수가 많으면 슬레이브 라이브러리에 큰 부담이 되고 CPU 리소스를 많이 소모하여 영향을 줍니다. 동기화 속도: 하나의 마스터와 여러 개의 슬레이브
대규모 트랜잭션 실행: 트랜잭션이 실행될 때까지 binlog가 기록되지 않으며 슬레이브 라이브러리 읽기 지연
메인 라이브러리 ddl(alter, drop, create)
1. 요청 및 보유 조건: 모든 리소스가 한 번에 할당되고 그렇지 않으면 할당되지 않습니다.
2. 교착 상태 해제
21. MySQL은 최적화합니다. 대용량 페이징 쿼리 제한 100000(offset), 10(page_sie)
1. 이유
지연 연관: 커버링 인덱스 사용
기본 키 임계값 방법: 기본 키가 자동 증가, 조건에 맞는 기본 키의 최대값과 최소값을 조건을 통해 계산합니다(커버링 인덱스 사용)record 이전 페이지의 결과 위치, OFFSET
방법:
3) 데이터 불일치
2. 먼저 데이터베이스를 업데이트한 다음 redis를 업데이트하세요 시나리오: A 프로세스 업데이트 세트 값 = 10, 여기서 값 = 9; value = 11 where value = 9; 1) 프로세스 A가 먼저 데이터베이스를 업데이트하지만 아직 캐시에 기록되지 않았습니다. mysql value = 10; redis value = 9 2) 프로세스 B가 데이터베이스를 업데이트하고 트랜잭션을 제출합니다. , 캐시 쓰기: mysql 값 = 11; redis 값 = 11; 3) 프로세스 A가 요청을 완료하고 트랜잭션을 제출하고 캐시를 씁니다: redis 값 = 10; 마지막으로 mysql 값 = 11; 값 = 103. 먼저 캐시를 삭제한 다음 데이터베이스를 업데이트하세요 시나리오: 프로세스 A가 설정 값 = 10을 업데이트합니다. 여기서 값 = 9, 프로세스 B가 값을 쿼리합니다. 1) 프로세스 A가 캐시를 먼저 삭제한 다음 거기에 있습니다. 데이터를 수정할 시간이 없었거나 트랜잭션이 제출되지 않았습니다 2) 프로세스 B가 쿼리를 시작했지만 캐시에 도달하지 않았기 때문에 데이터베이스를 확인하고 캐시에 기록했습니다. redis 값 = 9 3) 프로세스 A mysql 값 = 10을 완료하도록 데이터베이스를 업데이트했습니다. 4) 마지막으로 mysql 값 = 10; redis 값 = 9해결책:
1. 프로세스 업데이트 설정 값 = 10 여기서 값은 =입니다. 9; B 프로세스 쿼리 값 1) A 프로세스가 캐시를 먼저 삭제하고 데이터를 수정할 시간이 없거나 트랜잭션이 제출되지 않았습니다. 2) 프로세스 B가 쿼리를 시작하고 캐시에 도달하지 않습니다. 따라서 데이터베이스를 확인하고 캐시에 기록합니다. redis 값 = 9 3) 프로세스 A가 데이터베이스를 업데이트하고 mysql 값 = 10을 완료합니다. 4) 프로세스 A가 지연 시간을 예측하고 절전 모드 후에 캐시를 다시 삭제합니다5 ) 마지막으로 mysql 값 = 10; redis 값이 비어 있습니다(다음에 데이터베이스를 직접 확인하세요) ~ 6) B 프로세스의 B 프로세스를 방지하기 위해 지연되는 이유 ) 캐시가 존재하지 않고 데이터베이스를 확인해야 할 경우 키는 업데이트 큐에 저장됩니다
3) 쿼리가 완료되기 전에 새 요청이 들어오고 키가 업데이트 대기열에 여전히 존재하는 것으로 확인되면 키가 쿼리 대기열에 배치되고 기다립니다. 키가 존재하지 않으면 두 번째 단계를 반복합니다 4) 쿼리된 데이터는 쿼리 큐가 이미 존재한다는 것을 발견하므로 큐에 다시 쓸 필요가 없습니다 5) 데이터 업데이트가 완료된 후 rpop은 큐를 업데이트하고 동시에 rpop은 큐를 쿼리하고 쿼리를 해제합니다. 요청 6 ) 쿼리 요청은 while + sleep을 사용하여 캐시를 쿼리하고 최대 지연 시간을 설정할 수 있습니다. 완료되지 않으면 redis1에서 공백
Twenty-3, connect 및 pconnect를 반환합니다. : 스크립트 종료 후 연결 해제
1. 닫기: 연결 해제2. pconnect(긴 연결): 스크립트가 종료되면 연결이 해제되지 않으며, php-fpm 프로세스에 남아 있습니다. 수명 주기는 php-fpm 프로세스의 수명 주기를 따릅니다
1. close 연결이 해제되지 않았습니다현재 php-cgi 프로세스에서는 redis를 다시 요청할 수 없습니다
24. Redis zset Order Collection에서 Skiplist 사용 원리
1. 기본 개념1. Skiplist는 계층적 연결 리스트의 요소를 순서대로 저장하는 임의의 데이터입니다.
3. 중복된 값은 허용되므로 비교 검사는 키뿐만 아니라 값도 비교해야 합니다
2, 스킵 테이블 비교 및 균형 트리
1) 범위 쿼리 효율성
점프 테이블 범위 쿼리는 최소값을 찾았기 때문에 더 효율적입니다. 그 후에는 최대값보다 작을 때까지 1단계 연결 리스트만 순회하면 됩니다. value
균형 트리 범위 쿼리는 최소값을 찾은 다음, 최대값을 초과하지 않는 다른 노드를 찾기 위해 순차 순회를 수행합니다.
2) 메모리 점유
1) 예약 삭제
타이머를 통해 만료되면 즉시 삭제
메모리 친화적인 CPU 불친절
검사를 위해 만료 시간이 설정된 일부 키를 주기적으로 무작위로 테스트하고 만료되면 삭제합니다
각 정리 시간은 CPU의 25%를 초과해서는 안 되며, 해당 시간에 도달하면 확인을 종료하세요
정기적으로 삭제된 키는 없으며, 앞으로도 사용하지 않을 키는 여전히 존재합니다. 메모리에 있으므로 제거 전략에 협조해야 합니다
휘발성-lru : 만료 시간이 설정되고 최근에 사용된 횟수가 적을수록 제거 우선순위가 부여됩니다.
휘발성-ttl : 만료 시간이 설정되고 만료 시간이 빠를수록 우선순위가 제거됩니다. 삭제
휘발성-random : 만료가 설정됨 시간에 따라 무작위로 삭제
allkeys-lru : 모든 키의 만료 시간이 빠를수록 우선순위가 제거됩니다.
allkeys-random : 모든 키가 삭제됩니다. 만료 시 무작위로 제거됨
no-enviction: 제거가 허용되지 않음, 메모리 부족 오류 보고
1. 동시에 데이터베이스를 직접 쿼리하라는 요청이 발생하여 데이터베이스 메모리 및 CPU 부담이 증가하거나 가동 중지 시간도 증가합니다
해결책:
핫스팟 데이터가 만료되지 않거나 다른 인스턴스에 분산되어 단일 시스템 오류 문제가 줄어듭니다
많은 수의 캐시가 동시에 무효화되는 것을 방지하기 위해 캐시 시간에 임의의 숫자를 추가하세요
2단계 캐시 또는 이중 캐시를 수행합니다. A는 원래 캐시 짧은 적시성, B는 유효한 백업 캐시입니다. 오랫동안. 업데이트 시 캐시 이중 쓰기
2. 캐시 침투: 캐시와 데이터베이스에 데이터가 없습니다. 요청이 많은 경우 모든 요청이 데이터베이스에 직접 침투하여 다운타임이 발생합니다.
해결책:
블룸 필터: 비트 벡터 또는 길이가 m인 비트 목록(0 또는 1 비트 값만 포함하는 목록)으로 구성됨
여러 개의 서로 다른 해시 함수를 사용하여 여러 인덱스 값 생성 , 여러 위치에 해당하는 값을 입력하면 1
Bloom 필터를 사용하면 그 값이 "아마도 집합에 있음"인지 "확실히 집합에 있지 않음"인지 확인할 수 있습니다
잘못 판단할 수도 있지만 기본 필터링 효율성이 높습니다
심각한 경우 Bloom 필터에 여유 공간이 없을 경우 각 쿼리는 true를 반환합니다
빈 캐시(단기)
비즈니스 레이어 매개변수 필터링
3. 캐시 히트 웨어: 데이터베이스에 데이터가 있는데 갑자기 캐시 장애가 발생한 후 대량의 요청이 발생하여 데이터베이스에 대한 부담이 가중되고 심지어 다운타임까지 발생했습니다
해결책:
핫 데이터 만료되지 않음
Mutex 잠금: 잠금 획득 후 성공 여부에 관계없이 잠금은 해제되어야 합니다
1.
1) CGI 프로토콜
동적 언어의 코드 파일은 해당 코드 파일을 전달해야 합니다. 파서는 서버에서 인식될 수 있습니다
CGI 프로토콜은 서버와 인터프리터가 서로 통신할 수 있도록 하는 데 사용됩니다. other
PHP 파일을 구문 분석하려면 서버에 PHP 인터프리터와 해당 CGI 프로토콜이 필요합니다.
2) CGI 프로그램 = php-cgi
php-cgi는 CGI를 준수하는 CGI 프로그램입니다. 프로토콜
이자 PHP 인터프리터이기도 합니다
표준 CGI는 각 요청에 대해 php.ini를 구문 분석하고 실행 환경을 초기화하여 성능을 저하시킵니다
구성을 수정할 때마다 php.ini를 적용하려면 php-cgi를 다시 실행하세요
동적으로 작업자를 예약할 수 없으며 처음에만 작업자 수를 지정할 수 있습니다
3) FastCGI 프로토콜
프로토콜이기도 합니다 /표준이지만 CGI 기반으로 최적화되어 CGI 프로그램의 성능을 향상시키는 데 사용됩니다. 4) FastCGI 프로그램 = php-fpm
php-fpm은 FastCGI 프로토콜을 준수하는 FastCGI 프로그램입니다.
FastCGI 프로그램의 CGI 프로그램 관리 모드
마스터 프로세스 시작, 구성 파일 구문 분석 및 환경 초기화
여러 작업자 하위 시작 -processes
요청을 받은 후 작업자 프로세스에 전달하여 실행
process_control_timeout = 0, 이는 적용되지 않고 원활한 재시작을 보장할 수 없음을 의미합니다.
process_control_timeout 설정을 너무 크게 설정하면 시스템 요청 정체가 발생할 수 있습니다.
process_control_timeout =10, 코드 로직에 11초가 걸리면 이전 로직을 다시 시작하면 코드 실행이 발생할 수 있습니다.
권장 값: request_terminate_timeout
PHP-FPM 라이프 사이클: https://www.abelzhou.com/php/php-fpm-lifespan/#
참조:
1 통신 방법: fastcgi_pass
1 )tcp 소켓
크로스 서버, nginx와 php가 동일한 시스템에 없을 때 이 방법만 사용할 수 있습니다
연결 지향 프로토콜을 사용하면 통신의 정확성과 무결성을 더 잘 보장할 수 있습니다
2) 유닉스 소켓
은 네트워크 프로토콜 스택, 패키징 및 언패킹 등이 필요하지 않습니다.
TCP 오버헤드를 줄이고, TCP 소켓보다 효율적입니다.
동시성이 높으면 불안정하며, 연결 수가 갑자기 증가하면 많은 수의 장기 캐시가 생성됩니다. 대용량 데이터 패킷은 직접 예외를 반환할 수 있습니다
참고:
1.SQL 주입
2을 간략하게 분석합니다. ](https://tech.meituan.com/2018/09/27/fe-security.html)
3. CSRF 공격:
추천 자료: [프론트엔드 보안 시리즈(2): 방법 CSRF 공격을 방지하시겠습니까? ](https://tech.meituan.com/2018/10/11/fe-security-csrf.html)
4. 파일 업로드 취약점
추천 자료: [파일 업로드 취약점에 대한 간략한 분석]( https: //xz.aliyun.com/t/7365)
5. 도메인 간 문제:
1) jsonp
2) cors 3) nginx 프록시추천 학습: "PHP 비디오 튜토리얼
"위 내용은 2023년 최신 PHP 면접 질문 28개 공유(답변 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!