이러한 아이디어와 코드를 작성, 내 동료는 복사 및 붙여 넣기 할 수있는 프로그래머 생각하지 않습니다

머리말

최근 12 월에 수요의 완성 된 버전이 코드를 생각하는 깊이가 충분하지 않습니다, 쓰기 요약하면, 나는 매일 멀티 사고, 멀티 포인트 요약, 어서 당신이 코드를 작성 바랍니다! 거기에 뭔가 잘못이지만, 또한 희망을 지적 동시에,시.

첫째, 복잡한 논리 조건은 순서를 조정할 수 있습니다, 그것은보다 효율적인 절차를합니다.

비즈니스 수요가이이라고 가정 : 회원, 처음으로 도착, 당신은 당신이 노트 감사 보내야합니다. 그들이 생각하지 않는 경우, 직접 코드를 작성

if(isUserVip && isFirstLogin){
    sendMsg();
}
复制代码

오 개 요청의 총을 가정 할 때, isUserVip 요청을 통해 isFirstLogin 1에 의해 세 가지 요청이 있습니다. 위의 코드 그래서 수는 isUserVip 횟수가 isFirstLogin이 아니라 다음을 수행 세 배, 수행 다섯 가지입니다 :

그것에 대해 순서가 isUserVip 및 isFirstLogin 조정하면?

if(isFirstLogin && isUserVip ){
    sendMsg();
}
复制代码

실행 시간 IsFirstLogin하는 횟수는 다음과 같은 1 isUserVip 행한다 5 배 :

지앙 닫아 그것을보다 효율적으로 프로그램이 있는지?

둘째, 프로그램이 실수로 만들어 불필요한 객체입니다.

밤나무를 들어, 사용자가 회원 기간에 다음과 같은 코드에 일반적으로 유사 여부를 결정 :

//判断用户会员是否在有效期
public boolean isUserVIPValid() {
  Date now = new Date();
  Calendar gmtCal = Calendar.getInstance();
  gmtCal.set(2019, Calendar.JANUARY, 1, 0, 0, 0);
  Date beginTime = gmtCal.getTime();
  gmtCal.set(2020, Calendar.JANUARY, 1, 0, 0, 0);
  Date endTime= gmtCal.getTime();
  return now.compareTo(beginTime) >= 0 && now.compareTo(endTime) <= 0;
}

复制代码

그러나, 각 호출 방법은 일정 및 날짜 객체를 생성 isUserVIPValid. 사실 그것은, 새로운 날짜뿐만 아니라, 다른 객체가 같은, 우리는 할 수 전역 변수를 추출 , 불필요한 객체를 생성 방지하기 위해 다음과 같이하여 프로그램의 효율을 향상 :

public class Test {

    private static final Date BEGIN_TIME;
    private static final Date END_TIME;
    static {
        Calendar gmtCal = Calendar.getInstance();
        gmtCal.set(2019, Calendar.JANUARY, 1, 0, 0, 0);
        BEGIN_TIME = gmtCal.getTime();
        gmtCal.set(2020, Calendar.JANUARY, 1, 0, 0, 0);
        END_TIME = gmtCal.getTime();
    }

    //判断用户会员是否在有效期
    public boolean isUserVIPValid() {
        Date now = new Date();
        return now.compareTo(BEGIN_TIME) >= 0 && now.compareTo(END_TIME) <= 0;
    }
}
复制代码

데이터베이스를 쿼리 할 때 셋째, 당신은 데이터를 확인하지 이하 있나요?

우리 모두 알다시피, 데이터, 특히 많은 양의 라이브러리는 더 많은 시간이 소요되는 작업입니다 확인. 우리가 취할 필요가 같이 따라서, 쿼리 DB는 담요에 필요가 없습니다.

이 비즈니스 시나리오를 가정하면 이것이다 : 사용자가 쿼리의 멤버인지 여부. 본 적이 구현 코드이다. . .

List<Long> userIds = sqlMap.queryList("select userId from user where vip=1");
boolean isVip = userIds.contains(userId);
复制代码

왜 먼저 발견 한 후이 멤버인지 여부를 결정하는 것은이 useId, useId을 포함할지 여부를 결정? 직접 SQL로 통과 사용자 ID, 그것은 냄새하지 않는 이유는 무엇입니까? 으로는 다음과 같습니다 :

Long userId = sqlMap.queryObject("select userId from user where userId='userId' and vip='1' ")
boolean isVip = userId!=null;
复制代码

사실, 따로 쿼리에서 중복 데이터 등을 방지하기 위해 데이터베이스를 확인, 과거에 전달되는, 당신은 또한 수 있습니다 특정 필드를 선택 장소에 select *프로그램이 더 효율적.

