목차
일을 잘하려면 먼저 도구를 갈고닦아야 합니다
로그 레벨을 잊지 마세요
무엇을 녹음하고 있는지 아시나요?
避免副作用
描述要清晰
调整你的格式
记录方法的参数和返回值
观察外部系统
正确的记录异常
日志应当可读性强且易于解析
Java java지도 시간 Java 로그를 사용하여 시를 작성하는 방법에 대한 자세한 소개

Java 로그를 사용하여 시를 작성하는 방법에 대한 자세한 소개

Mar 25, 2017 am 10:53 AM

일을 잘하려면 먼저 도구를 갈고닦아야 합니다

많은 프로그래머는 동시성 버그가 발생했을 때 애플리케이션의 동작을 기록하는 것이 얼마나 중요한지 잊어버렸을 것입니다. 스레드 환경의 높은 압력으로 인해 발생하는 로그 기록의 중요성을 실감할 수 있습니다.

어떤 사람들은 다음 문장을 코드에 기꺼이 추가했습니다.

log.info("Happy and carefree logging");
로그인 후 복사

그는 유지 관리, 조정 및 오류 식별에서 애플리케이션 로그의 중요성을 깨닫지 못할 수도 있습니다.

저는 slf4j가 최고의 로깅 API라고 생각합니다. 주로 훌륭한 패턴 주입 방식을 지원하기 때문입니다.

log.debug("Found {} records matching filter: '{}'", records, filter);
로그인 후 복사

log4j 이렇게 하세요:

log.debug("Found " + records + " recordsmatching filter: '" + filter + "'");
로그인 후 복사

이렇게 작성하면 더 장황하고 가독성이 떨어질 뿐만 아니라 문자열 연결이 효율성에 영향을 미칩니다(이 수준에서는 출력이 필요하지 않은 경우).

slf4j는 {} 주입 기능을 도입하고, 문자열 접합이 매번 방지되므로 toString 메서드가 호출되지 않으며 isDebugEnabled가 더 이상 필요하지 않습니다.

slf4j는 외관 모드의 애플리케이션이며 단지 외관일 뿐입니다. 구체적인 구현을 위해서는 이미 완성된 log4j 대신 이전에 한 번 광고되었던 logback 프레임워크를 권장합니다. 흥미로운 기능이 많이 있으며 log4j와 달리 아직 개발 및 개선이 활발하게 진행되고 있습니다.

권장할 또 다른 도구는 perf4j입니다.

Perf4J는 System.currentTimeMillis()에 대한 것이고 log4j는 System.out.println()에 대한 것입니다

log4j가 System.out.println을 더 잘 대체하는 것처럼 perf4j도 System.currentTimeMillis()를 대체하는 것과 더 비슷합니다.

어떤 프로젝트에 perf4j를 도입하고 높은 부하에서 성능을 관찰한 적이 있습니다. 관리자와 비즈니스 사용자 모두 이 가젯이 제공하는 아름다운 차트에 깜짝 놀랐습니다.

성능 문제는 언제든지 검토할 수 있습니다. perf4j에 대한 전용 기사가 있어야 합니다. 지금은 개발자 가이드를 먼저 읽어보세요.

또한 Ceki Gülcü(log4j, slf4j 및 logback 프로젝트 창시자)는 commons-logging에 대한 종속성을 제거할 수 있는 간단한 방법을 제공합니다.

로그 레벨을 잊지 마세요

로그 라인을 추가하고 싶을 때마다 여기서 어떤 로그 레벨을 사용해야 할까? 약 90%의 프로그래머는 이 문제에 많은 관심을 기울이지 않습니다. 그들은 모두 하나의 수준(보통 INFO 또는 DEBUG)을 사용하여 로그를 기록합니다. 왜?

