Back home

الفنون رقم 007

الفنون رقم 007

ARTS هو نشاط بدأه 由左耳朵耗子--陈皓: قم بإجراء سؤال واحد على الأقل عن خوارزمية leetcode كل أسبوع، واقرأ مقالًا تقنيًا واحدًا على الأقل باللغة الإنجليزية وعلق عليه، وتعلم مهارة فنية واحدة على الأقل، وشارك المقالة مع الآراء والأفكار. (أي أن الخوارزمية والمراجعة والنصائح والمشاركة يشار إليها باسم ARTS) وتستمر لمدة عام واحد على الأقل.

فنون 007

هذه هي المادة السابعة. لقد اعتدت أن أشعر بالحيرة عند النظر إلى الخوارزميات، لكنني الآن أشعر بها ببطء ولدي أفكار. وآمل أن تصبح أفضل وأفضل في المستقبل.

سؤال خوارزمية الخوارزمية

سؤال خوارزمية leetcode 15 3Sum: الصعوبة: معتدلة

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

الطريقة الأولى التي تتبادر إلى الذهن هي كما يلي، وهي بالطبع الأقل كفاءة. على جهازي، يستغرق الأمر 15 ثانية لاختبار 3000 قطعة من البيانات.


int** threeSum(int* nums, int numsSize, int* returnSize) {
    int **a= NULL;  //用二级指针动态申请二维数组
    int count = 0;
    for (int i =0; i < numsSize-2; i++) {
        for (int j =i+1; j < numsSize-1; j++) {
            for (int k  =j+1; k<numsSize; k++) {
                int first = nums[i];
                int second = nums[j];
                int third = nums[k];
                if (first + second + third == 0) {
                    if (first < second ) {
                        int temp =first;
                        first = second;
                        second = temp;
                    }
                    
                    if (first < third ) {
                        int temp =first;
                        first = third;
                        third = temp;
                    }
                    
                    if (second<third) {
                        int temp =second;
                        second = third;
                        third = temp;
                    }
                    
                    
                    int b = 0;
                    if(a != NULL){
                        for (int loop = 0; loop < count; loop++) {
                            int *aa = a[loop];
                            
                            if (aa[0] == first && aa[1] == second) {
                                //已经存在
                                b = 1;
                                break;
                            }
                            
                        }
                    }
                    
                    if (b == 0) {
                        int* result = (int*)malloc(sizeof(int) * (3));
                        result[0] = first;
                        result[1] = second;
                        result[2] = third;
                        
                        if (count ==0) {
                            count++;
                            a=(int**)malloc(sizeof(result)*count);
                        }
                        else{
                             count++;
                             a=(int**)realloc(a,sizeof(int*)*count);
                        }
                        
                        a[count-1] = result;
                    }
                }
            }
        }
    }
    *returnSize = count;
    return a;
}

عند النظر إلى المطالبات، يتم فرزها جميعًا أولاً. بعد الفرز، فكرت في البحث الثنائي، لذلك قمت بتنفيذه على النحو التالي

/插入排序
int* insertionSort(int nums[],int numsSize) {
    for (int j = 1; j < numsSize; j++) {
        int  sortingNum = nums[j];
        for (int i = j-1; i >=0; i--) {
            if (sortingNum < nums[i] ) {
                int temp = nums[i+1];
                nums[i+1] = nums[i];
                nums[i] = temp;
            }
        }
    }
    return nums;
}


