René's URL Explorer Experiment


Title: 아이템 76 : 가능한 한 실패 원자적으로 만들라 · Study-2-Effective-Java · Discussion #176 · GitHub

Open Graph Title: 아이템 76 : 가능한 한 실패 원자적으로 만들라 · Study-2-Effective-Java · Discussion #176

X Title: 아이템 76 : 가능한 한 실패 원자적으로 만들라 · Study-2-Effective-Java · Discussion #176

Description: 아이템 76 : 가능한 한 실패 원자적으로 만들라

Open Graph Description: 0. 들어가며 이 아이템이 말하는 바는 짧고 명확해서, 아이템 이름만 봐도 명확하게 보입니다. 저는 “가능한 한 실패 원자적으로 만들라” 라고 핵심 키워드를 꼽았습니다. 가능한 : 반드시 해야한다는건 아니지만, 실패 원자적 : 실패 상황에도 정상적인 흐름으로 흘러가게 하라. 그런데 실패 원자적이라는 말이 확 와닿지는 않는데요. 이를 책에서는 다음과 같...

X Description: 0. 들어가며 이 아이템이 말하는 바는 짧고 명확해서, 아이템 이름만 봐도 명확하게 보입니다. 저는 “가능한 한 실패 원자적으로 만들라” 라고 핵심 키워드를 꼽았습니다. 가능한 : 반드시 해야한다는건 아니지만, 실패 원자적 : 실패 상황에도 정상적인 흐름으로 흘러가게 하라. 그런데 실패 원자적이라는 말이 확 와닿지는 않는데요. 이를 책에서는 다음과 같...

Opengraph URL: https://github.com/orgs/Study-2-Effective-Java/discussions/176

X: @github

direct link

Domain: patch-diff.githubusercontent.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"QAPage","mainEntity":{"@type":"Question","name":"아이템 76 : 가능한 한 실패 원자적으로 만들라","text":"

0. 들어가며

\n

이 아이템이 말하는 바는 짧고 명확해서, 아이템 이름만 봐도 명확하게 보입니다.

\n

저는 “가능한실패 원자적으로 만들라” 라고 핵심 키워드를 꼽았습니다.

\n\n

그런데 실패 원자적이라는 말이 확 와닿지는 않는데요.
\n이를 책에서는 다음과 같이 말합니다.

\n
\n

호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.

\n
\n

어떻게 원자적으로 만들 수 있는지, 해야하는 상황과 아닌 상황은 어떻게 구분하는지 아래에서 알아보겠습니다.

\n

1. 실패 원자적으로 만드는 방법

\n

1.1 불변

\n

사실, 불변객체인 경우에는 실패원자적으로 만들기가 쉽습니다.

\n

왜냐하면, 불변 객체인 경우에는 상태를 변경할때 새 객체를 생성하기 때문입니다.

\n

그래서 실패하더라도 현재 객체는 변경되지 않기 때문에, 자연스럽게 실패 원자성을 가지게 되죠.

\n
record ImmutablePerson(String name, int age) {\n\t\n\tpublic ImmutableName changeAge(int newAge) {\n\t\tif (newAge <= 0) throw new IllegalArgumentException();\n\t\treturn new ImmutableName(this.name, newAge);\n\t}\n}
\n

위와 같은 불변 객체는 상태를 변경할때 새로운 객체를 반환합니다.

\n

만약 changeAge를 호출할때 0이하의 나이를 주는 경우에 예외가 발생하는데요.

\n

이 경우에는 해당 메서드 자체만 실패하는 것이지, 기존 객체는 정상적인 상태가 유지됩니다.

\n

1.2 가변

\n

가변인 경우는 조금 더 복잡할 수 밖에 없는데요.

\n

미리 검증을 통해 상태 변경을 막거나, 변경을 되돌리는 작업이 있어야 하기 때문입니다.

\n

그래서 책에서는 제시하는 가변 객체 실패 원자성 유지 방법은 아래 4가지 입니다.

\n
    \n
  1. 상태 변경에 앞서 매개변수 유효성을 검사하는 것\n
      \n
    • 아이템 49와 연관있음
    • \n
    \n
  2. \n
  3. 실패 가능성이 있는 코드를, 상태 변경 로직보다 앞에 배치하는 것
  4. \n
  5. 복사본에서 작업 수행 후, 성공하면 원래 객체와 교체하는 방법
  6. \n
  7. 실패를 가로채는 복구코드를 작성하여, 작업 전 상태로 되돌리는 방법\n
      \n
    • DB트랜잭션 등
    • \n
    \n
  8. \n
\n

1) 상태 변경에 앞서 매개변수 유효성을 검사하는 것