로깅 프레임워크에는 System.out에 비해 분류와 수준이라는 두 가지 주요 이점이 있습니다. 두 가지 모두 영구적으로 또는 문제 해결 시 로그를 선택적으로 필터링할 수 있습니다.

  • ERROR 심각한 오류가 발생했으며 즉시 처리해야 합니다. 이 수준의 오류는 어떤 시스템에서도 허용될 수 없습니다. 예: Null 포인터 예외, 데이터베이스를 사용할 수 없으며 중요 경로의 사용 사례를 계속 실행할 수 없습니다.

  • WARN은 후속 프로세스를 계속 실행할 예정이지만 심각하게 받아들여야 합니다. 실제로 여기에는 두 가지 수준이 있기를 바랍니다. 하나는 솔루션에 대한 명백한 문제(예: "현재 데이터를 사용할 수 없습니다. 캐시 데이터를 사용하세요.")이고, 다른 하나는 잠재적인 문제이며 제안(예: "프로그램이 개발 모드에서 실행 중입니다." 또는 "관리 콘솔의 비밀번호가 충분히 안전하지 않습니다.") 애플리케이션은 이러한 메시지를 허용할 수 있지만 확인하고 복구해야 합니다.

  • DEBUG는 개발자들의 고민거리입니다. 이 수준에서 어떤 것들을 기록해야 하는지는 나중에 이야기하겠습니다.

  • TRACE 보다 자세한 정보는 개발 단계에서만 사용됩니다. 제품 출시 후 짧은 기간 동안은 이 정보에 주의가 필요할 수 있지만 이러한 로그 기록은 일시적일 뿐이므로 결국에는 삭제되어야 합니다. DEBUG와 TRACE의 차이점은 구별하기 어렵지만, 로그 한 줄을 추가했다가 개발 및 테스트 후에 삭제한다면 로그는 TRACE 수준이어야 합니다.

위 목록은 단지 권장사항일 뿐이며 자신만의 규칙에 따라 로그인할 수 있지만 특정 규칙을 갖는 것이 가장 좋습니다. 내 개인적인 경험은 코드 수준에서 로그를 필터링하지 말고 올바른 로그 수준을 사용하여 원하는 정보를 빠르게 필터링하면 많은 시간을 절약할 수 있다는 것입니다.

마지막으로 이야기하고 싶은 것은 악명 높은 is*Enabled 조건문입니다. 어떤 사람들은 각 로그 앞에 다음을 추가하기를 좋아합니다.

if(log.isDebugEnabled())
    log.debug("Place for your commercial");
로그인 후 복사

개인적으로 저는 이렇게 지저분한 것을 코드에 추가하는 것을 피해야 한다고 생각합니다. 성능 향상은 없는 것 같습니다(특히 slf4j를 사용한 후). 조기 최적화와 비슷합니다. 또한 이것이 약간 중복된다는 것을 모르십니까? 로그 메시지 자체를 구성하는 데 비용이 너무 많이 든다는 것을 증명하지 않는 한, 그러한 명시적인 판단문이 분명히 필요한 경우는 거의 없습니다. 그렇지 않으면 원하는 것을 기억하고 로깅 프레임워크가 이를 처리하도록 하십시오.

무엇을 녹음하고 있는지 아시나요?

로그 줄을 작성할 때마다 잠시 시간을 내어 로그 파일에 정확히 무엇을 인쇄하고 있는지 살펴보세요. 로그를 읽고 예외 사항을 찾아보세요. 첫째, 최소한 널 포인터 예외를 피하십시오:

log.debug("Processing request with id: {}", request.getId());
로그인 후 복사

你确认过request不是null了吗?

记录集合也是一个大坑。如果你用Hibernate从数据库里获取领域对象的集合的时候,不小心写成了这样:

log.debug("Returning users: {}", users);
로그인 후 복사

slf4j只会在这条语句确实会打印的时候调用toString方法,当然这个很酷。不过如果内存溢出了,N+1选择问题,线程饿死,延迟初始化异常,日志存储空间用完了…这些都有可能发生。

最好的方式是只记录对象的ID(或者只记录集合的大小)。不过收集ID需要对每个对象调用getId方法,这个在Java里可真不是件简单的事。Groovy有个很棒的展开操作符(users*.id),在Java里我们可以用Commons Beanutils库来模拟下:

log.debug("Returning user ids: {}", collect(users, "id"));
로그인 후 복사

collect方法大概是这么实现的:

public static Collection collect(Collection collection, String propertyName) {
    return CollectionUtils.collect(collection, new BeanToPropertyValueTransformer(propertyName));
}
로그인 후 복사

最后要说的是,toString方法可能没有正确的实现或者使用。