넷째, 그것의 주요 흐름에 영향을 미칠 수없고, 코드 알림 클래스의 라인을 추가합니다.

비즈니스 프로세스는이 가정 : 사용자가 팬을 알리기 위해 문자 메시지를 추가 할 로그인 할 필요가있을 때. 으로 다음되는 구현 프로세스를 생각하기 쉽습니다 :

가정 제공 sendMsgNotify 서비스 시스템이 걸려 , 또는 sendMsgNotify 실패를 호출 한 후 사용자 로그인에 실패했습니다. . .

주 착륙 절차에 대한 알림 기능 리드는 분명히, 현명 페니와 파운드 바보 사용할 수 없습니다. 그리고 너무 먹을 낚시를 할 수있는 방법은 없습니다? 예 인터페이스에 문자 메시지를 캡처 예외 처리 , 또는 다른 스레드 비동기 처리를 열고 다음과 같이 :

다운 그레이드 인터페이스를 중지하고 주요 흐름에 대처하는 최선의 방법을 생각에 영향을 미칠 것입니다 여부를 고려해야 할 때 따라서, 우리는 알림 클래스 그렇게하지 않은 전공을 추가 할 수 있습니다.

사용이 비교 동일 같은 V. 지속적인 방출 또는 왼쪽의 값을 결정, 후각 NULL 포인터를 들고.

NullPointException은 우리가 코드를 작성할 때, 당신은 두 번 생각 할 수 있습니다 그들이 쓰기 전에, 낮은 수준의 널 포인터 문제를 피하려고, 자바 세계에서 일반적이었다.

예를 들어, 다음과 같은 비즈니스 시나리오, 사용자가 구성원인지, 우리는 종종 다음과 같은 코드를 볼 수 있습니다 결정하기 :

boolean isVip = user.getUserFlag().equals("1");
复制代码

프로덕션 환경에 코드 줄을하자, 내가 다시 볼 때, 그것은있을 수 있습니다 왕이 그 희미 한 빛에 널 포인터 버그. user.getUserFlag ()가 null이 될 수 있기 때문에 분명히, 이것은 널 포인터 예외가 발생할 수 있습니다.

어떻게 널 포인터 문제를 방지하려면? 다음과 같이 왼쪽에 상수 1, 친구가 될 수 :

boolean isVip = "1".equals(user.getUserFlag());
复制代码

여섯째, 당신의 비즈니스에 중요한 코드는 로그 호위를 가지고?

주요 사업 코드 곳이 충분해야 로그 에스코트.

예를 들어 : 당신은 몇 만 달러를 설정, 전송 사업을 달성하고 실패 좌회전 후 고객 불만은, 당신은 곤경의 종류의 처지에 대해 생각, 로그에 인쇄하지 않은,하지만 당신은 아무것도하지 않고 . . .

그래서, 송금 업무는 것입니다 이러한 로그 필요 를? 메소드가 호출되기 전에 적어도, 매개 변수는 다음과 같이 당신이 그것에 대해 비정상적인 캡처하고 비정상적인 로그에 관련된 인쇄해야, 그것은 필요로 인쇄 인터페이스 호출이 필요합니다 :

public void transfer(TransferDTO transferDTO){
    log.info("invoke tranfer begin");
    //打印入参
    log.info("invoke tranfer,paramters:{}",transferDTO);
    try {
      res=  transferService.transfer(transferDTO);
    }catch(Exception e){
     log.error("transfer fail,cifno:{},account:{}",transferDTO.getCifno(),
     transferDTO.getaccount())
     log.error("transfer fail,exception:{}",e);
    }
    log.info("invoke tranfer end");
    }
复制代码

충분한 로그를 인쇄 할뿐만 아니라, 우리는 또한주의 할 필요가 있다는 것입니다 로그 레벨이 혼동을 사용하지 않는 로그에이 정보를 인쇄하지 않습니다,하지만 당신은 나쁜에 문제 해결 문제에 늦은 밤 오류 수준, 경보 알림 당신을 인쇄.

세븐, 더 많은 기능에 대한 행의 수는, 그것을 최적화 여부 작은 기능으로 나눌 수있다?

우리가 예전의 코드를 유지하는 경우, 종종 Tuotuo 코드, 일부 참조 줄이나 수천의 기능 수백 , 그들에게 더 어려운 읽어 보시기 바랍니다.

다음 코드가 지금 가정

public class Test {
    private String name;
    private Vector<Order> orders = new Vector<Order>();

    public void printOwing() {
        //print banner
        System.out.println("****************");
        System.out.println("*****customer Owes *****");
        System.out.println("****************");

        //calculate totalAmount
        Enumeration env = orders.elements();
        double totalAmount = 0.0;
        while (env.hasMoreElements()) {
            Order order = (Order) env.nextElement();
            totalAmount += order.getAmout();
        }

        //print details
        System.out.println("name:" + name);
        System.out.println("amount:" + totalAmount);
    }
}
复制代码