\n

이 항목은 사실 위의 불변 예제와 거의 비슷할 것 입니다.

\n

다만, 차이점은 새로운 객체를 반환하는것이 아니라 자기 자신의 상태를 변경한다는 점이겠죠.

\n
class MutablePerson {\n\tprivate String name;\n\tprivate int age;\n\n\tpublic MutableName(String name, int age) { \n\t\tthis.name = name;\n\t\tthis.age = age;\n\t}\n\t\n\tpublic String getName() {\n\t\treturn this.name;\n\t}\n\n\tpublic String getAge() {\n\t\treturn this.age;\n\t}\n\n\tpublic void changeAge(int newAge) {\n\t\tif (newAge <= 0) throw new IllegalArgumentException();\n\t\t\n\t\tthis.age = newAge;\n\t}\n}
\n

위 처럼, 상태 변경 전에 매개변수 유효성을 검증하고 예외를 발생시켜 원자성을 유지할 수 있습니다.

\n

2) 실패 가능성이 있는 코드를, 상태 변경 로직보다 앞에 배치하는 것

\n
class Processor {\n\t// ...\n\n\tpublic void process(UserCommand command) {\n\t\tthis.status = Status.SUCCESS;\n\n\t\tlog.info(\"[{}] run command\", command.getUser()) // command 가 null 이라면??\n\t\tthis.run(command.getCommand());\n\t}\n\n\tprivate void run(Command command) {\n\t\t// ...\n\t}\n}\n\n-----\n// 이렇게 바꾸면 이전보다는 나음\n\nclass Processor {\n\t// ...\n\n\tpublic void process(UserCommand command) {\n\t\tlog.info(\"[{}] run command\", command.getUser())\n\t\tthis.run(command.getCommand());\n\n\t\tthis.status = Status.SUCCESS;\n\t}\n\n\tprivate void run(Command command) {\n\t\t// ...\n\t}\n}
\n

위쪽 예제는 command가 null일때 NullPointerException이 발생합니다.

\n

그러면 상태는 SUCCESS인 상태로 멈춰버리게 되는데요.

\n

하지만, 상태 변경로직보다 앞에 둔다면 실패했는데 SUCCESS라고 되진 않을 것 입니다.

\n

2. 실패 원자성 구현은 필수?

\n

하지만, 항상 실패 원자성을 구현해야하는건 아니라고 하는데요.

\n

2.1 할 수 없는 경우 & 안해도 되는 경우

\n

만약 멀티 스레드에서의 경쟁 상태(Race condition)에 놓였을 경우에는 해결하기 힘들겠죠.

\n

\"image\"

\n\n

여러 경우의 수를 고려해야하겠지만, 위와 같이 대상이 많지 않은 경우라면 괜찮을 것 입니다.

\n

하지만 아래와 같이 복잡하고 대상이 많은 경우라면 어떨까요?

\n

\"image\"

\n

이런 상황에서 원자성 달성을 위한 로직을 개발하는건 비용이 크고 복잡할 것 입니다.

\n

그리고 책에서는 문제가 무엇인지 아록 나면 실패 원자성을 공짜로 얻을 수 있는 경우가 있다고 하는데요.

\n

위 상황에서의 문제는 여러 스레드가 한 데이터에 접근하면서 발생한 문제입니다.

\n

이와 같은 경우, ‘임계 구역’을 설정하면 해결될 수 있는 상황이기도 하죠.

\n

이렇게 하면 큰 변경없이도 실패 원자성을 얻을 수 있게 됩니다.

\n

3. 실패 원자성 명세

\n

실패 원자성 여부는 특정 메서드를 사용하는 입장에서 중요한 정보입니다.

\n

그래서 책에서는 메서드 명세에 기술되어있는 예외는 발생하더라도 원자성을 지켜줘야한다고 합니다.

\n

그리고 원자성을 지켜주지 못한다면, 예외 발생시 어떤 상태가 되는지를 명시해야한다고 하는데요.

\n

하지만 이런건 이상적인 얘기일 뿐, 잘 지켜지지는 않는다고 합니다.

","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"
\n

이런건 이상적인 얘기일 뿐, 잘 지켜지지는 않는다고 합니다.

\n
\n

논리적 관점과 물리적 관점이 맞지않는 그런 상황인가 봅니다 ㅎㅎ

\n

\"image\"

\n

구현부 위 아래로 바꾸는건 위트있는 코드 같군여 😄

\n

이펙자바가 이제 끝시점으로 달려가고 있다 보니, 여러 개념이 중첩되고는 하는 것 같습니다.
\n꽤 많은 아이템에서 다뤄지는 내용 중 하나를 꼽아 저도 아이템을 제안 해 보고싶네요.

\n
왠만하면 불변으로 만들어라\n
","upvoteCount":1,"url":"https://github.com/orgs/Study-2-Effective-Java/discussions/176#discussioncomment-5441852"}}}

route-pattern/_view_fragments/Voltron::DiscussionsFragmentsController/show/orgs/:org/:discussion_number/discussion_layout(.:format)
route-controllervoltron_discussions_fragments
route-actiondiscussion_layout
fetch-noncev2:f4958106-b005-9d18-fbaa-cd6df16344d1
current-catalog-service-hash9f0abe34da433c9b6db74bffa2466494a717b579a96b30a5d252e5090baea7be
request-idB89A:382E6F:5B40C8:80C4F2:696E5895
html-safe-nonce60d2715bae7c8777ac36ce0142907a071df2e2d8b71e1c149201927a3c667d81
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCODlBOjM4MkU2Rjo1QjQwQzg6ODBDNEYyOjY5NkU1ODk1IiwidmlzaXRvcl9pZCI6IjM0ODI4NjYxMTExMTc5NDA4ODUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ==
visitor-hmac9ad931978901c82599df180b338b610bf2fb4894cb9badbeee7684d6e5946ef1
hovercard-subject-tagdiscussion:5002332
github-keyboard-shortcutsrepository,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/discussions_fragments/discussion_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/Voltron::DiscussionsFragmentsController/show/orgs/Study-2-Effective-Java/176/discussion_layout
twitter:imagehttps://opengraph.githubassets.com/12df992beeec6e2df475a191e061f5701406a50c041e48714b879081b88ee40c/orgs/Study-2-Effective-Java/discussions/176
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/12df992beeec6e2df475a191e061f5701406a50c041e48714b879081b88ee40c/orgs/Study-2-Effective-Java/discussions/176
og:image:alt0. 들어가며 이 아이템이 말하는 바는 짧고 명확해서, 아이템 이름만 봐도 명확하게 보입니다. 저는 “가능한 한 실패 원자적으로 만들라” 라고 핵심 키워드를 꼽았습니다. 가능한 : 반드시 해야한다는건 아니지만, 실패 원자적 : 실패 상황에도 정상적인 흐름으로 흘러가게 하라. 그런데 실패 원자적이라는 말이 확 와닿지는 않는데요. 이를 책에서는 다음과 같...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
Nonef68b42d371252b0f236260d6234f4304a806fe5ac43d59faa21fb59d80df103b
turbo-cache-controlno-preview
octolytics-dimension-user_id120388640
octolytics-dimension-user_loginStudy-2-Effective-Java
octolytics-dimension-repository_id577325341
octolytics-dimension-repository_nwoStudy-2-Effective-Java/Effective-Java
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id577325341
octolytics-dimension-repository_network_root_nwoStudy-2-Effective-Java/Effective-Java
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release6b74bc8dbcd10b5d69fd9ee9d2cfdc8b35e18a4c
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#start-of-content
https://patch-diff.githubusercontent.com/
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Forgs%2FStudy-2-Effective-Java%2Fdiscussions%2F176
Study-2-Effective-Javahttps://patch-diff.githubusercontent.com/Study-2-Effective-Java
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Forgs%2FStudy-2-Effective-Java%2Fdiscussions%2F176
Sign up https://patch-diff.githubusercontent.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fdiscussions_fragments%2Fdiscussion_layout&source=header-repo&source_repo=Study-2-Effective-Java%2FEffective-Java
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Effective-Java-Study https://patch-diff.githubusercontent.com/Study-2-Effective-Java
Overview https://patch-diff.githubusercontent.com/Study-2-Effective-Java
Repositories https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/repositories
Discussions https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions
Projects https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/projects
Packages https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/packages
People https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/people
Overviewhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java
Repositorieshttps://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/repositories
Discussionshttps://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions
Projectshttps://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/projects
Packageshttps://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/packages
Peoplehttps://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/people
Answered https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5441852
Irisation23https://patch-diff.githubusercontent.com/Irisation23
jinan159 https://patch-diff.githubusercontent.com/jinan159
3. 과제https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions/categories/3-%EA%B3%BC%EC%A0%9C
아이템 76 : 가능한 한 실패 원자적으로 만들라 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#top
jinan159 https://patch-diff.githubusercontent.com/jinan159
Answered https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5441852
Irisation23https://patch-diff.githubusercontent.com/Irisation23
Return to tophttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#top
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
jinan159 https://patch-diff.githubusercontent.com/jinan159
Mar 25, 2023 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussion-5002332
https://user-images.githubusercontent.com/45728407/227704715-587e4b80-36ee-4a6f-a7b2-b4b28f532ae4.png
https://user-images.githubusercontent.com/45728407/227704724-6221cfb8-7923-4488-9fe8-d5dc993f089d.png
Give feedback.https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Irisation23 https://patch-diff.githubusercontent.com/Irisation23
Mar 27, 2023 https://github.com/orgs/Study-2-Effective-Java/discussions/176#discussioncomment-5441852
View full answer https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5441852
Oldest https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions/176?sort=old
Newest https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions/176?sort=new
Top https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions/176?sort=top
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
Irisation23 https://patch-diff.githubusercontent.com/Irisation23
Mar 27, 2023 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5441852
https://user-images.githubusercontent.com/53285909/227965171-f24dce47-8047-4db9-9a92-4b1b5abfaca8.png
Give feedback.https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/chikeem90
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
chikeem90https://patch-diff.githubusercontent.com/chikeem90
Apr 4, 2023 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5520059
Give feedback.https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/corock
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
corockhttps://patch-diff.githubusercontent.com/corock
Apr 4, 2023 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176#discussioncomment-5520085
Give feedback.https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
jinan159https://patch-diff.githubusercontent.com/jinan159
Sign up for freehttps://patch-diff.githubusercontent.com/join?source=comment-repo
Sign in to commenthttps://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Forgs%2FStudy-2-Effective-Java%2Fdiscussions%2F176
📚 3. 과제 https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions/categories/3-%EA%B3%BC%EC%A0%9C
10장 예외 https://patch-diff.githubusercontent.com/orgs/Study-2-Effective-Java/discussions?discussions_q=label%3A%2210%EC%9E%A5+%EC%98%88%EC%99%B8%22
https://patch-diff.githubusercontent.com/jinan159
https://patch-diff.githubusercontent.com/corock
https://patch-diff.githubusercontent.com/chikeem90
https://patch-diff.githubusercontent.com/Irisation23
https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions/176
https://patch-diff.githubusercontent.com/settings/replies?return_to=1
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.