首先,为了记录日志,为每个类创建一个toString的做法比比皆是,最好用 ToStringBuilder来生成(不过不是它的反射实现的那个版本)。

第二,注意数组和非典型的集合。数组和一些另类的集合的toString实现可能没有挨个调用每个元素的toString方法。可以使用JDK提供的Arrays#deepToString方法。经常检查一下你自己打印的日志,看有没有格式异常的一些信息。

避免副作用

日志打印一般对程序的性能没有太大影响。最近我一个朋友在一些特殊的平台上运行的一个系统抛出了Hibernate的LazyInitializationException异常。你可能从这已经猜到了,当会话连接进来的时候,一些日志打印导致延迟初始化的集合被加载。在这种情况下,把日志级别提高了,集合也就不再被初始化了。如果你不知道这些上下文信息,你得花多长时间来发现这个BUG。

另一个副作用就是影响程序的运行速度。快速回答一下这个问题:如果日志打印的过多或者没有正确的使用toString和字符串拼接,日志打印就会对性能产生负面影响。能有多大?好吧,我曾经见过一个程序每15分钟就重启一次,因为太多的日志导致的线程饿死。这就是副作用!从我的经验来看,一小时打印百来兆差不多就是上限了。

当然如果由于日志打印异常导致的业务进程中止,这个副作用就大了。我经常见到有人为了避免这个而这么写:

try {
    log.trace("Id=" + request.getUser().getId() + " accesses " + manager.getPage().getUrl().toString())
} catch(NullPointerException e) {}
로그인 후 복사

这是段真实的代码,但是为了让世界清净点,请不要这么写。

描述要清晰

每个日志记录都会包含数据和描述。看下这个例子:

log.debug("Message processed");
log.debug(message.getJMSMessageID());
log.debug("Message with id '{}' processed", message.getJMSMessageID());
로그인 후 복사

当在一个陌生的系统里排查错误的时候,你更希望看到哪种日志?相信我,上面这些例子都很常见。还有一个反面模式:

if(message instanceof TextMessage)
    //...
else
    log.warn("Unknown message type");
로그인 후 복사

在这个警告日志里加上消息类型,消息ID等等这些难道很困难吗?我是知道发生错误了,不过到底是什么错误?上下文信息是什么?

第三个反面例子是“魔法日志”。一个真实的例子:团队里的很多程序员都知道,3个&号后面跟着!号再跟着一个#号,再跟着一个伪随机数的日志意味着”ID为XYZ的消息收到了”。没人愿意改这个日志,某人敲下键盘,选中某个唯一的”&&&!#”字符串,他就能很快找到想要的信息。

结果是,整个日志文件看起来像一大串随机字符。有人不禁会怀疑这是不是一个perl程序。

日志文件应当是可读性强的,清晰的,自描述的。不要用一些魔数,记录值,数字,ID还有它们的上下文。记录处理的数据以及它的含义。记录程序正在干些什么。好的日志应该是程序代码的一份好的文档。

我有提过不要打印密码还有个人信息吗?相信没有这么傻的程序员。

调整你的格式

日志格式是个很有用的工具,无形中在日志添加了很有价值的上下文信息。不过你应该想清楚,在你的格式中包含什么样的信息。比如说,在每小时循环写入的日志中记录日期是没有意义的,因为你的日志名就已经包含了这个信息。相反的,如果你没记录线程名的话当两个线程并行的工作的时候,你就无法通过日志跟踪线程了——日志已经重叠到一起了。在单线程的应用程序中,这样做没问题,不过那个已经是过去的事儿了。

从我的经验来看,理想的日志格式应当包括(当然除了日志信息本身了):当前时间(无日期,毫秒级精度),日志级别,线程名,简单的日志名称(不用全称)还有消息。在logback里会是这样的:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern>
    </encoder>
</appender>
로그인 후 복사

文件名,类名,行号,都不用列进来,尽管它们看起来很有用。我还在代码里见过空的日志记录:

log.info(“”);
因为程序员认为行号会作为日志格式的一部分,并且他知道如果空日志消息出现在这个文件的67行的话,意味着这个用户是认证过的。不仅这样,记录类名方法名,或者行号对性能都有很大的影响。