기능 후 작은, 단일 기능으로 나누어 :

public class Test {
    private String name;
    private Vector<Order> orders = new Vector<Order>();

    public void printOwing() {

        //print banner
        printBanner();
        //calculate totalAmount
        double totalAmount = getTotalAmount();
        //print details
        printDetail(totalAmount);
    }

    void printBanner(){
        System.out.println("****************");
        System.out.println("*****customer Owes *****");
        System.out.println("****************");
    }

    double getTotalAmount(){
        Enumeration env = orders.elements();
        double totalAmount = 0.0;
        while (env.hasMoreElements()) {
            Order order = (Order) env.nextElement();
            totalAmount += order.getAmout();
        }
        return totalAmount;
    }

    void printDetail(double totalAmount){
        System.out.println("name:" + name);
        System.out.println("amount:" + totalAmount);
    }
    
}
复制代码

너무 기능과 일부 의견이 사람들이 이해하도록하기 위해 필요 , 코드 사용을 기능 단위로 절단하는 것은 명확하고 간략하고 명확하게 정의 된 함수 이름 기능을 고려,이 코드가 더 우아하게됩니다.

여덟, 등등 붉은 피부와 같은 일부 변수는, 더 나은 것인지의 구성을 확인합니다.

제품에 대한 수요가 빨간 봉투를 제기하면, 크리스마스, 크리스마스 붉은 피부, 등등 봄 축제, 붉은 피부와 관련.

당신이 죽은를 제어하는 ​​코드를 작성하는 경우, 다음 코드와 유사있을 수 있습니다 :

if(duringChristmas){
   img = redPacketChristmasSkin;
}else if(duringSpringFestival){
   img =  redSpringFestivalSkin;
}
......
复制代码

등불 축제에서, 갑자기 다른 여동생 조작 아이디어에 붉은 등불은 피부 관련, 코드, 수정하지 않을이 시간을 재 출시 할 때 경우?

처음부터 구성 테이블 붉은 피부를 달성하기 위해, 붉은 피부는 그것의 구성을 할 것인가? , 붉은 피부를 바꾸기 만 잘 테이블 데이터를 수정합니다.

나인, 초과 수입 부문, 지역 변수, 대한 언급이 삭제되지 않도록한다

코드를 사용에는 수입 클래스가없는 것을 알 경우,하지를 삭제하는 등 지역 변수에 사용되는 다음 :

그것을 사용하지 않을 경우이 더 부드러운을 유지하는 것, 그것은 빈티지 Nver 아니라, 제거, 로컬 변수를 참조하지 않습니다. 여전히 아직 Haozhe 자원이라고 함께 컴파일됩니다.

큰 테이블을 쿼리 할 때 열은 인덱스를 인상 할 것인지, 당신은 SQL 인덱스 일을 이동합니다.

데이터 테이블의 쿼리 많은 양의, 우리는 세 가지를 확인해야합니다 :

  • 귀하의 테이블은 인덱스를 구축
  • 인덱스 히트 여부를 귀하의 SQL 쿼리
  • 당신의 SQL이 최적화 여지가

일반적으로, 데이터의 양이 10 만 개 이상의 테이블, 테이블에 인덱스를 추가하는 것이 좋습니다. 어떤 상황에서, 인덱스가 실패 할 것인가? 이러한 실패로 이어질 인덱스 열 인덱스를 계산하는 등의 와일드 카드, 등을 포함한다. 관심있는 친구들은 나의 기사를 볼 수 있습니다. 필요한 백엔드 프로그래머 : 인덱스의 최고 열 질환의 실패

XI, 당신의 방법은 결국 그것의 빈 세트 또는 null을 반환해야합니까?

이 널 (null)을 반환하는 경우, 호출자는 널 포인터 예외가 발생할 수 있습니다 때를 감지하는 것을 잊지. 그것은 문제를 제거, 빈 집합을 반환합니다.

이 결과 집합을 반환하는 경우 MyBatis로 쿼리가 비어있는 경우도 오히려 널 (null)보다는 빈 집합을 반환합니다.

성신

public static List<UserResult> getUserResultList(){
    return Collections.EMPTY_LIST;
}
复制代码

열두은 초기화 세트의 크기를 지정하려고

알리는 개발 매뉴얼을 권장

지도의 요소의 수는 15에 대해 저장할 것을 가정하면, 다음과 같이 대부분의 말로

 //initialCapacity = 15/0.75+1=21
 Map map = new HashMap(21);
复制代码

XIII, 쿼리 데이터베이스, 데이터가 너무 많은 고려 배치를 반환합니다.

