OOP学习的第二次BLOG

Posted 3starry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OOP学习的第二次BLOG相关的知识,希望对你有一定的参考价值。

褚鑫豪

(1)前言:

  在完成了第四次到第六次的pta题目集作业后,进一步了解熟悉了对类以及对象的的使用。理解并实现类之间关系,类中方法的编写和使用。学会如何在多个类属于聚合关系时,如何去逐层调用不同类中的属性与方法。学会用Array类中自带的排序方法去排序,去简短排序时间。理解封装性的写法以及学会在面对私有属性如何调用。同时学习了正则表达式的部分语法。

  三次作业的题目量都不算多,但是每一次的作业难度都较大,尤其是题目集6的7-1以及题目集4的7-1,皆为迭代了多次之后所呈现出来的题目,需要花大量的时间去完成,个人认为难度较大,涉及的知识点很多,考察范围广。

(2)设计与分析:

题目及4的7-5:

  题目集4的7-1要求我们完成编写一个菜单计价程序,在初步阅读题目要求后,发现题目要求很多,并且是别人迭代了多次之后的题目之后,便没有了动手做下去的动力,但还是逼着自己写了点,但是发现最终无果,而且错误很多,便一直放在那没怎么动,之后在看到一大批人没有去完成后,我更是没有了继续去思考的想法,于是不出意外的以0分收尾。在此之后,也是发现不应该以这样的心态去面对问题,要有着迎难而上的心态,不能看到别人没做那就我也不太想做,毕竟知识是自己的。

题目集5的7-5:

 

类图如下

源码如下:

import java.util.Scanner;

public class Main 
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) 
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            m = input.nextInt();

            if (m < 0) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            System.out.println(date.getNextNDays(m).showDate());
         else if (choice == 2) 
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            n = input.nextInt();

            if (n < 0) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            System.out.println(date.getPreviousNDays(n).showDate());
         else if (choice == 3) 
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) 
                System.out.println(fromDate.getDaysofDates(toDate));
             else 
                System.out.println("Wrong Format");
                System.exit(0);
            
        
        else
            System.out.println("Wrong Format");
            System.exit(0);
                
    


class DateUtil
    Day day;
    
    DateUtil()
        
    
    
    DateUtil (int day,int month, int year)
           this.day = new Day(day, month, year);
    
    
    Day getDay()
        return this.day;
    
    
    void setDay(Day day)
        this.day = day;
    
    
    public boolean checkInputValidity() 
        
        if (getDay().validate() && getDay().getMonth().validate() && getDay().getMonth().getYear().validate())
            return true;
        else
            return false;
    
    
    public boolean compareDates(DateUtil date) 
        if (getDay().getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue())
            return true;
        else if (getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && getDay().getMonth().getValue() > date.getDay().getMonth().getValue())
            return true;
        else if (getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && getDay().getMonth().getValue() > date.getDay().getMonth().getValue() && getDay().getValue() > date.getDay().getValue())
            return true;
        else
            return false;
    
    
    public boolean equalTwoDates(DateUtil date) 
        if (getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue() && getDay().getMonth().getValue() == date.getDay().getMonth().getValue() && getDay().getValue() == date.getDay().getValue())
            return true;
        else
            return false;
    
    
    public String showDate() 
        return getDay().getMonth().getYear().getValue()+"-"+getDay().getMonth().getValue()+"-"+day.getValue();
    
    
    public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
    
        int year = getDay().getMonth().getYear().value;
        int month = getDay().getMonth().value;
        int day = getDay().value;
        for (int i = 0; i < n; i++) 
            day++;
            if (day > getDay().mon_maxnum[getDay().getMonth().value] && !(getDay().getMonth().getYear().isLeapYear())) 
                day = 1;
                month++;
            
           if(getDay().getMonth().getYear().isLeapYear() && getDay().getMonth().value == 2 && day > 29) 
               day = 1;
               month++;
           
           
           if (day > getDay().mon_maxnum[getDay().getMonth().value] && getDay().getMonth().getYear().isLeapYear() && getDay().getMonth().value != 2) 
               day = 1;
               month++;
           
           if (month > 12) 
               month = 1;
               year++;
           
            getDay().getMonth().value = month;
            getDay().getMonth().getYear().setValue(year);
        
        return new DateUtil(year, month, day);
    
    
    public DateUtil getPreviousNDays(int n) 
        int flag = 0;
        while(n != 0) 
            if (getDay().getValue() > n) 
                getDay().value -= n;
                flag++;
            
            else 
                n = n - getDay().value;
                getDay().getMonth().monthReduction();
                if (getDay().getMonth().getValue() == 0) 
                    getDay().getMonth().resetMax();
                    getDay().getMonth().getYear().yearReduction();
                    
                if (getDay().getMonth().getValue() == 2 && getDay().getMonth().getYear().isLeapYear())
                    getDay().value = 29;
                else
                    getDay().value = getDay().mon_maxnum[getDay().getMonth().getValue()];
            
            for (int i = getDay().getMonth().getValue(); n > getDay().mon_maxnum[i]; i--) 
                if (i == 2 && getDay().getMonth().getYear().isLeapYear())
                    n -= 29;
                else
                    n -= getDay().mon_maxnum[i];
                getDay().getMonth().monthReduction();
                if (getDay().getMonth().getValue() == 0) 
                    getDay().getMonth().resetMax();
                    getDay().getMonth().getYear().yearReduction();
                    i = 13;
                    
                if (getDay().getMonth().getValue() == 2 && getDay().getMonth().getYear().isLeapYear())
                    getDay().value = 29;
                else
                    getDay().value = getDay().mon_maxnum[getDay().getMonth().getValue()];
            
            if (getDay().value > n && flag != 1) 
                getDay().value -= n;
                n = 0;
            
            if (flag == 1)
                n = 0;
        
        DateUtil date1 = new DateUtil(getDay().getMonth().getYear().getValue(), getDay().getMonth().getValue(), getDay().value);
        return date1;
    
    
    public int getDaysofDates(DateUtil date) 
        DateUtil dateUtil1 = this;//较小的
        DateUtil dateUtil2 = date;//较大的
        if (this.compareDates(date)) 
            dateUtil1 = date;
            dateUtil2 = this;
        

        int days = 0;
        int leapYearNum = 0;
        
        for (int i = dateUtil1.getDay().getMonth().getYear().getValue(); i < dateUtil2.getDay().getMonth().getYear().getValue(); i++) 
            if (i % 400 == 0 || i % 4 == 0 && i % 100 !=0 && i + 1 < dateUtil2.getDay().getMonth().getYear().getValue()) 
                leapYearNum++;
            
        

        if (dateUtil2.getDay().getMonth().getYear().getValue() - dateUtil1.getDay().getMonth().getYear().getValue() > 1) 
        days = 365 * (dateUtil2.getDay().getMonth().getYear().getValue() - dateUtil1.getDay().getMonth().getYear().getValue()-1) + leapYearNum;
        
        if(dateUtil1.getDay().getMonth().getYear().value != dateUtil2.getDay().getMonth().getYear().value)
        for (int i = dateUtil1.getDay().getMonth().value + 1; i <= 12; i++) 
            if(dateUtil1.getDay().getMonth().getYear().isLeapYear() && i == 2)
                    days += 29;
            else
                    days += dateUtil1.getDay().mon_maxnum[i];
        
        for (int i = 1; i < dateUtil2.getDay().getMonth().value; i++) 
            if (dateUtil2.getDay().getMonth().getYear().isLeapYear() && i == 2)
                    days += 29;
            else
                    days += dateUtil2.getDay().mon_maxnum[i];
        
        if (dateUtil1.getDay().getMonth().value == 2 && dateUtil1.getDay().getMonth().getYear().isLeapYear())
            days = days + 29 - dateUtil1.getDay().value + dateUtil2.getDay().value;
        else
            days = days + dateUtil1.getDay().mon_maxnum[dateUtil1.getDay().getMonth().value] - dateUtil1.getDay().value + dateUtil2.getDay().value;
        
     if (dateUtil1.getDay().getMonth().getYear().value == dateUtil2.getDay().getMonth().getYear().value && dateUtil2.getDay().getMonth().value > dateUtil1.getDay().getMonth().value) 
        days += dateUtil2.getDay().value;
        if (dateUtil1.getDay().getMonth().getYear().isLeapYear() && dateUtil1.getDay().getMonth().value == 2)
            days = days + 29 - dateUtil1.getDay().value;
        else
            days = days + dateUtil1.getDay().mon_maxnum[dateUtil1.getDay().getMonth().value] - dateUtil1.getDay().getMonth().value;
        dateUtil1.getDay().getMonth().value += 1;
        for (int i = dateUtil1.getDay().getMonth().value; i < dateUtil2.getDay().getMonth().value; i++)
            if (i % 400 == 0 || i% 4 == 0 && i % 100 != 0) 
                if (i == 2)
                    days += 29;
                else
                    days += getDay().mon_maxnum[i];
            
    
    else
        days += dateUtil2.getDay().value - dateUtil1.getDay().value;
    return days;
     