日志框架的一个比较高级的特性是诊断上下文映射(Mapped Diagnostic Context)。MDC只是一个线程本地的一个map。你可以把任何键值对放到这个map里,这样的话这个线程的所有日志记录都能从这个map里取到相应的信息作为输出格式的一部分。

记录方法的参数和返回值

如果你在开发阶段发现了一个BUG,你通常会用调试器来跟踪具体的原因。现在假设不让你用调试器了,比如,因为这个BUG几天前在用户的环境里出现了,你能拿到的只有一些日志。你能从中发现些什么?

如果你遵循打印每个方法的入参和出参这个简单的原则,你根本不需要调试器。当然每个方法可能访问外部系统,阻塞,等待,等等,这些都应该考虑进来。就参考以下这个格式就好:

public String printDocument(Document doc, Mode mode) {
    log.debug("Entering printDocument(doc={}, mode={})", doc, mode);
    String id = ...; //Lengthy printing operation
    log.debug("Leaving printDocument(): {}", id);
    return id;
}
로그인 후 복사

由于你在方法的开始和结束都记录了日志,所以你可以人工找出效率不高的代码,甚至还可以检测到可能会引起死锁和饥饿的诱因——你只需看一下“Entering”后面是不是没有”Leaving“就明白了。如果你的方法名的含义很清晰,清日志将是一件愉快的事情。同样的,分析异常也更得更简单了,因为你知道每一步都在干些什么。代码里要记录的方法很多的话,可以用AOP切面来完成。这样减少了重复的代码,不过使用它得特别小心,不注意的话可能会导致输出大量的日志。

这种日志最合适的级别就是DEBUG和TRACE了。如果你发现某个方法调用 的太频繁,记录它的日志可能会影响性能的话,只需要调低它的日志级别就可以了,或者把日志直接删了(或者整个方法调用只留一个?)不过日志多了总比少了要强。把日志记录当成单元测试来看,你的代码应该布满了日志就像它的单元测试到处都是一样。系统没有任何一部分是完全不需要日志的。记住,有时候要知道你的系统是不是正常工作,你只能查看不断刷屏的日志。

观察外部系统

这条建议和前面的有些不同:如果你和一个外部系统通信的话,记得记录下你的系统传出和读入的数据。系统集成是一件苦差事,而诊断两个应用间的问题(想像下不同的公司,环境,技术团队)尤其困难。最近我们发现记录完整的消息内容,包括Apache CXF的SOAP和HTTP头,在系统的集成和测试阶段非常有效。

这样做开销很大,如果影响到了性能的话,你只能把日志关了。不过这样你的系统可能跑的很快,挂的也很快,你还无能为力?当和外部系统进行集成的时候,你只能格外小心并做好牺牲一定开销的准备。如果你运气够好,系统集成由ESB处理了,那在总线把请求和响应给记录下来就最好不过了。可以参考下Mule的这个日志组件。

有时候和外部系统交换的数据量决定了你不可能什么都记下来。另一方面,在测试阶段和发布初期,最好把所有东西都记到日志里,做好牺牲性能的准备。可以通过调整日志级别来完成这个。看下下面这个小技巧:

Collection<Integer> requestIds = //...
if(log.isDebugEnabled())
    log.debug("Processing ids: {}", requestIds);
else
    log.info("Processing ids size: {}", requestIds.size());
로그인 후 복사

如果这个logger是配置成DEBUG级别,它会打印完整的请求ID的集合。如果它配置成了打印INFO信息的话,就只会输出集合的大小。你可能会问我是不是忘了isInfoEnabled条件了,看下第二点建议吧。这里还有一个值得注意的是ID的集合不能为null。尽管在DEBUG下,它为NULL也能正常打印,但是当配置成INFO的时候一个大大的空指针。还记得第4点建议中提到的副作用吧?

正确的记录异常

首先,不要记录异常,让框架或者容器来干这个。当然有一个例外:如果你从远程服务中抛出了异常(RMI,EJB等),异常会被序列化,确保它们能返回给客户端 (API中的一部分)。不然的话,客户端会收到NoClassDefFoundError或者别的古怪的异常,而不是真正的错误信息

异常记录是日志记录的最重要的职责之一,不过很多程序员都倾向于把记录日志当作处理异常的方式。他们通常只是返回默认值(一般是null,0或者空字符串),装作什么也没发生一样。还有的时候,他们会先记录异常,然后把异常包装了下再抛出去:

log.error("IO exception", e);
throw new CustomException(e);
로그인 후 복사

这样写通常会把栈信息打印两次,因为捕获了MyCustomException异常的地方也会再打印一次。日志记录,或者包装后再抛出去,不要同时使用,否则你的日志看起来会让人很迷惑。

如果我们真的想记录日志呢?由于某些原因(大概是不读API和文档?),大约有一半的日志记录我认为是错误的。做个小测试,下面哪个日志语句能够正确的打印空指针异常?

try {
    Integer x = null;
    ++x;
} catch (Exception e) {
    log.error(e); //A
    log.error(e, e); //B
    log.error("" + e); //C
    log.error(e.toString()); //D
    log.error(e.getMessage()); //E
    log.error(null, e); //F
    log.error("", e); //G
    log.error("{}", e); //H
    log.error("{}", e.getMessage()); //I
    log.error("Error reading configuration file: " + e); //J
    log.error("Error reading configuration file: " + e.getMessage()); //K
    log.error("Error reading configuration file", e); //L
}
로그인 후 복사

很奇怪吧,只有G和L(这个更好)是对的!A和B在slf4j下面根本就编译不过,其它的会把栈跟踪信息给丢掉了或者打印了不正确的信息。比如,E什么也不打印,因为空指针异常本身没有提供任何异常信息而栈信息又没打印出来 .记住,第一个参数通常都是文本信息,关于这个错误本身的。不要把异常信息给写进来,打印日志后它会自动出来的,在栈信息的前面。不过想要打印这个,你当然还得把异常传到第二个参数里面才行。

日志应当可读性强且易于解析

现在有两组用户对你的日志感兴趣:我们人类(不管你同不同意,码农也是在这里边),还有计算机(通常就是系统管理员写的shell脚本)。日志应当适合这两种用户来理解。如果有人在你后边看你的程序的日志却看到了这个:

那你肯定没听从我的建议。日志应该像代码一样易于阅读和理解。

另一方面,如果你的程序每小时就生成了半GB的日志,没有谁或者任何图形化的文本编辑器能把它们看完。这时候我们的老家伙们,grep,sed和awk这些上场的时候就来了。如果有可能的话,你记录的日志最好能让人和计算机都能看明白 ,不要将数字格式化,用一些能让正则容易匹配的格式等等。如果不可能的,用两个格式来打印数据:

log.debug("Request TTL set to: {} ({})", new Date(ttl), ttl);
// Request TTL set to: Wed Apr 28 20:14:12 CEST 2010 (1272478452437)
final String duration = DurationFormatUtils.formatDurationWords(durationMillis, true, true);
log.info("Importing took: {}ms ({})", durationMillis, duration);
//Importing took: 123456789ms (1 day 10 hours 17 minutes 36 seconds)
로그인 후 복사

计算机看到”ms after 1970 epoch“这样的的时间格式会感谢你的,而人们则乐于看到”1天10小时17分36秒“这样的东西。

总之,日志也可以写得像诗一样优雅,如果你愿意琢磨的话。

위 내용은 Java 로그를 사용하여 시를 작성하는 방법에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Java Spring 인터뷰 질문 Java Spring 인터뷰 질문 Aug 30, 2024 pm 04:29 PM

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

PHP : 웹 개발의 핵심 언어 PHP : 웹 개발의 핵심 언어 Apr 13, 2025 am 12:08 AM

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 ​​있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

Java의 날짜까지의 타임스탬프 Java의 날짜까지의 타임스탬프 Aug 30, 2024 pm 04:28 PM

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

PHP vs. Python : 차이점 이해 PHP vs. Python : 차이점 이해 Apr 11, 2025 am 12:15 AM

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

캡슐의 양을 찾기위한 Java 프로그램 캡슐의 양을 찾기위한 Java 프로그램 Feb 07, 2025 am 11:37 AM

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

PHP vs. Python : 핵심 기능 및 기능 PHP vs. Python : 핵심 기능 및 기능 Apr 13, 2025 am 12:16 AM

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP 대 기타 언어 : 비교 PHP 대 기타 언어 : 비교 Apr 13, 2025 am 12:19 AM

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

See all articles