테이블이 상태를 업데이트 100,000 주문 데이터가 가정이 아닌 1 회 모든 주문이 일괄 적으로 업데이트되지 않습니다 쿼리합니다.

반례 :

List<Order> list = sqlMap.queryList("select * from Order where status='0'");
for(Order order:list){
  order.setStatus(1);
  sqlMap.update(order);  
}
复制代码

성신 :

Integer count = sqlMap.queryCount(select count(1) from Order where status ='0');
while(true){
    int size=sqlMap.batchUpdate(params);
    if(size<500){
        break;
    }
}
复制代码

당신이 계정에 인터페이스 멱등을 경우 넷째, 상황을 복잡?

전원 등은 무엇 섹스에? 일단 반복하면 같은 결과가 있어야 자체 자원에 대한 자원을 요청합니다. 즉, 다수의 실행 중은 자원 자체를 오른쪽에 의해 발생 된 충격 한번 동일한 영향을 행 하였다.

왜 우리는 멱등 필요합니까?

  • 주문을 제출 연속 APP의 수에 사용자가 클릭, 당신은 더 많은 주문을 생성 할 수 없습니다
  • 사용자가 네트워크 카드 때문에, 연속 클릭 메시지를 보내려면받는 사람이 같은 소식을 반복받을 수 없습니다.

비즈니스 시나리오가 가정 :

사용자가 다운로드 버튼을 클릭, 시스템은 파일을 다운로드 사용자가 파일의 존재를 다운로드하라는 메시지가 표시됩니다 다운로드 다시 클릭하기 시작합니다.

이것을 실현되는 일부 사람들이있다 :

Integer count = sqlMap.selectCount("select count(1) from excel where state=1");
if(count<=0){
    Excel.setStatus(1);
    updateExcelStatus();
    downLoadExcel();
}else{
    "文件正在下载中"
}
复制代码

우리는이 요청이 올있을 수 있습니다 어떤 문제를 볼 수 있습니까?

구현 과정 :

  • 첫 번째 단계는하는 쿼리 파일로 다운로드되지 않습니다.
  • 두 번째 단계는, B 쿼리 파일로 다운로드되지 않습니다.
  • 세 번째 단계, A는 파일을 다운로드를 시작합니다
  • 파트 IV는 B 파일을 다운로드를 시작

이 개 파일을 다운로드하는 동안 분명히, 그것은 문제입니다. 그것의 적절한 구현?

if(updateExcelStatus(1){
    downLoadExcel(); 
}else{
    "文件正在下载中"
}
复制代码

다섯째, 개인 생성자와 툴을 강화,이 미야하지 않는 이유는 무엇입니까?

정적 방법이 있습니다 수업 방법 론적 도구는 직접 클래스에 의해 호출 할 수 있습니다. 그러나 일부 발신자가 다음 주제는 첫 번째 인스턴스를 호출 할 수 있으며, 이것은 좋지 않다. 이런 상황을 방지하는 방법, 툴의 상태를 제어에 도달 할 수 있도록 개인 생성자를 추가

public class StringUtis{
       private StringUtis(){} ///私有构造类,防止意外实例出现
       public static bool validataString(String str){
           
       }
}
复制代码

XVI 기본적으로 변경되지 않은 사용자 데이터, 캐시, 성능은 개선 여부

당신은 데이터의 각에 도착하는 데이터베이스 여러 번에 쿼리 인터페이스를 필요로한다고 가정하고이 데이터를 기반으로 다양한 분류 작업 등의 작업을 아래로 호랑이처럼 맹렬한의이 시리즈는, 인터페이스 성능이 좋은 충분하지 않았다. 이들의 라이브 목록 : 같은 일반적인 응용 프로그램 시나리오.

그럼, 어떻게 그것을 최적화? 당신이 종류의 실시간 변경 데이터의, 앞으로 예약 된 작업을 넣어 DB, 이러한 사용자의 나이와 같은 데이터를 확인 DB 캐시에서 끌어 데리고 계속 데이터의 부분의 분석, 캐시로 직접 이동합니다.

그래서,이 점은 그입니다 생각, 적절한 타이밍에, 캐시의 적절한 사용.

추가 할 수 ...

개인 공공 번호

  • 당신이 소년 학습의 사랑이 있다면, 내가 함께 토론 학습, 국민 수에 집중할 수 있습니다.
  • 이 문서가 바로 이곳 아니라고 느끼는 경우에, 코멘트 수있는 것, 나는 공공의 수, 나, 우리는 카자흐스탄을 진행 함께 공부합니다 개인 채팅에 대해 우려 할 수 있습니다.

추천

출처juejin.im/post/5dfe2e72518825125f39a2de