class Day
    int value;
    Month month;
    int[] mon_maxnum = 0,31,28,31,30,31,30,31,31,30,31,30,31;
    
    Day()
        
    
    
    Day(int yearValue, int monthValue, int dayValue)
//        this.getMonth().getYear().setValue(yearValue);
//        this.getMonth().setValue(monthValue);
//        value = dayValue;
        this.month = new Month(yearValue, monthValue);
        value = dayValue;
    
    
    int getValue() 
        return value;
    
    
    void setValue(int value)
        this.value = value;
    
    
    Month getMonth() 
        return month;
    
    
    void setMonth(Month value) 
        this.month = value;
    
    
    void reseMin() 
        this.value = 1;
    
    
    void reseMax() 
        if(value > 0 && this.getMonth().getYear().isLeapYear()) //闰年
            if(this.getMonth().getValue() == 2 && value <= 29) //闰年二月
                this.value = 29;
            
        
        this.value = mon_maxnum[getValue()];//非闰年二月份时日期的最大值
    
    
    boolean validate() 
        boolean a = false;
        if(this.getMonth().getValue() > 0 && this.getMonth().getValue() < 13) 
        if(this.value > 0 && this.getMonth().getYear().isLeapYear() && this.getMonth().getValue() == 2 && this.value <= 29) //闰年
            a = true;
        
        else if(value > 0 && value <= mon_maxnum[getMonth().value])//除去二月的其他月份
            a = true;
            
        
        else
            a = false;
        return a;
        
    
    
    void dayIncrement() 
        this.value++;
    
    
    void dayReduction() 
        this.value--;
    

    class Month
        int value;
        Year year;
        
        Month()
            
        
        
        Month(int yearValue, int monthValue)
            this.year = new Year(yearValue);
            this.value = monthValue;
        
        
        int getValue() 
            return this.value;
        
        
        void setValue(int value)
            this.value = value;
        
        
        Year getYear() 
            return this.year;
        
        
        void setYear(Year value) 
            this.year = value;
        
        
        void resetMin() 
            this.value = 1;
        

        void resetMax()
            this.value = 12;
        
        
        boolean validate() 
            if(value > 0 && value < 13)
                return true;
            else
                return false;
        
        
        void monthIncrement() 
            this.value++;
        
        
        void monthReduction() 
            this.value--;
        
    
    
    class Year
        int value;
        
        Year()
            
        
        
        Year(int value)
            this.value = value;
        
        
        int getValue()
            return value;
        
        
        void setValue(int value) 
            this.value = value;
        
        
        boolean isLeapYear() 
            if (value % 400 == 0 || value % 4 == 0 && value % 100 != 0)
                return true;
            else
                return false;
        
        
        boolean validate() 
            if(value >= 1900 && value <= 2050)
                return true;
            else
                return false;
        
        
        void yearIncrement() 
            this.value++;
        
        
        void yearReduction() 
            this.value--;
        
    

首先我们需要实现dateutil,day,month,year这三个类之间的聚合关系,以降低类之间的耦合性,这就需要我去学会如何使用getter/setter方法去一层层调用不同类中的属性与方法。其中大部分的方法只需要按照上一次实验的代码为参照稍加修改,对各个属性的访问方法进行修改。

例如对于闰年的判断

需要从Month类中去一层层调用至year类中去才可实现

 相较于之前的日期问题的代码,在每个类中都增加了一个自增和自减以及判断是否需要复位的方法,这样能够更方便的对日期自增自减以及复位进行操作,

部分实现代码如下

 

 在基于之前的代码基础上修改的过程中,发现许多算法的不合理性,这也就导致在写这次题目时,有相当一部分的代码需要重新编写,花费了大量的时间,因此,在以后的题目中,我更应该对算法逻辑的合理性以及代码的复写性进行思考,以便以后对此代码的迭代扩充。

 

题目集4的7-6:

 

类图如下

 

 

源码如下:

import java.util.Scanner;

