머리말
대머리만이 당신을 강하게 만들 수 있습니다
저도 예전에 블로그를 하다가 글이 잘 쓰여진 블로그들이 소리 없이 모아지는 걸 발견했습니다. 최근 누락된 내용을 확인하고 있는데 상대적으로 중요한 지식 포인트가 있는데, 이전 블로그에 작성하지 않았기 때문에 여유 시간을 활용해 정리했습니다. (추천: JAVA 면접 질문 모음 ).
텍스트 지식 포인트:
정수 상수 풀
TCP 압축 해제 및 고정
select, poll, epoll
간단한 차이점select、poll、epoll
简单区别jdk1.6以后对Synchronize锁优化
Java内存模型
本文力求简单讲清每个知识点,希望大家看完能有所收获
一、神奇的Integer
前阵子在群上看有人在讨论关于Integer的true或者false问题,我本以为我已经懂了这方面的知识点了。但还是做错了,后来去请教了一下朋友。朋友又给我发了另一张图:
后来发现这是出自《深入理解Java虚拟机——JVM高级特性与最佳实践(第2版)》中的10.3.2小节中~
public class Main_1 { public static void main(String[] args) { Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; Long h = 2L; System.out.println(c == d); System.out.println(e == f); System.out.println(c == (a + b)); System.out.println(c.equals(a + b)); System.out.println(g == (a + b)); System.out.println(g.equals(a + b)); System.out.println(g.equals(a + h)); } }
你们可以先思考一下再往下翻看答案,看看能不能做对。
1.1解题思路
在解这道题之前,相信很多人都已经知道了,在Java中会有一个Integer缓存池,缓存的大小是:-128~127
答案是:
true
false
true
true
true
false
true
简单解释一下:
使用
==
的情况:如果比较Integer变量,默认比较的是地址值。
Java的Integer维护了从
-128~127
的缓存池如果比较的某一边有操作表达式(例如a+b),那么比较的是具体数值
使用
equals()
的情况:无论是Integer还是Long中的
equals()
默认比较的是数值。Long的
equals()
方法,JDK的默认实现:会判断是否是Long类型注意自动拆箱,自动装箱问题。
反编译一下看看:
import java.io.PrintStream; public class Main_1 { public static void main(String[] paramArrayOfString) { Integer localInteger1 = Integer.valueOf(1); Integer localInteger2 = Integer.valueOf(2); Integer localInteger3 = Integer.valueOf(3); Integer localInteger4 = Integer.valueOf(3); Integer localInteger5 = Integer.valueOf(321); Integer localInteger6 = Integer.valueOf(321); Long localLong = Long.valueOf(3L); // 缓存池 System.out.println(localInteger3 == localInteger4); // 超出缓存池范围 System.out.println(localInteger5 == localInteger6); // 存在a+b数值表达式,比较的是数值 System.out.println(localInteger3.intValue() == localInteger1.intValue() + localInteger2.intValue()); // equals比较的是数值 System.out.println(localInteger3.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue()))); // 存在a+b数值表达式,比较的是数值 System.out.println(localLong.longValue() == localInteger1.intValue() + localInteger2.intValue()); // Long的equals()先判断传递进来的是不是Long类型,而a+b自动装箱的是Integer类型 System.out.println(localLong.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue()))); // ... 最后一句在这里漏掉了,大家应该可以推断出来 } }
我使用的反编译工具是jd-gui
- jdk1.6 이상용 동기화 잠금 최적화
- 는 각 지식 포인트를 간략하게 설명하려고 노력하고 있습니다
- , 모두가 이 글을 읽고 뭔가를 얻을 수 있기를 바랍니다1. 마법의 정수
- 그룹 A에서 누군가를 봤습니다. 얼마 전 Integer의 참/거짓 문제를 논할 때 이 지식 포인트를 이미 이해했다고 생각했습니다. 하지만 그래도 실수를 해서 친구에게 조언을 구했습니다. 친구가 나에게 다른 사진을 보냈습니다:
- 나중에 이 내용이 "Java Virtual Machine의 심층 이해 - JVM 고급 기능 및 모범 사례(2판)"의 10.3.2절에 있다는 것을 알게 되었습니다~
public void vectorTest(){ Vector<String> vector = new Vector<String>(); for(int i = 0 ; i < 10 ; i++){ vector.add(i + ""); } System.out.println(vector); }
생각해 보면 됩니다. 답을 읽기 전에 잠시 동안 답을 읽어보고 정답을 맞힐 수 있는지 확인하세요. - 1.1 문제 해결 아이디어이 문제를 해결하기 전에 많은 사람들이 이미 Java에 정수 캐시 풀이 있고 캐시 크기는
-128~127
- 답은 다음과 같습니다.
- true
- false
- true
- true
- true
true
간단한 설명:
사용 == 사례:
-
정수 변수를 비교하는 경우 기본 비교는 주소 값입니다. .
Java의 정수는 -128~127
equals()
사용: 🎜🎜- 🎜🎜아니요 문제 정수인가요 아니면 Long인가요?
equals()
의 기본값은 🎜숫자 값🎜입니다. 🎜🎜🎜🎜Long의 equals()
메소드, JDK의 기본 구현: 🎜Long 유형인지 여부를 결정합니다🎜🎜🎜🎜🎜🎜자동 언박싱 및 자동 박싱 문제에 주의하세요. 🎜🎜🎜🎜
jd-gui
입니다. 아직 디컴파일을 시도하지 않았다면 다운로드하여 사용할 수 있습니다. 🎜🎜🎜 🎜https: //github.com/java-decompiler/jd-gui/releases🎜🎜🎜🎜2. 동기화 잠금 최적화 방법은 무엇입니까? 멀티 스레딩 기사 리뷰: 🎜🎜🎜🎜ThreadLocal은 매우 간단합니다🎜🎜🎜🎜 멀티스레딩 3분이면 문 안으로 들어갈 수 있어요! 🎜🎜🎜🎜스레드 소스코드 분석🎜🎜🎜🎜멀티스레딩의 기본지식 포인트! 계속 읽어서 멀티스레딩을 배우고 절반의 노력으로 두 배의 결과를 얻으세요🎜🎜🎜🎜Java 잠금 메커니즘에 대해 알아보고🎜🎜🎜🎜AQS에 대해 알아보고 간단히 살펴보세요🎜🎜🎜🎜잠금 하위 클래스에 대해 알아보기🎜🎜🎜🎜 스레드 풀, 정말 배우고 싶지 않나요? 🎜🎜🎜🎜멀티쓰레드 교착상태는 참 간단해요🎜🎜🎜🎜자바 멀티스레딩을 도와주는 세 젊은이🎜🎜🎜🎜전에 멀티스레딩 글을 썼을 때, jdk1 이후에 동기화 잠금이 일어난다고 간략하게 말씀드렸습니다. 6 스핀 잠금, 잠금 제거, 잠금 조대화, 경량 잠금 및 바이어스 잠금에 대한 적응 등 다양한 최적화가 있습니다. 🎜🎜🎜🎜🎜이러한 최적화가 참 이해하기 어렵다고 생각했는데 사실~~간단한 이해로 이해하기 쉽습니다. 🎜🎜2.1 스핀 잠금에 적응🎜🎜잠금 경쟁은 커널 모드에서 사용자 모드에서 커널 모드로 🎜전환🎜을 거치게 되는데, 이는 꽤 시간이 많이 걸립니다. 🎜🎜🎜스핀 잠금🎜이 나타나는 이유는 대부분의 경우 🎜잠금 점유가 커널 모드로 전환하는 데 걸리는 시간보다 훨씬 짧은 시간🎜 동안만 지속되므로 스레드를 기다리게 하기 때문입니다. 커널 모드에 들어가기 전 제한된 시간, 이 시간 내에 잠금을 얻을 수 있으면 불필요한 시간을 많이 피할 수 있습니다. 그렇지 않은 경우 커널 모드에 들어가 잠금을 위해 경쟁합니다. 🎜🎜JDK 1.6에 적응형 스핀 잠금이 도입되었습니다. 이는 🎜회전 시간이 고정되지 않고 회전 여부가 점점 더 똑똑해진다🎜는 의미입니다. 🎜自旋锁在JDK1.4.2中就已经引入,只不过默认是关闭的,可以使用-XX:+UseSpinning
参数来开启,在JDK1.6中就已经改为默认开启了。
2.2锁消除
如果JVM明显检测到某段代码是线程安全的(言外之意:无锁也是安全的),JVM会安全地原有的锁消除掉!
比如说:
public void vectorTest(){ Vector<String> vector = new Vector<String>(); for(int i = 0 ; i < 10 ; i++){ vector.add(i + ""); } System.out.println(vector); }
Vector是默认加锁的,但JVM如果发现vector变量仅仅在vectorTest()
方法中使用,那该vector是线程安全的。JVM会把vector内部加的锁去除,这个优化就叫做:锁消除。
2.3锁粗化
默认情况下,总是推荐将同步块的作用范围限制得尽量小。
但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作是出现在循环体中的,频繁地进行互斥同步操作也会导致不必要的性能损耗。
JVM会将加锁的范围扩展(粗化),这就叫做锁粗化。
2.4轻量级锁
轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。
如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销
但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。
简单来说:如果发现同步周期内都是不存在竞争,JVM会使用CAS操作来替代操作系统互斥量。这个优化就被叫做轻量级锁。
2.5偏向锁
偏向锁就是在无竞争的情况下把整个同步都消除掉,连CAS操作都不做了!
偏向锁可以提高带有同步但无竞争的程序性能。它同样是一个带有效益权衡(Trade Off)性质的优化,也就是说,它并不一定总是对程序运行有利,如果程序中大多数的锁总是被多个不同的线程访问,那偏向模式就是多余的。在具体问题具体分析的前提下,有时候使用参数-XX:-UseBiasedLocking
来禁止偏向锁优化反而可以提升性能。
2.6简单总结各种锁优化
自适应偏向锁:自旋时间不固定
锁消除:如果发现代码是线程安全的,将锁去掉
锁粗化:加锁范围过小(重复加锁),将加锁的范围扩展
轻量级锁:在无竞争的情况下使用CAS操作去消除同步使用的互斥量
偏向锁:在无竞争环境下,把整个同步都消除,CAS也不做。
参考资料:
https://blog.csdn.net/chenssy/article/details/54883355
三、TCP粘包,拆包
这是在看wangjingxin大佬面经的时候看到的面试题,之前对TCP粘包,拆包没什么概念,于是就简单去了解一下。
3.1什么是拆包粘包?为什么会出现?
在进行Java NIO学习时,可能会发现:如果客户端连续不断的向服务端发送数据包时,服务端接收的数据会出现两个数据包粘在一起的情况。
TCP的首部格式:
TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界;
从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段
基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。
一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包
接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包
拆包和粘包的问题导致接收端在处理的时候会非常困难(因为无法区分一个完整的数据包)
3.2 포장을 풀고 붙는 문제 해결
하위 포장 메커니즘에는 일반적으로 두 가지 공통 솔루션이 있습니다:
1, 특수 문자 제어
2, 헤더 대문자에 데이터 패킷 길이 추가
네티를 사용한다면 포장을 풀고 달라붙는 문제를 해결하기 위한 특수 인코더와 디코더가 있습니다.
팁:UDP에는 패킷 고착 문제가 없지만 패킷 손실 및 장애가 있습니다. 불완전한 패키지는 없으며, 수신된 모든 패키지는 완전히 정확합니다. 전송되는 데이터 단위 프로토콜은 UDP 메시지 또는 사용자 데이터그램이며 전송 시 병합되거나 분할되지 않습니다.
4. select, poll, epoll의 간단한 차이점
NIO 리뷰:
JDK10이 출시되었습니다. nio에 대해 얼마나 알고 계시나요?
Linux에서 I/O 재사용 모델을 구현하는 방법은 다음과 같습니다.
select/poll/epoll
함수 중 하나를 호출하고 여러 파일 설명자를 전달합니다. 파일 설명자가 준비되었습니다. 그렇지 않으면 시간 초과될 때까지 차단됩니다. select/poll/epoll
其中一个函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。
这几个函数是有些区别的,可能有的面试官会问到这三个函数究竟有什么区别:
区别如下图:
两句话总结:
select和poll
都需要轮询每个文件描述符,epoll
基于事件驱动,不用轮询select和poll
每次都需要拷贝文件描述符,epoll
不用select
最大连接数受限,epoll和poll
最大连接数不受限
tips:epoll在内核中的实现,用红黑树管理事件块
4.1通俗例子
现在3y在公司里边实习,写完的代码需要给测试测一遍。
select/poll
情况:
开发在写代码,此时测试挨个问所有开发者,你写好程序了没有?要测试吗?
epoll
- 차이점은 다음과 같습니다.
선택 및 설문 조사
각 파일 설명자를 폴링해야 합니다. epoll
은 이벤트 기반이며 폴링이 필요하지 않습니다
select and poll
은 매번 파일 설명자를 복사해야 합니다. epoll
은 사용되지 않습니다
select
최대 연결 수는 제한되어 있으며, epoll 및 poll
최대 연결 수는 제한되지 않습니다- 팁: 커널에서 epoll 구현은 레드-블랙 트리를 사용하여 이벤트 블록을 관리합니다
현재 3y는 회사에서 인턴으로 일하고 있으며 작성된 코드를 테스트해야 합니다.
select/poll
상황:
개발자가 코드를 작성하는 중입니다. 이때 테스트는 모든 개발자에게 하나씩
. 프로그램 작성을 마쳤나요? 테스트하고 싶나요?
epoll
상황:
- 개발자가 코드 작성을 마치고 테스터에게 다음과 같이 말합니다. "내가 코드를 작성했으니 가서 테스트해 보세요. 함수는 XXX입니다." 그래서 테스터는 기쁜 마음으로 버그를 찾았습니다.
다른 인기 있는 설명 [1]:
- 바텐더(실), 한 무리의 술고래들이 그 앞에 누워 있는데, 갑자기 그들 중 한 명이 "와인을 부어라"라고 외치면(사건), 당신은 달려가서 붓습니다. 그를 놔주고 갑자기 다른 사람이 포도주를 따르려고 하면 당신이 가서 따르십시오. 이렇게 웨이터는 때때로 술을 마시는 사람이 없고 웨이터가 한가해서 할 수 있습니다. 다른 일을 하고 휴대폰을 가지고 놀아요. epoll과 select의 경우, poll과 poll의 차이점은 후반 두 장면에서 술 취한 사람들이 한 명씩 술 한잔 하겠느냐고 물어야 하고, 휴대폰을 가지고 놀 시간도 없다는 점이다. . io 멀티플렉싱은 아마도 이 술고래들이 웨이터를 공유한다는 것을 의미할 것입니다.
기타 인기 있는 설명 [2]: 간단한 예를 들자면(별로 생생하지 않을 수도 있음) 선택/설문 조사 레스토랑 웨이터(커널)가 호텔 소유자(사용자 프로그램)에게 "지금 체크아웃하는 고객이 있습니다"라고 말하지만 아니요 이 웨이터를 아는 사람이 손님이 어떤 테이블에 돈을 지불하는지 상사에게 말하십시오. 사장님은 각 테이블에 가서 물어보세요: 지불하시겠습니까? epoll 호텔 웨이터(커널)가 호텔 주인(사용자 프로그램)에게 "1번, 2번, 5번 손님은 체크아웃하세요."라고 말합니다. 사장은 1번, 2번, 5번 테이블로 직접 가서 돈을 모을 수 있습니다
5. Java 메모리 모델 - JVM 블로그 게시물 리뷰:
JVM은 어떻게 시작에서 포기하게 되었나요?
JVM 메모리 구조와 Java 메모리 모델을 혼동한 적이 있었습니다~~~ 다행히 일부 열성적인 네티즌들이 지적해 주셨습니다.
JVM 메모리 구조:- Java 메모리 모델:
- 🎜🎜 변수 운영 시 규칙: 🎜🎜🎜🎜Java 메모리 모델은 모든 🎜 변수가 메인 메모리에 저장되도록 규정합니다. 🎜🎜🎜🎜 🎜 스레드 🎜 작업 메모리🎜는 스레드가 사용하는 변수의 주 메모리 🎜복사본🎜🎜🎜🎜을 저장합니다. 스레드에 의한 변수의 모든 🎜작업🎜(읽기, 할당 등)은 🎜작업 메모리🎜에서 수행되어야 합니다. 🎜🎜🎜🎜 🎜 작업 메모리에서 메인 메모리로의 동기화 🎜는 다음 8가지 작업을 통해 구현됩니다. 🎜🎜🎜🎜lock(잠금): 메인 메모리의 변수에 작용합니다. memory , 변수를 하나의 스레드에만 사용되는 것으로 표시합니다. 🎜🎜🎜🎜unlock(잠금 해제): 잠금 상태의 변수를 해제하기 위해 주 메모리 변수에 작용합니다. 해제된 변수만 다른 스레드에 의해 잠길 수 있습니다. 🎜
read(읽기): 메인 메모리 변수에 대해 작동하고, 후속 로드 작업에서 사용할 수 있도록 메인 메모리에서 스레드의 작업 메모리로 변수 값을 전송합니다.
load(로드) : 읽기 작업을 통해 주 메모리에서 얻은 변수 값을 작업 메모리의 변수 복사본에 저장하는 작업 메모리 변수에 작용합니다.
use(사용): 작업 메모리의 변수에 작용하여 작업 메모리의 변수 값을 실행 엔진에 전달합니다. 이는 가상 머신이 변수 값이 필요한 바이트코드 명령어를 발견할 때마다 실행됩니다. 작동하다.
할당(할당): 작업 메모리의 변수에 작용합니다. 실행 엔진에서 받은 값을 작업 메모리의 변수에 할당합니다. 이는 가상 머신이 값을 할당하는 바이트코드 명령어를 만날 때마다 실행됩니다. 변수로 작동합니다.
store(저장소): 작업 메모리의 변수에 작용하여 후속 쓰기 작업을 위해 작업 메모리의 변수 값을 주 메모리로 전송합니다.
write(쓰기): 메인 메모리의 변수에 대해 작업 메모리의 변수 값에서 메인 메모리의 변수로 저장 작업을 전송합니다.
Java 메모리 모델은 동시 프로세스에서 원자성, 가시성 및 순서를 처리하는 방법을 중심으로 구축되었습니다.
원자성을 보장하는 작업:
read、load、assign、use、store和write
-
동기화 잠금
보장하는 운영 질서(무질서한 결과 재정렬):
휘발성
동기화 잠금
가시성 보장:
휘발성
동기화 잠금
final
위에서도 언급했듯이, 휘발성 및 동기화 잠금을 통해 질서를 보장할 수 있지만 일반적으로 프로그램을 작성할 때 코드의 질서에 항상 주의를 기울이지는 않습니다. 실제로 Java에는 이전 발생 원칙(이전 발생)
- 이라는 원칙이 있습니다. "이전 발생" 원칙은 몇 가지
- 를 통해 동시 환경에서 두 가지 문제를 해결하는 데 사용할 수 있습니다. 규칙
작업 간 충돌 가능성과 관련된 모든 문제
- 에는 이러한 규칙이 있으며, 당사의
작업은 이 규칙에 의해 정의된 범위 내에 있습니다. 작업 A가 작업 B보다 먼저 발생하도록 보장할 수 있습니다(재주문 문제는 없음)
- 프로그램 순서 규칙(프로그램 순서 규칙): 스레드에서는 프로그램 코드의 순서에 따라 앞에 쓰여진 작업이 뒤에 쓰여진 작업보다 먼저 발생합니다. 정확하게 말하면 프로그램 코드 순서가 아닌 제어 흐름 순서여야 합니다. 분기, 루프 등의 구조를 고려해야 하기 때문입니다.
- 모니터 잠금 규칙: 동일한 잠금에 대한 후속 잠금 작업 전에 잠금 해제 작업이 발생합니다. 여기서 강조해야 할 것은 동일한 잠금이고, "나중에"는 시간상의 순서를 의미합니다.
- 휘발성 변수 규칙: 휘발성 변수에 대한 쓰기 작업이 먼저 발생하고 나중에 변수에 대한 읽기 작업이 발생합니다. 스레드 시작 규칙: Thread 개체의 start() 메서드는 이 스레드의 모든 작업보다 우선합니다.
- 스레드 종료 규칙(Thread Termination Rule): 스레드의 모든 작업은 이 스레드의 종료 감지를 통해 먼저 발생합니다. Thread.isAlive()의 반환 값인 Thread.join() 메서드를 통해 스레드를 종료할 수 있습니다. 등. 스레드가 실행을 종료한 것으로 감지되었습니다.
- 스레드 중단 규칙: 중단된 스레드의 코드가 인터럽트 이벤트 발생을 감지하기 전에 먼저 스레드 Interrupt() 메소드 호출이 발생합니다. Thread.interrupted() 메소드를 통해 인터럽트 발생 여부를 감지할 수 있습니다.
- 객체 종료자 규칙: 객체 초기화(생성자 실행 끝)는 finalize() 메서드 시작 부분에서 먼저 발생합니다.
- 전환성: 작업 A가 작업 B보다 먼저 발생하고 작업 B가 작업 C보다 먼저 발생하면 작업 A가 작업 C보다 먼저 발생한다고 결론을 내릴 수 있습니다.
위 내용은 자바 면접 질문 모음 - 쉽게 제안을 받는 데 도움이 되는 추천 면접 질문의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要整理了Stream流的概念和使用的相关问题,包括了Stream流的概念、Stream流的获取、Stream流的常用方法等等内容,下面一起来看一下,希望对大家有帮助。


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

Dreamweaver Mac版
시각적 웹 개발 도구

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