// 二分查找
int binary_search(int arr[],int left,int right,int element){
    while(left<=right) {
        int mid = (left+right)/2;
        if(arr[mid]>element){
            right = mid - 1;
        }
        else if(arr[mid]<element){
            left = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}

int** threeSum3(int* nums1, int numsSize, int* returnSize) {
    int *dddsd = insertionSort(nums1,numsSize);
    if(dddsd[0] > 0)
        return NULL;
    if(dddsd[numsSize-1] < 0)
        return NULL;
    int **result= NULL;  //用二级指针动态申请二维数组
    int count = 0;
    for (int i =0; i < numsSize-2 && dddsd[i] <=0; i++) {
        for (int j =numsSize-1; j >i && dddsd[j] >= 0; j--) {
            int first = dddsd[i];
            int second = dddsd[j];
            int third = 0 - first - second;
            int dfsd =binary_search(dddsd, i+1, j-1, third);
            if (dfsd == -1) {
                continue;
            }
            third = dddsd[dfsd];
        
            int b = 0;
            if(result != NULL){
                for (int loop = 0; loop < count; loop++) {
                    int *aa = result[loop];
                    
                    if (aa[0] == first && aa[1] == second) {
                        //已经存在
                        b = 1;
                        break;
                    }
                    
                }
            }
        
            if (b == 0) {
                int* sums = (int*)malloc(sizeof(int) * (3));
                sums[0] = first;
                sums[1] = second;
                sums[2] = third;
                
                if (count ==0) {
                    count++;
                    result=(int**)malloc(sizeof(sums)*count);
                }
                else{
                    count++;
                    result=(int**)realloc(result,sizeof(int*)*count);
                }
                
                result[count-1] = sums;
            }
        }
    }
    *returnSize = count;
    return result;
}

من أجل منع التكرار، ستقوم الخوارزمية المذكورة أعلاه بمقارنتها بالخوارزمية السابقة في كل مرة تتم فيها إضافة النتيجة. يمكن بالفعل تحسين هذه العملية، ويكون التنفيذ النهائي كما يلي:

//插入排序
int* insertionSort(int nums[],int numsSize) {
    for (int j = 1; j < numsSize; j++) {
        int  sortingNum = nums[j];
        for (int i = j-1; i >=0; i--) {
            if (sortingNum < nums[i] ) {
                int temp = nums[i+1];
                nums[i+1] = nums[i];
                nums[i] = temp;
            }
        }
    }
    return nums;
}


// 二分查找
int binary_search(int arr[],int left,int right,int element){
    while(left<=right) {
        int mid = (left+right)/2;
        if(arr[mid]>element){
            right = mid - 1;
        }
        else if(arr[mid]<element){
            left = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    int *sortedNums = insertionSort(nums,numsSize);
    if(sortedNums[0] > 0)
        return NULL;
    if(sortedNums[numsSize-1] < 0)
        return NULL;
    
    int **result= NULL;  //用二级指针动态申请二维数组
    int count = 0;
    for (int i =0; i < numsSize-2 && sortedNums[i] <=0; i++) {
        if (i > 0 && sortedNums[i] == sortedNums[i-1]) {
            continue;
        }
        for (int j =numsSize-1; j >i && sortedNums[j] >= 0; j--) {
            if (j < numsSize-1 && sortedNums[j] == sortedNums[j+1]) {
                continue;
            }
            
            int first = sortedNums[i];
            int second = sortedNums[j];
            int third = 0 - first - second;
            int dfsd =binary_search(sortedNums, i+1, j-1, third);
            if (dfsd == -1) {
                continue;
            }
            third = sortedNums[dfsd];
        

            int* sums = (int*)malloc(sizeof(int) * (3));
            sums[0] = first;
            sums[1] = second;
            sums[2] = third;
        
            if (count ==0) {
                count++;
                result=(int**)malloc(sizeof(sums)*count);
            }
            else{
                count++;
                result=(int**)realloc(result,sizeof(int*)*count);
            }
            result[count-1] = sums;
        }
    }
    *returnSize = count;
    return result;
}

مراجعة

الحصول على البرنامج هل تريد وظيفة مع شركة متعددة الجنسيات ناجحة؟ سوف تواجه الكثير من المنافسة. قبل عامين، تلقى بنك جولدمان ساكس ربع مليون طلب من الطلاب والخريجين. هذه ليست مجرد احتمالات شاقة بالنسبة للباحثين عن عمل؛ إنها مشكلة عملية للشركات. فإذا كان فريق مكون من خمسة من موظفي الموارد البشرية في جولدمان، يعملون 12 ساعة كل يوم، بما في ذلك عطلات نهاية الأسبوع، يقضون خمس دقائق في كل طلب، فإنهم سيستغرقون ما يقرب من عام لإكمال مهمة غربلة الطلبات.

هل تبحث عن وظيفة في شركة متعددة الجنسيات ناجحة؟ ثم عليك أن تواجه الكثير من المنافسة. قبل عامين، تلقى بنك جولدمان ساكس 250 ألف طلب عمل من الطلاب والخريجين. وهذا لا يجعل الباحثين عن عمل لديهم فرصة ضئيلة للنجاح فحسب، بل يجلب أيضًا مشكلة حقيقية للشركة. وعلى افتراض أن فريقاً من خمسة موظفين في قسم الموارد البشرية في جولدمان ساكس عملوا 12 ساعة يومياً، على مدار الساعة، وأمضوا خمس دقائق في كل طلب، فإن الأمر سيستغرق ما يقرب من عام لفحص هذا الكم الهائل من الطلبات.

ولا عجب إذن أن تستخدم أغلب الشركات الكبرى برنامج كمبيوتر، أو خوارزمية، عندما يتعلق الأمر بفحص المرشحين الباحثين عن وظائف مبتدئة. وهذا يعني أن المتقدمين سيستفيدون من معرفة ما تبحث عنه الخوارزميات بالضبط.

ليس من المستغرب أن تستخدم معظم الشركات الكبرى برنامج كمبيوتر، يُعرف باسم الخوارزمية، لفحص المرشحين للمناصب ذات المستوى الأدنى. وهذا يعني أن الباحثين عن عمل يمكنهم الاستفادة من معرفة ما تبحث عنه الخوارزمية بالضبط.

فيكتوريا ماكلين هي موظفة مصرفية سابقة ومديرة توظيف أنشأت شركة تسمى City CV، والتي تساعد المرشحين للوظائف في تقديم الطلبات. وتقول إن أنظمة تتبع المتقدمين (ATS) ترفض ما يصل إلى 75% من السير الذاتية، أو السيرة الذاتية، قبل أن يراها الإنسان. تبحث هذه الأنظمة عن الكلمات الرئيسية التي تلبي معايير صاحب العمل. إحدى النصائح هي دراسة اللغة المستخدمة في إعلان الوظيفة؛ إذا تم استخدام الأحرف الأولى PM لإدارة المشاريع، فتأكد من ظهور PM في سيرتك الذاتية.

أنشأت فيكتوريا ماكلين، وهي مديرة توظيف ومديرة توظيف مصرفية سابقة، شركة تدعى City CV لمساعدة الباحثين عن عمل في صياغة طلباتهم. وقالت إن نظام تتبع مقدم الطلب (ATS) يرفض ما يصل إلى 75% من الطلبات قبل أن يتمكن الإنسان من معالجة السيرة الذاتية. تبحث هذه الأنظمة عن الكلمات الرئيسية التي تتوافق مع معايير صاحب العمل. نصيحة سريعة هي البحث عن اللغة المستخدمة في إعلان الوظيفة. إذا تم استخدام الأحرف الأولى PM للإشارة إلى إدارة المشروع، فتأكد من وجود PM في سيرتك الذاتية.

وهذا يعني أن السيرة الذاتية العامة قد تقع عند العقبة الأولى. كان لدى السيدة ماكلين عميل كان عضوًا بارزًا في القوات المسلحة. وأشارت خبرته إلى الوظائف المحتملة في التدريب والتعليم أو المشتريات أو المبيعات الدفاعية. كانت أفضل استراتيجية هي إنشاء ثلاث سير ذاتية مختلفة باستخدام مجموعات مختلفة من الكلمات الرئيسية. ويحتاج الباحثون عن عمل أيضًا إلى التأكد من أن ملفهم الشخصي على LinkedIn وسيرتهم الذاتية يعززان بعضهما البعض؛ وتقول إن الغالبية العظمى من مسؤولي التوظيف سيستخدمون الموقع الإلكتروني للتحقق من مؤهلات المرشحين.

وهذا يعني أن السيرة الذاتية غير المستهدفة قد لا تتجاوز العقبة الأولى. كان لدى ماكلين عميل كان ضابطًا عسكريًا رفيع المستوى. انطلاقا من سيرته الذاتية، قد تكون لديه فرص عمل في التدريب والتعليم، أو المشتريات، أو مبيعات الأسلحة. وتقول إن أفضل استراتيجية هي إنشاء ثلاث سير ذاتية مختلفة باستخدام ثلاث مجموعات مختلفة من الكلمات الرئيسية. يحتاج المرشحون أيضًا إلى التأكد من أن ملفهم الشخصي على LinkedIn يطابق سيرتهم الذاتية، حيث تستخدم الغالبية العظمى من مسؤولي التوظيف الموقع للتحقق من مؤهلات المرشحين.

قد لا يكون اجتياز مرحلة ATS هو العائق التكنولوجي الوحيد أمام الباحثين عن عمل. تستخدم العديد من الشركات، بما في ذلك Vodafone وIntel، خدمة مقابلة فيديو تسمى HireVue. يتم اختبار المرشحين بينما يقوم برنامج الذكاء الاصطناعي (AI) بتحليل تعابير وجوههم (يُنصح بالحفاظ على التواصل البصري مع الكاميرا) وأنماط اللغة (الظهور بثقة هو الحيلة). من المرجح أن يفشل الأشخاص الذين يلوحون بأذرعهم أو يتراخون في مقاعدهم. فقط إذا نجحوا في اجتياز هذا الاختبار، سيلتقي المتقدمون ببعض البشر.

قد لا تكون ATS هي العقبة التقنية الوحيدة التي يواجهها الباحثون عن عمل. اعتمدت العديد من الشركات، بما في ذلك Vodafone وIntel، خدمة مقابلات الفيديو تسمى HireVue. عندما يجيب المرشحون على أسئلة الفيديو، تقوم برامج الذكاء الاصطناعي بتحليل تعبيرات الوجه (يوصى بالحفاظ على التواصل البصري مع الكاميرا) وأنماط الكلام (الظهور بمظهر واثق هو المفتاح). من المرجح أن يفشل الأشخاص الذين يلوحون بأذرعهم أو يجلسون في وضعية متراخية. فقط بعد اجتياز هذا الاختبار يمكن للباحث عن عمل مقابلة بعض المحاورين.

قد تتوقع أن تكون برامج الذكاء الاصطناعي قادرة على تجنب بعض التحيزات في أساليب التوظيف التقليدية، وخاصة ميل القائمين على إجراء المقابلات إلى تفضيل المرشحين الذين يشبهون الشخص الذي يجري المقابلة. ومع ذلك، فإن التمييز يمكن أن يظهر بطرق غير متوقعة. قامت أنجا لامبرشت وكاثرين تاكر، وهما خبيرتان اقتصاديتان، بوضع إعلانات تروج لوظائف في مجالات العلوم والتكنولوجيا والهندسة والرياضيات على فيسبوك. ووجدوا أن احتمال عرض الإعلانات للنساء أقل من عرضها للرجال.

ربما كنت تعتقد أن برنامج الذكاء الاصطناعي سيكون قادرًا على تجنب بعض التحيزات الموجودة في طرق التوظيف التقليدية، وخاصة ميل القائمين على المقابلات إلى اختيار المرشحين الذين يشبهونهم. ومع ذلك، فإن التمييز يمكن أن يظهر بطرق غير متوقعة. نشر اثنان من الاقتصاديين، أنجا لامبرشت وكاترين تاكر، إعلانات على فيسبوك تروج لفرص العمل في مجالات العلوم والتكنولوجيا والهندسة والرياضيات. ووجدوا أن هذه الإعلانات من المرجح أن يتم تقديمها للرجال أكثر من النساء.لم يكن هذا بسبب التحيز الواعي من جانب خوارزمية فيسبوك. بل إن النساء الشابات يشكلن مجموعة ديموغرافية أكثر قيمة على فيسبوك (لأنهن يسيطرن على حصة كبيرة من إنفاق الأسر) وبالتالي فإن الإعلانات التي تستهدفهن أكثر تكلفة. استهدفت الخوارزميات بشكل طبيعي الصفحات التي يكون فيها عائد الاستثمار أعلى: للرجال، وليس للنساء.

وهذا ليس نتيجة للتحيز الواعي في خوارزمية فيسبوك. وفي المقابل، تشكل النساء الشابات مجموعة أكثر قيمة على فيسبوك (لأنهن يسيطرن على جزء كبير من إنفاق الأسرة)، وبالتالي فإن الإعلانات التي تستهدفهن تكون أكثر تكلفة. تستهدف هذه الخوارزميات بشكل طبيعي الصفحات ذات أعلى عائد على الاستثمار: الرجال، وليس النساء.

في كتابهم* عن الذكاء الاصطناعي، يقول أجاي أجراوال، وجوشوا جانز، وآفي جولدفارب من كلية روتمان للإدارة في تورنتو، إن الشركات لا يمكنها ببساطة تجاهل مثل هذه النتائج باعتبارها أثرًا جانبيًا مؤسفًا لطبيعة “الصندوق الأسود” للخوارزميات. إذا اكتشفوا أن مخرجات نظام الذكاء الاصطناعي تمييزية، فعليهم معرفة السبب، ثم ضبط الخوارزمية حتى يختفي التأثير.

كتب أجاي أجراوال، وجوشوا غانز، وآفي جولدفارب من كلية روتمان للإدارة بجامعة تورنتو في مؤلفهم المشارك حول الذكاء الاصطناعي* أن الشركات لا يمكنها ببساطة رفض مثل هذه النتائج باعتبارها أثرًا جانبيًا مؤسفًا لطبيعة “الصندوق الأسود” للخوارزميات. إذا وجدوا أن مخرجات نظام الذكاء الاصطناعي تمييزية، فيجب عليهم معرفة السبب ثم ضبط الخوارزمية حتى يختفي التأثير.

وقد ظهرت المخاوف بشأن التحيز المحتمل في أنظمة الذكاء الاصطناعي في مجموعة واسعة من المجالات، من العدالة الجنائية إلى التأمين. وفي التوظيف أيضاً، ستواجه الشركات مخاطر قانونية ومخاطر تتعلق بالسمعة إذا تبين أن أساليب التوظيف التي تتبعها غير عادلة. لكنهم بحاجة أيضًا إلى النظر في ما إذا كانت البرامج تفعل أكثر من مجرد تبسيط العملية. على سبيل المثال، هل يتمتع المرشحون الناجحون بمهن طويلة ومثمرة؟ ففي نهاية المطاف، يعد رحيل الموظفين أحد أكبر تكاليف التوظيف التي تواجهها الشركات.

وقد أثار احتمال التحيز من أنظمة الذكاء الاصطناعي المخاوف في العديد من المجالات، من العدالة الجنائية إلى التأمين. وينطبق الشيء نفسه على توظيف الموظفين. إذا استخدمت الشركات أساليب توظيف غير عادلة، فإنها ستواجه مخاطر قانونية ومخاطر تتعلق بالسمعة. لكنهم بحاجة أيضًا إلى النظر في ما إذا كانت هذه البرامج قادرة على القيام بأكثر من مجرد تبسيط عملية التوظيف. على سبيل المثال، هل سيبقى المرشح الناجح في الشركة لفترة طويلة وبشكل منتج؟ بعد كل شيء، يعد معدل دوران الموظفين أحد أكبر تكاليف التوظيف التي تواجهها الشركات.

وقد يكون هناك أيضًا سباق تسلح حيث يتعلم المرشحون كيفية ضبط سيرهم الذاتية لاجتياز اختبار الذكاء الاصطناعي الأولي، وتتكيف الخوارزميات لغربلة المزيد من المرشحين. وهذا يخلق المجال لتحيز محتمل آخر: قد يكون المرشحون من الأسر الميسورة (ومن مجموعات معينة) أسرع في تحديث سيرتهم الذاتية. وفي المقابل، قد يتطلب هذا من الشركات تعديل خوارزمياتها مرة أخرى لتجنب التمييز. ومن المرجح أن يكون ثمن الذكاء الاصطناعي هو اليقظة الأبدية.

وبينما يتعلم المرشحون كيفية تعديل سيرتهم الذاتية لاجتياز اختبار الذكاء الاصطناعي الأولي، وتتحسن الخوارزميات لتصفية المزيد من المتقدمين، فقد يؤدي ذلك إلى إشعال سباق تسلح. وهذا يخلق مجالاً لتحيز محتمل آخر: قد يتمكن المرشحون من العائلات الأكثر ثراءً (ومجموعات معينة) من تحديث سيرتهم الذاتية بسرعة أكبر. وفي المقابل، قد تحتاج الشركات إلى تعديل خوارزمياتها مرة أخرى لتجنب التمييز. يبدو أن ثمن استخدام الذكاء الاصطناعي هو اليقظة الدائمة.

نصائح:

كيفية تنفيذ أحجام قوس مختلفة في زوايا مختلفة من العرض

قم بقص جميع الزوايا الأربع اليمنى للمنظر إلى زوايا مستديرة:

    //设置圆角半径值    
    self.view.layer.cornerRadius  = 10.f;    
    //设置为遮罩,除非view有阴影,否则都要指定为YES的    
    self.view.layer.masksToBounds = YES;
  1. قص الزاوية اليمنى للعرض إلى زاوية مستديرة:
    //把 view2 的 左下角 和 右下角的直角切成圆角    
    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(120,10,80,80)];    
    view2.backgroundColor = [UIColor redColor];    
    [self.view addSubview:view2];        
    //设置切哪个直角
    //    UIRectCornerTopLeft     = 1 << 0,  左上角
    //    UIRectCornerTopRight    = 1 << 1,  右上
    //    UIRectCornerBottomLeft  = 1 << 2,  左下角
    //    UIRectCornerBottomRight = 1 << 3,  右下角
    //    UIRectCornerAllCorners  = ~0UL     全部角    
    //得到view的遮罩路径    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view2.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(10,10)];    
    //创建 layer    
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];    
    maskLayer.frame = view2.bounds;    
//赋值    
maskLayer.path = maskPath.CGPath;

الزوايا الدائرية التي تم ضبطها بالطريقة المذكورة أعلاه لها نفس القوس لكل زاوية مستديرة. فكيف يمكن تحقيق أربع زوايا بأحجام مختلفة للزوايا المستديرة؟ المفتاح لتحقيق الزوايا الدائرية أعلاه هو مسار CAShapeLayer، لذلك نحتاج فقط إلى تخصيص هذا المسار. التنفيذ على النحو التالي:

- (void)setViewRadius:(UIView  *)view{
    CGFloat topLeftRadius = 50;
    CGFloat topRightRadius = 60;
    CGFloat bottomRightRadius = 40;
    CGFloat bottomLeftRadius = 30;
    
    CGFloat minx = CGRectGetMinX(view.bounds);
    CGFloat miny = CGRectGetMinY(view.bounds);
    CGFloat maxx = CGRectGetMaxX(view.bounds);
    CGFloat maxy = CGRectGetMaxY(view.bounds);
    
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(minx + topLeftRadius, miny)];
    
    [path addLineToPoint:CGPointMake(maxx - topRightRadius, miny)];
    [path addArcWithCenter:CGPointMake(maxx - topRightRadius, miny + topRightRadius) radius: topRightRadius startAngle: 3 * M_PI_2 endAngle: 0 clockwise: YES];
    
    [path addLineToPoint:CGPointMake(maxx, maxy - bottomRightRadius)];
    [path addArcWithCenter:CGPointMake(maxx - bottomRightRadius, maxy - bottomRightRadius) radius: bottomRightRadius startAngle: 0 endAngle: M_PI_2 clockwise: YES];
    
    [path addLineToPoint:CGPointMake(minx + bottomLeftRadius, maxy)];
    [path addArcWithCenter:CGPointMake(minx + bottomLeftRadius, maxy - bottomLeftRadius) radius: bottomLeftRadius startAngle: M_PI_2 endAngle:M_PI clockwise: YES];
    
    [path addLineToPoint:CGPointMake(minx, miny + topLeftRadius)];
    [path addArcWithCenter:CGPointMake(minx + topLeftRadius, miny + topLeftRadius) radius: topLeftRadius startAngle: M_PI endAngle:3 * M_PI_2 clockwise: YES];
    
    [path closePath];
    
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.path = path.CGPath;
    view.layer.mask = maskLayer;

قدم عرضًا توضيحيًا آخر لـ UIView لتنفيذ لون التدرج.

 UIColor *frameColor = [UIColor colorWithHexString:@"#FFB300"];
            UIColor *toColor = [UIColor colorWithHexString:@"#FF6100"];
            CAGradientLayer *gradientLayer = [CAGradientLayer layer];
            gradientLayer.locations = @[@0.0, @1.0];
            gradientLayer.startPoint = CGPointMake(0, 0);
            gradientLayer.endPoint = CGPointMake(1.0, 0);
            gradientLayer.frame = _bgImageView.bounds;
            gradientLayer.colors = @[(__bridge id)frameColor.CGColor, (__bridge id)toColor.CGColor];
            [_bgImageView.layer insertSublayer:gradientLayer atIndex:0];

شارك:

هناك أسئلة وأجوبة من Zhihu تنتشر اليوم، ~~ هل يتخلف بناء التكنولوجيا في Tencent حاليًا (في 2018) عن الشركات من نفس الحجم؟ ~~,yأصبحت الإجابة المسماة “toughguy” شائعة، ولكن تم حذف إجابة المؤلف بعد يوم من نشرها. ومع ذلك، هناك نسخة احتياطية عبر الإنترنت. إذا كنت مهتما، يمكنك البحث عنه.

اسمحوا لي أن أشارككم أفكاري حول هذه القضية:

يتحدث المقال عن ضعف التكنولوجيا، وعدم كفاية احتياطيات المواهب، والتسوية التكنولوجية، والقواعد واللوائح الداخلية الصارمة نسبيًا داخل الشركة. الشركة التي أعمل بها هي في الواقع هكذا. العديد من أنظمة الشركة لا تساعد على تطوير تكنولوجيا الشركة. العديد من القادة الصغار في الشركة هم من كبار السن الذين يعملون في الشركة منذ أكثر من 5 سنوات. مهاراتهم متوسطة وقد نجوا. بعضهم لا يعرف Git ولا يزال يستخدم SVN. لا أحد يجرؤ على إعادة بناء الكود لأنه لا توجد حالات اختبار. إذا قمت بتصحيح الخلل، عليك أن تتحمل المسؤولية. موقف القائد هو أنه يمكن استخدامه.

ويمكن القول أن المستوى الفني للفريق يعتمد على قيادة الفريق. إذا كان نمط القيادة كبيرا بما فيه الكفاية والقدرة قوية بما فيه الكفاية، فإن الإبداع لدى الفريق بأكمله سيكون قويا.

فإذا كان القائد راضياً عن نفسه، ويسعى إلى تحقيق الاستقرار، ويمنع الآخرين من استخدام التكنولوجيات الجديدة دون إحراز أي تقدم، فهو مخطئ ويجب أن يغادر في أقرب وقت ممكن.

في شركة كبيرة، يصعب على المبرمج الشعبي تغيير هذا الوضع. أعتقد أن الطريقة الوحيدة لتغيير هذا الوضع هي من القيادة.

هناك أيضا مسألة العمل الإضافي. في الواقع، الكثير من العمل الإضافي في الشركات الكبيرة ليس بسبب عدم إمكانية إكمال العمل، ولكن لأن الشركة تستخدم هذا كمعيار لقياس عبء العمل. بهذه الطريقة، بغض النظر عما يحدث، يجب أن يكون هناك ما يكفي من العمل الإضافي. المعروف باسم مشروع الوجه.