public class Main 
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) 
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            m = input.nextInt();

            if (m < 0) 
                System.out.println("Wrong Format");
                System.exit(0);
            
            System.out.print(date.getYear().value + "-" + date.getMonth().value + "-" + date.getDay().value + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
         else if (choice == 2) 
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) 
                System.out.println("Wrong Format");
                System.exit(0);
            

            n = input.nextInt();

            if (n < 0) 
                System.out.println("Wrong Format");
                System.exit(0);
            
            System.out.print(date.getYear().value + "-" + date.getMonth().value + "-" + date.getDay().value + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
         else if (choice == 3) 
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) 
                System.out.println("The days between " + fromDate.showDate() + 
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
             else 
                System.out.println("Wrong Format");
                System.exit(0);
            
        
        else
            System.out.println("Wrong Format");
            System.exit(0);
                
    


class DateUtil
    Day day;
    Month month;
    Year year;
    int[] mon_maxnum = 0,31,28,31,30,31,30,31,31,30,31,30,31;
    
    DateUtil()
        
    
    
    DateUtil (int year,int month, int day)
           this.day = new Day(day);
           this.month = new Month(month);
           this.year = new Year(year);
    
    
    Year getYear() 
        return this.year;
    
    
    void setYear(Year year) 
        this.year = year;
    
    
    Month getMonth() 
        return this.month;
    
    
    void setMonth(Month month) 
        this.month = month;
    
    
    Day getDay()
        return this.day;
    
    
    void setDay(Day day)
        this.day = day;
    
    
    public boolean checkInputValidity() 
        
        if (month.validate() && year.validate())
            return true;
        else
            return false;
    
    
    public boolean compareDates(DateUtil date) 
        if (getYear().getValue() > getYear().getValue())
            return true;
        else if (getYear().getValue() == date.getYear().getValue() && getMonth().getValue() > date.getMonth().getValue())
            return true;
        else if (getYear().getValue() == date.getYear().getValue() && getMonth().getValue() > date.getMonth().getValue() && getDay().getValue() > date.getDay().getValue())
            return true;
        else
            return false;
    
    
    public boolean equalTwoDates(DateUtil date) 
        if (getYear().getValue() == date.getYear().getValue() && getMonth().getValue() == date.getMonth().getValue() && getDay().getValue() == date.getDay().getValue())
            return true;
        else
            return false;
    
    
    public String showDate() 
        return getYear().getValue()+"-"+getMonth().getValue()+"-"+day.getValue();
    
    
    public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
    
        int year = getYear().value;
        int month = getMonth().value;
        int day = getDay().value;
        for (int i = 0; i < n; i++) 
            day++;
            if (day > mon_maxnum[month] && !(getYear().isLeapYear())) 
                day = 1;
                month++;
            
           if(getYear().isLeapYear() && getMonth().value == 2 && day > 29) 
               day = 1;
               month++;
           
           
           if (month > 12) 
               month = 1;
               year++;
           
           
           if (day > mon_maxnum[month] && getYear().isLeapYear() && getMonth().value != 2) 
               day = 1;
               month++;
           

           if (month > 12) 
               month = 1;
               year++;
           
           
            getMonth().value = month;
            getYear().setValue(year);
        
        return new DateUtil(year, month, day);
    
    
    public DateUtil getPreviousNDays(int n) 
        int flag = 0;
        while(n != 0) 
            if (getDay().getValue() > n) 
                getDay().value -= n;
                flag++;
            
            else 
                n = n - getDay().value;
                getMonth().monthReduction();
                if (getMonth().getValue() == 0) 
                    getMonth().resetMax();
                    getYear().yearReduction();
                    
                if (getMonth().getValue() == 2 && getYear().isLeapYear())
                    getDay().value = 29;
                else
                    getDay().value = mon_maxnum[getMonth().value];
            
            for (int i = getMonth().getValue(); n > mon_maxnum[i]; i--) 
                if (i == 2 && getYear().isLeapYear())
                    n -= 29;
                else
                    n -= mon_maxnum[i];
                getMonth().monthReduction();
                if (getMonth().getValue() == 0) 
                    getMonth().resetMax();
                    getYear().yearReduction();
                    i = 13;
                    
                if (getMonth().getValue() == 2 && getYear().isLeapYear())
                    getDay().value = 29;
                else
                    getDay().value = mon_maxnum[getMonth().getValue()];
            
            if (getDay().value > n && flag != 1) 
                getDay().value -= n;
                n = 0;
            
            if (flag == 1)
                n = 0;
        
        DateUtil date1 = new DateUtil(getYear().getValue(), getMonth().getValue(), getDay().value);
        return date1;
    
    
    public int getDaysofDates(DateUtil date) 
        DateUtil dateUtil1 = this;//较小的
        DateUtil dateUtil2 = date;//较大的
        if (this.compareDates(date)) 
            dateUtil1 = date;
            dateUtil2 = this;
        

        int days = 0;
        int leapYearNum = 0;
        
        for (int i = dateUtil1.getYear().getValue(); i < dateUtil2.getYear().getValue(); i++) 
            if (i % 400 == 0 || i % 4 == 0 && i % 100 !=0 && i + 1 < dateUtil2.getYear().getValue()) 
                leapYearNum++;
            
        

        if (dateUtil2.getYear().getValue() - dateUtil1.getYear().getValue() > 1) 
        days = 365 * (dateUtil2.getYear().getValue() - dateUtil1.getYear().getValue()-1) + leapYearNum;
        
        if(dateUtil1.getYear().value != dateUtil2.getYear().value)
        for (int i = dateUtil1.getMonth().value + 1; i <= 12; i++) 
            if(dateUtil1.getYear().isLeapYear() && i == 2)
                    days += 29;
            else
                    days += dateUtil1.mon_maxnum[i];
        
        for (int i = 1; i < dateUtil2.getMonth().value; i++) 
            if (dateUtil2.getYear().isLeapYear() && i == 2)
                    days += 29;
            else
                    days += dateUtil2.mon_maxnum[i];
        
        if (dateUtil1.getMonth().value == 2 && dateUtil1.getYear().isLeapYear())
            days = days + 29 - dateUtil1.getDay().value + dateUtil2.getDay().value;
        else
            days = days + dateUtil1.mon_maxnum[dateUtil1.getMonth().value] - dateUtil1.getDay().value + dateUtil2.getDay().value;
        
     if (dateUtil1.getYear().value == dateUtil2.getYear().value && dateUtil2.getMonth().value > dateUtil1.getMonth().value) 
        days += dateUtil2.getDay().value;
        if (dateUtil1.getYear().isLeapYear() && dateUtil1.getMonth().value == 2)
            days = days + 29 - dateUtil1.getDay().value;
        else
            days = days + dateUtil1.mon_maxnum[dateUtil1.getMonth().value] - dateUtil1.getMonth().value;
        dateUtil1.getMonth().value += 1;
        for (int i = dateUtil1.getMonth().value; i < dateUtil2.getMonth().value; i++)
            if (i % 400 == 0 || i% 4 == 0 && i % 100 != 0) 
                if (i == 2)
                    days += 29;
                else
                    days += mon_maxnum[i];
            
    
    else if(dateUtil1.getYear().value == dateUtil2.getYear().value && dateUtil1.getMonth().value == dateUtil2.getMonth().value)
        days += dateUtil2.getDay().value - dateUtil1.getDay().value;
    //else
        
    return days;
     


class Day
    int value;
    
    Day()
        
    
    
    Day(int value)
        this.value = value;
    
    
    int getValue() 
        return value;
    
    
    void setValue(int value)
        this.value = value;
    
    
    void dayIncrement() 
        this.value++;
    
    
    void dayReduction() 
        this.value--;
    

    class Month
        int value;
        
        Month()
            
        
        
        Month(int value)
            this.value = value; 
        
        
        int getValue() 
            return this.value;
        
        
        void setValue(int value)
            this.value = value;
        
        
        void resetMin() 
            this.value = 1;
        

        void resetMax()
            this.value = 12;
        
        
        boolean validate() 
            if(value > 0 && value < 13)
                return true;
            else
                return false;
        
        
        void monthIncrement() 
            this.value++;
        
        
        void monthReduction() 
            this.value--;
        
    
    
    class Year
        int value;
        
        Year()
            
        
        
        Year(int value)
            this.value = value;
        
        
        int getValue()
            return value;
        
        
        void setValue(int value) 
            this.value = value;
        
        
        boolean isLeapYear() 
            if (value % 400 == 0 || value % 4 == 0 && value % 100 != 0)
                return true;
            else
                return false;
        
        
        boolean validate() 
            if(value >= 1820 && value <= 2020)
                return true;
            else
                return false;
        
        
        void yearIncrement() 
            this.value++;
        
        
        void yearReduction() 
            this.value--;
        
    

该题目要求与上一道又略有不同,year,month,day三个类各个都与dateutil类形成聚合关系,这也就使得程序在调用这三个类中的属性方法时,不需要一层层去调用可以直接调用,而在对代码进行修改的过程中,需要注意的就是将属性的访问方式修改以及,在算法上略微改动。同时需要需要注意,改题目的年份范围与上一题是有差异的

 

 

 心得:

  在对于以上两种聚合方式的编写,对不同的聚合方式的利与弊有了初步的认识,也知道了同一种题目要求可以拥有多种结构模式,而不同的结构模式,对于一个代码往后的修改有很大的影响,一个好的模式,能更好的服务于未来的各种需求。

 

题目集6的7-1:

  在得知题目集6的题目是之前题目集4的迭代时,就知道,这次大概率时完不成了的,再加之老师之前所说至少20h+,有所恐惧,但在题目集4第一题未作出的情况下,觉得自己还是要试一试,之后在eclipse上进行的部分功能的编写,也是花费了不少的时间,但是最后代码总是出现种种问题,同时对题目的要求也是有部分没能看懂,从而进一步导致对完成这道题失去了动力与信心。虽然没能完成该题,但我认为,也是跨出了自己不敢尝试的一步,希望下次,更加努力,去完成每一道题目。

(3)踩坑心得:

   在完成此次三次题目集之后,发现了自己对各种类之间的关系的不明确,不清楚各种关系的定义,就如在初次看到两种聚合关系类图时,根本不清楚要如何去实现,也是在后续的自主学习过程中逐步理解聚合,就光看第五次题目集的两道相,是较于另外没写的题来说算简单的,但是也是花了大量的时间去完成,期间不断的调试出现的问题,包括月份不能复位,或者是日期不能返回最大值。

public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
    
        int year = getYear().value;
        int month = getMonth().value;
        int day = getDay().value;
        for (int i = 0; i < n; i++) 
            day++;
            if (day > mon_maxnum[month] && !(getYear().isLeapYear())) 
                day = 1;
                month++;
            
           if(getYear().isLeapYear() && getMonth().value == 2 && day > 29) 
               day = 1;
               month++;
           
           
           if (month > 12) 
               month = 1;
               year++;
           
           
           if (day > mon_maxnum[month] && getYear().isLeapYear() && getMonth().value != 2) 
               day = 1;
               month++;
           

           if (month > 12) 
               month = 1;
               year++;
           
           
            getMonth().value = month;
            getYear().setValue(year);
        
        return new DateUtil(year, month, day);
    

在编写计算下n天日期的方法中,在判断完月份或者日期达到最大值时,经常忘记要将年份或者月份加一,这也就导致在调试过程中反复在同一个问题下进行多次的调试找错。在这类错误中,突出了我在编写代码时,对自己的逻辑不够清晰,或者是在面对较为复杂的逻辑算法时,需要去用笔写下来,及时提醒自己当心某类容易忽略的错误。

(4)改进建议:

   首先,格式问题,在代码量一大时,在写完之后,通篇去扫视代码,会觉得很乱,不能一眼看到自己想要的东西,这需要我在今后的学习中不断去学习如何将代码写的至少要清晰明了。代码的清晰不光方便自己之后的调试修改,同时养成这样一个好的习惯,我认为也是有利于以后的职业道路。

  其次就是逻辑的不清晰,尤其在面对较为复杂的问题时,会把自己绕晕,并且不能及时找到错误的地方在哪,因此,善于在纸上写写画画,就显得很有必要了。因为在之前学习c语言时,我们所面对的都是相对简单的问题,自己在脑中构思一下就够了,而现在面向对象呈现的要求,这是就不光是仅靠大脑去构思能解决的了,所有有必要拿起笔去多画。

(5)总结:

  完成了三次作业之后,也是深刻意识到学习java不再是和之前学习c语言那样,不仅是知识点难度上升了,同时知识量也大大增加。在每一次完成pta作业时不能有意识地督促自己尽快完成作业,而导致在最后三天来花大量的时间去完成,在经历这一次的叫教训之后,我应该想办法拿出更多的时间去及时完成作业,这样也就不会再次出现周末两天写整整两天的作业而得不到休息的情况。

  而这三次作业对我的练习来说,深刻意识到自己没能跟上学习进度,没能习惯java学习的节奏。不过在补充学习过程中,进一步的拓宽了我对Java这么语言以及这门课程的认知,想要学好,真的需要花大量的时间,不然最后跟不上的雪球只会越滚越大,只有在对相应的知识点有了系统的学习,之后再进行题目的训练,这样才能达到最大的效率,所有,在以后完成作业时,一定要先保证自己已经将所考察的知识点已经有了初步的学习。我认为这次作业我从中获得的不仅是这些java的知识,同样也锻炼了自己的耐心,在前两个周末的作业中,都可以让强迫自己静下心来去完成,尽管期间很痛苦,因为写了很久但是还没有完成题目要求,一坐就是一下午直到晚上。当然,我不知道是我能力的不太行还是哪方面,对于一些问题总是要花很长的时间去完成,长到我自己都不敢想,但我又是那种偏要做出来的性格,这也就导致了花大把的时间去完成最后一两道题。虽然题目最终没能拿到满分,但我认为,我已经尽力去完成了。而在完成题目集之后,及时去学习之前没能弄得很明白的一些知识点,学习到了很多东西,刷新了面向对象这门语言的认知,也更加知道了自己之前对许多概念的错误的理解,而学习到的大量的知识,也让我对学习好这门课程重新看到了希望,也是发现了这门语言的优越性,知道了语言不应该只有简简单单的语法,其中的一些结构,模式,等等才是重中之重。希望在接下来的java学习过程中能够保持对java知识的渴望,不要畏惧难题,不要随大流,要努力做好自己力所能及的每一件事,尽力去完成每一道题。

我的第二次找工作之旅

去年7月份的时候想转iOS,那时候刚刚学习iOS不久的我急于求成,刚学完高级控件就敢去应聘iOS开发,结果闹了很多笑话。经过半年的沉淀,在年后我又一次开始找工作之旅,记录一下。

腾讯科技

去TX一直是我的梦想,7月份的时候就找前同事内推过,但是当时水平太低,没能通过一面,自那时候起,我便将自己电脑的开机密码改为了w1dyjtx!(我一定要进腾讯!)以此每日激励自己勤奋努力。

经过了半年,自己的博客和GitHub渐渐有了点内容,偶然看到7月面试我的腾讯高级工程师在朋友圈里分享“移动开发精英俱乐部”的群信息,于是也去申请加入。群里面都是来自各个公司的大牛,平时聊些技术问题,每周还有话题讨论,也有人在里面发布招聘和求职信息。这个群规定至少有三年经验才能加入,我虽然只有两年经验,但是给群主看了我的博客和GitHub后,他破格让我加入了。

真的是蝴蝶效应,就是因为加入这个群后,才有了后来的事。某一天,看到群里有腾讯的招聘信息:初中高级的iOS工程师都要!

看到这消息我立马去完善了好久没更新的简历,次日投出了。

简历通过地还比较顺利,等过了一个星期后,得到了电话面试的机会,也就是一面,面试问了许多有难度的问题,算是后来我面试那么多次里面问得比较深比较密的了(我也记不得太多问题,稍微把记得的题目回忆记录了一下: 《2016年1月TX电面题》)。基本上一面结束时我已经猜想到我没有达到他的要求。有点失落。

奇迹是过年的时候我才发现,一面面试官在一面后加了我的QQ好友!然而一直没上QQ的我过了半个多月才发现。然后我接受了他的申请,询问着是不是我还有机会?可是跟他聊天的过程中发现,他们希望的是招一批T3以上的高级工程师,我确实没有达到他们的要求。人生的大起又大落。

这个时候已经是年后了,我也开始在拉勾投简历,不死心地还是投了腾讯。

然而人生的大起大落还没完!在拉勾上的投递过了几天后又被秒“不合适”后,2.18号我居然又接到腾讯电话说让我明天去面试!当时很疑惑到底是哪个让我去呢?明明这边QQ上都已经说“很遗憾”了,那边拉勾又被标记为“不合适”了。

不管哪般,有机会总是好的!为了准备各家公司的面试,最近复习了超多知识点,对相对比较难的RunTime和RunLoop尤其关注,哪怕是再次一面那么难我也不怕了。

这次二面是我觉得我所有面试里面表现最好的之一了,但是表现好倒不是因为准备得充分,而且面试官并没有问我这些iOS里面比较难的点,反而是问了我很多智力题,举两个栗子��

1.给我一串数字“20,21,23,25,26,27,28,30,1,3,4,6,7,8,10,13,15,17,18,19”,一个从小到大排的队列从某一处切断,将切断处前后子队列交换位置,用什么方法可以找到最小值的位置?

他刚一写数字的时候,我心里就想:“完了完了,又要排序了,怎么办,没背呀!”还好他后来说是找数字不是排序,我心中大喜。

思考了几分钟,我就说出用“二分法”来查找,先把第一个数字(21)记录下来,然后从队列中间开始找(3),比较中间的数字和第一个数字大小。如果中间数比第一个数字大,(因为这本来就是个递增序列,所以前面子序列都可以不看了),则把中间那个数字记录下来,再二分后面的子序列进行递归比较;如果中间数比第一个数小,则说明更小的只可能在它们之间,后面的只会更大,所以二分前面的子序列进行递归比较。

2.一栋大楼100层高,你有且只有两个特质玻璃球,想要测试它们从多少层扔下来的时候会碎,请给出最少次数的方案?

我又想到了二分法,提出先50层扔一下,如果碎了,就从第1层开始往50层试;如果没碎,就75层扔一下,递归。

他提出这个方法极端情况要50次,有没有更好的。我说我想不出更好的,因为我只有两个玻璃球,碎了就没了,于是问他能不能给我提示。他提示我说要考虑的是粒度的大小,如果把层数提高至10000层,我的方法岂不是要试5000次?然后他提出是不是可以先25层扔一次,如果碎了,就1到25层一层层试;如果没碎,就在50层扔一次,递归。这样最复杂的情况也是25次。

依着他给的思路,我想着100是10的平方,那以10次作为切分点应该是比较好的。面试结束后我还特地查了一下答案:知乎:《用2个玻璃球找到从一100层的大楼的某一层落下刚好会摔碎,如何制定最优策略?》

诸如此类的智力题,我都算答上来了,于是自我感觉较好,后来又被问到一个C++的问题,让写出删除双向链表中的某一个结点的方法。还好我C++其他全忘光了,除了链表。于是飞快地写出函数。

然后立马遭到反问,如果要删除的是头结点你这个方法还能用?原来我完全忘记考虑多种情况了,只顾着写最基本的逻辑。于是后来我不仅加上头尾判断,还加上链表判空,数据长度判断。

二面结束时,面试官没有说“你有什么要问我的?”而是说“后面可能还有两次面试,我尽量压缩成一次”,还用大号加了我QQ,我就知道绝对有戏!

然后就到了2.24号,下班时来了电话说明天17:30-18:30面试。这次面试感觉和前面不太一样,面试当天下午两三点就开始打电话提醒我晚上的面试,到了四五点的时候,又来电话问我到哪了,是否能准时赴约。而我那时刚好被卡在另一家公司面试,那一家公司让我当场翻译一篇苹果官方英文文档,花费了很多时间,从1点半开始一直面试到5点。

后来干脆打的去的,可是发现简历少带了一张!时间紧急又来不及去打印。到了万利达大楼后,是一面的面试官来接我,像见到再生父母一般!我问他为什么QQ上拒绝我后又给我机会呢?他说是总监的意思。可能有意培养有潜力的新人吧,而今天的面试就是总监面!说明今天很重要啊,如果不合总监意就前功尽弃了!于是我向一面面试官询问是否能帮我打印份简历,他一句“准备工作没做好啊…”当场给我造成了一万点伤害。

整个面试过程除了自我介绍和介绍项目外,我也记不清楚问了些什么问题了,只记得总监一直和我强调的不要看问题的表象,要看本质——男女怎么区别,不是看头发长短,而是看染色体是XX还是XY。还问我自己感觉比别的程序员优秀的地方是什么?

面试到了晚上7点左右,换招聘经理来了,我们简单聊了几句后,他说时间太晚了,让我早点去吃晚饭,他也要回去问下总监的意思,这第四面就算完了。

过了一个星期,一直都没有消息来,我心里也有些许着急,但是没有消息其实就是好消息。之前听说第五面是部门经理面,而部门经理刚好休假了,所以暂时无法进行面试,如果没通过一个星期内就会告知没通过的消息对不对?所以没消息就是好消息!抱着这个心态,我在3月4号询问了HR消息,果真是好消息!他说部门经理暂时回不来,所以授权给总监了,而上周总监面我通过了!也就是我的专业面试都过了!我心里乐开了花~

接下来就剩下周一招聘经理的终极一战了!我已经抱着不要薪水的态度去奋战了,相信希望就在不远的前方!

美图移动

美图是我在拉勾上刷新刷到的,大家应该都知道美图,每个人的手机上也都应该有美图秀秀或美拍之类的软件。我在2.15投出了简历,直到2.23有了回复说简历过了筛选,然后立马就来了电话,约了第二天下午面试。

去美图的第一印象极其的好,一进办公室就有种闪瞎了眼的感觉,三面雪白的墙壁,能倒印出影子的地板砖,整齐简洁的摆设……下图来自网络,可以借鉴感受一下。

去了先是笔试,难得遇到笔试,还是那种程序大题,比如要求自己用现有ScrollView写出一个TableView来,又或者写一个自定义手势,前面的选择题我都比较有信心地完成了,看到后面的大题我脑子一片空白,一种“要交白卷了”的恐怖心理缠绕着我,让我想放下试卷离开了。而我也确实交了白卷,挺不好意思的,后面大题一片空白,觉得要这是在面试官面前要被完虐的节奏。

交卷后首先是HR简单的面试,我上来就道歉说,不好意思,我笔试写得不好,后面都空白了。她问我为什么空了,我说,这些我其实都做过,但是让我突然写,有些方法我记不起来了,说完我还拿出我做的APP给她看证明我确实是做过的。然后就是一些“为什么要离职”的交谈了。

过了没多久就是技术面了,出来的一个男生估计比我大不了几岁,很好相处的样子。我又一上来就开始道歉。他笑笑说,“没关系,这个没事的,你要我做这些我也记不得的。” 感觉瞬间被奶满了血原地复活!气氛一下子就缓和了!他带了个笔记本,开始看我的博客,发现我写了一篇对腾讯面试题的记录,就开始挑里面的问题问我,我暗自窃喜,我写博客自然是要对内容理解了才会记录下来,所以那些问题自然都难不倒我,而且最近还恶补了很多中高级的知识点(文章最后会给出网址)。接着就聊技术,整个过程轻松愉快,在我给他介绍我做的“QQ小红点”效果时,我为了更好地向他展示,无意识地跑到了他身边,过了一会会他笑着说让我回到座位上,不然被“那群屌丝”看到又要议论了。我这才意识到自己有点失礼,同时又觉得他很平易近人,我周围的程序员好像就是这个样子的。

中间唯一有点失误的可能是NSString那里,他问我copy的区别,我们知道copy放在属性里面,是为了防止外部传入的 NSMutableString 在外部被更改了,所以要用copy进行内容的复制,也就是深拷贝。而[NString copy];这里的copy其实是浅拷贝,只会对引用计数+1。

回答这题的时候我脑袋突然有点蒙了,思路变成了:既然[NString copy];是浅拷贝,那在属性里面放copy有什么用呢?属性里面放copy不就是在setter方法中使用[NString copy];吗?那[NString copy];是浅拷贝的话,copy就没有用了呀!(我完全忽略了NSMutableString的存在了。)

然后我就混乱地回答一通,最后我向他提问时问他我的表现如何时,他说整体还好,但是比如NSString这样小的问题上可能会在开发过程中遇到一点小坑。不过他对我的博客和GitHub还是比较满意的,觉得我自己解决问题的能力还不错。我和他相处起来感觉也很愉快,于是琢磨着有戏。

果不其然,第二天(2.25)下午就接到了美图的电话,说我一二面通过了,接下来和我约了隔天的总监面。

我总感觉只要过了第一次的技术面,后面都是越来越简单的。总监问我的问题果然提高了一个阶,直接问我如果让我培训有C语言基础的新人学习iOS,我会如何做起。平时写博客的时候其实已经有种为“人师”的感觉,而且我还在我们公司开过iOS基础培训,所以对这题还是有话可说的。

(闪开,我要开始胡扯了)

首先我不建议大家通过书籍来入门,我更推荐通过视频来入门,我相信学习iOS的都晓得MJ,只要跟着看完他的三季视频,就基本入门了。然后这个时候开始做点小Demo,可以按着自己的兴趣去做,比如我喜欢动画,就看想做什么比较酷炫的效果。如果这个时候有项目能做的话是进步最快的方式,跟着项目去完成需求,完善代码,优化性能。做了一个完整的项目后,以后遇到问题基本能搜索SO解决,会调试,会测试,会使用第三方,基本小项目都没有太大问题了。如果遇到业务上的问题,就需要请教团队中的前辈,看看有没有什么好的解决方案。

(胡扯完毕,大概当时是这么回答的)

总监了解我喜欢做UI动画,于是问到我UIKit框架是如何,继承关系又是如何,我当时居然回答了UIView继承NSObject,后面讲的就都乱了套了。事后把继承关系图复习了一遍:

担惊受怕地度过了几天,直到3月2号,终于接到了美图HR的电话,通知我总监面过了!约了我第二天的CTO电面。

这次CTO面应该是我觉得面试当中最失败之一了,因为本来面试时长总共不到20分钟,还大部分时间着重在我不擅长的领域纠缠,也怪我自己没带好“路”。

在做自我介绍的时候,我提到我大学实习的时候做过web开发,CTO问我用地什么语言,我说JavaScript。问我用什么服务器,我说Tomcat。问我用什么数据库,我说Oracle。问我为什么用Oracle,我……后来在Oracle上询问了很长时间,比如Oracle和其他数据库比优点在哪?Oracle和SQlite的区别?为什么不在手机端用Oracle?等等问题。回答地有些心虚。

后来嘴贱的我又提到最近看到一篇技术文说iPhone4的性能比iPhone6的性能要好,直接遭到CTO质疑:“哪篇文章,你发给我看?”,后来又揪着这个问题询问了好多,让我当场羞愧不已。(事后我再找到那篇文章,发现说的并不是iPhone的区别,而是iOS6和iOS9的区别——我记错了)。

面试完心里很忐忑,现在还在等消息。

随手科技

其实找工作找了这么久(两三周时间),面试那么多次(每一家企业平均面3次),心里也有些疲倦了,每次新去一家都要重新开始的感觉很疲惫,于是后来就投的少了,只投那种“如果给了Offer,我就愿意去”的公司。其实要求也很简单,就希望下一家做的项目能有一点影响力(比如为千万用户服务),项目有难度能让自己在技术上深入成长。作为金蝶的子公司,随手科技就是这么一家企业。

其实我本人对金融一窍不通,当初也没投随手,正好有个同事投随手通知去面试引起了我的注意,查了一下它们的APP在AppStore上排行靠前,是行业的领头羊,正合我意,于是才投的简历。

2.22投的简历,2.29收到了面试通知,3.1去面试。这次面试是我面试过的最有效率的一次!

之前和同事谈面经的时候,聊到了他在随手的面试,他说是全英文笔试题,第一题就没回答上,导致当场被面试官拒绝了。去了后发现真的是全英文笔试,还好只有四道。第一题用英文问的“如何给一个对象分配内存空间?”哈哈,还好有请教同事,只要回答“alloc”就可以了!~后面的题目也都不难,问了下UIKit的结构(看,除了美图又一次问到了),block如何会循环引用等。我为了表示自己英文还不错,都用英文回答了,但其实我英文真不咋地,所以回答地句子都异常简单简短。还有一张试卷是一道大题,当场让用设计模式设计出来低耦合的多蜂鸟采蜜的场景以及画出UML图。我使用了观察者模式。

笔试完后面试官来了,首先很仔细地看我的笔试,看到第一题就疑惑了:“除了alloc还有没有别的?”我突然灵光一现想到了内存管理,于是说还有retaincopy。他笑笑问为什么我没写上去,我说我光注意怎么用英文回答去了。看到蜂鸟采蜜时,他问我还能不能想到别的办法低耦合?我又灵光一现想到了KVO,但其实KVO也属于观察者模式,其他的想不出来了。

笔试题看完开始和我聊项目,我问他要不要拿出手机给他直接看,他说不用,想听听我的描述能力怎样。也好,我觉得描述出来的东西总比看上去的东西要高大上一点。再后来就问一些技术问题,对身经百战的我来说真的不难。整个一面过程自我感觉良好,而且面试官还说是我校友,都是江西财经大学的!看来一面是过了。

果不其然,他让我等一下,二面面试官会过来——这就二面了?还真效率。结束的时候他问我是否下载了他们的产品,我说没有,他有点不满意,我急忙说是否有wifi我马上下载,他说昨天就应该下好的。(这也提醒了我以后准备工作要做足。)

刚进这公司的时候感觉很热闹,角落到处都是两三个人在谈话,应该是在面试,我猜测他们公司最近应该在大招。果然,后来二面面试官说iOS的现有十多人,还准备再招十多人,做“随手记”这一个项目。还真是个大项目耶,居然要这么多人。面试时,二面面试官也不“看”我的项目,要让我“说”出来。

二面也算顺利,面试官又让我等一下——然后三面面试官来了。三面应该是总监级别的,和我聊的什么我已经完全忘记了,一下午连三面还真是比较少见的高效率,而且几位面试官都还和蔼,面试过程中都能看见他们的笑容。我就记得三面面试官最后问我有什么想问他的时候,我说不出来话,我说“刚刚一面面试官让我问,二面面试官也让我问,您这,我真的没什么想问的了”。他笑笑。他又问我对金融了解多少,我说我完全金融小白,他说我这有点吃亏了。我以为他的意思是说对于这个岗位我有点吃亏了,实际上他是说我不懂金融,对于每年6%的增值率吃亏了,他们公司的员工普遍能保持自己的资产高于6%的增值,甚至达到12%,听得我一愣一愣的,觉得进入这个公司真的可以学到很多东西的样子。(金融我真不懂,什么增值率的可能我记错了专业名词也不一定)

再然后他又让我等一下,给我从前台拿了张表,说我填完了就交给前台然后HR就会来面我了——这是已经到HR面的节奏了么?!填完了表交给前台,前台反问我总监说是交给她就可以了还是要叫HR出来?看来不是所有人交完表都有HR面呀~我说有让HR出来。于是HR面就开始了。

之前技术面的时候我一直绷着个脸,到HR面后,看她笑容满面的,我也就松了口气,和她轻松地聊起天。她说这里也有另外两个做技术的女孩子,都酷酷的,我苦笑说我应该没有她们酷。然后HR着重和我介绍他们公司文化福利等。

整个过程给我的感觉就是很有效率!想起来之前有个美工同事去魅族的时候,也是当天面试完所有面!后来她进了魅族,看来我这也是差不多了。

在3.3晚上接到了HR通过的电话!~就等发Offer啦!~

其他

上面有提到有一家让我当场翻译苹果官方文档的公司,就属于“其他”里面的,当时让我翻译的是APNS,在后来的面试中,我还用到了当时读到的知识哈。

为什么不说明公司名字呢?——因为我没过。

是一家小公司,环境还不错,Boss办公室外是高尔夫球场的视野。面试过程给我感觉很压抑,笔试面完后的一面技术面,二面CEO面,他们都不笑的,这让我感觉很有压力。技术面的时候,面试官一边问我问题,一边在纸上记录我回答的话,很少抬头看我。有问到一题蛮有意思的数据结构题我记一下:

一个栈,不停入栈出栈大小随机的数字,问如何做才能在任意时刻都知道该栈内的最大数是多少?

首先很容易想到再开辟一部分内存保存这个最大数,如果入栈更大的,就把更大的记录下来。他问我如果入栈 2 1 3 的话,现在保存最大的是3,可是3又出栈了我怎么办?

大脑飞速旋转:说明只保存一个最大数是不够的!于是我想这部分内存应该是个特殊的数据结构,立马又想到栈!我的栈只入栈比栈顶大的数字!如果入栈 2 1 3 的话,我的栈内保存的是 2 3,这时候3出栈的话,我的栈的3也出栈,那么留下2就是他的栈当前最大的数。

看得出来他对这个回答还是比较满意的。后来的CEO面,我用眼睛瞟到一面技术官在本子上给我打的分基本都是ABAB。CEO面我只记得他让我翻译官方文档了。

这一家是在简寻上推荐的公司,据后来简寻的负责人讲,当时她推荐了几个候选人给这家公司,其中有个是在乐视工作过的,但是只有我通过了,他们对我印象也是比较谦虚向上,而且我还有GitHub和博客(再再再次验证GitHub和博客对找工作的重要性)。

一面算是过了,几天后HR打电话来要求我再进行一次机试,然后我就挂了。机试是这样的,一张试卷3道题,基本上都是算法题,可是给我准备的本本居然没装Xcode,其他比如Android Studio,Eclipse,VC等都没有,然后询问面试官怎么办,面试官说让我手写代码,我问是否能回去敲代码然后给他们发过来,被拒绝了。可能是这中间发生的一些不愉快导致我的态度有点不佳,写完笔试后我就回去了。回答得也一般吧,机试我以为考的是平时写代码的能力,以及使用API的熟悉程度,虽然是算法题,我还是用了一些既有函数来简答。

2.29的机(笔)试,3.4被告知未通过最终的面试。

总结

这次找工作之旅增加了自己很多经验值,以下总结一下需要注意的地方。

简历

其实找工作第一步就是要写好简历,简历其实不难写,但是不注意的话连简历都过不了筛选真是死得冤枉——像乐视的同学挂在简历上我都替他不值。

简历需要有姓名、年龄、联系方式、工作年限、毕业学校、所学专业几小项,以及工作经历,项目经验,个人能力,自我描述等几大项。(好像说了和没说一样?)其他还有作品展示地址,上线应用连接,个人博客地址,GitHub地址,StackOverflow账号等,自己常去逛的技术网站也可以提提,最好是翻墙去的网站。有这么多内容要说,所以尽量精简语句。

面试准备

开始准备面试时,需要回顾各个知识点,重难点RunTime和RunLoop以及UI结构树,强烈建议把《招聘一个靠谱的iOS》里的题目弄明白,基本能应付一些中高级问题了,答案在这里:
《招聘一个靠谱的iOS》面试题参考答案(上)
《招聘一个靠谱的iOS》面试题参考答案(下)

一些其他的比如去面试时多准备几份简历;提前下载好对方公司的应用进行观看检查有无bug或者不合理的地方;提前10-20分钟赶到等。

对了,关于一些面试官很有可能问到的问题,提前做好准备,比如首当其冲的就是“自我介绍”,其实就是自己把自己从大学毕业到工作经历简单讲一遍,给面试官时间看你简历的一个过程。然后就是“项目技术”,“你在项目中做了什么?”“这个项目用到了哪些技术?”“这个项目的难度在哪?”“画出框架/流程图?”这些需要面试前把自己的项目理一遍,可以看当时项目的需求文档和设计文档,里面有许多的书面介绍。

看到一篇面经里面提到的就是我想说的,引用一下

面试不是你问我答

在屡屡受挫之后,我开始反思面试的流程:自我介绍->项目经历-> 技术问题 -> 我有何问题。我发现在除了项目经历之后,其他环节都不是问题,毕竟我有着两年的积淀,基础还是很扎实的。

于是我去请教一些师兄,面试应该要注意什么。起初问了微信的两位大牛师兄,结果甚是惊讶。简单总结就是,在讲项目的时候,你需要展示你自己的亮点,可以说一些装逼的词,但装逼也是得有真材实料的。比如我在项目中使用了WebSocket,那么面试官很可能问你WebSocket是什么,底层原理你知道么?如果你当场傻掉,面试官就会觉得你只是会使用别人的东西,并不在意实现原理,终究是码农。那么事先你就应当去看看WebSocket协议的官方文档(纯英文,看得累死我了!),这样面试官一问你,你能头头是道,会大大加分。再比如,你在项目中使用了模块化,那么你就一定要知道什么是模块化,而不是说你会用模块化工具。其实要求并不高,你只要能很好说清楚什么是AMD规范,什么是CommonJs规范,各自的优缺点是什么就很够了,起码之后每次面试官问我,我都是秒回的,面试官竟无言以对,也就是对我的认同。

最后一点,也就是最重要的一点是,一定要把面试官往你熟悉的领域引导,这真的很重要,因为如果你不引导,面试官不了解你的项目,看不到你的亮点,就只能一直问技术问题刁难你,人家在大公司待这么久了,还不是轻松碾压你。所以你在引导的同时,时不时提及一些事先准备好的关键词,技术官一问,你一回答,怎么都妥了~

原文: 《我是如何同时拿到阿里和腾讯offer的》

关于面试官的最后一个问题:“你还有什么想问我的么?”如果你没有,可以看看这篇文章:《面试最后,你还有什么要问我的?》

好了就这么多啦!希望大家都能有好结果!~

以上是关于OOP学习的第二次BLOG的主要内容,如果未能解决你的问题,请参考以下文章

oop第二次作业

OOP课程题目集第二次总结

Python学习的第二次总结

FC第二次博客作业

自考的第二次考试

六个让你零距离接触哈佛的学习平台,这可能是你的第二次机遇