阅读助手

  • 写在前面
  • 赛题介绍
  • 个人赛况
  • 代码开源-score 1.2+
    • 【00】数据导入TI-ONE
    • 【01】按userid聚合(groupby)特征
    • 【02】word2vec训练
    • 【03】数据特征化
    • 【04】lgb模型训练
    • 【05】test分批次预测
    • 【06】合并和提交到COS存储桶
  • 参考资料

写在前面

全文共计11958字,请合理使用目录(阅读助手)辅助阅读

《2020腾讯广告算法大赛》复赛已经接近尾声,作为一瓶初赛酱油,打算做个复盘,留个笔记,本来初赛结束就打算写的,被各种事情耽搁了,直到今天才动手开写

先说下个人情况:某电商公司任职,数据分析方向,做的大部分是DBA和爬虫的活(从过往博客也看的出来),了解过sklearn库的一些传统机器学习(eg:决策树、随机森林、Kmeans、逻辑回归等基础传统机器学习算法),(卷积)神经网络,lgb,lstm,W2V,RNN等都是在比赛过程中听大佬们分享后现学的(虽然还是不太会用,原理也推不出来,至少比一开始听见这些词都一脸懵逼要好太多太多 了),

可以说是算法纯小白,最终成绩:score — 1.269806;排名 — 367

赛题介绍

题目:广告受众基础属性预估

赛题描述
本届算法大赛的题目来源于一个重要且有趣的问题。众所周知,像用户年龄和性别这样的人口统计学特征是各类推荐系统的重要输入特征,其中自然也包括了广告平台。这背后的假设是,用户对广告的偏好会随着其年龄和性别的不同而有所区别。许多行业的实践者已经多次验证了这一假设。然而,大多数验证所采用的方式都是以人口统计学属性作为输入来产生推荐结果,然后离线或者在线地对比用与不用这些输入的情况下的推荐性能。本届大赛的题目尝试从另一个方向来验证这个假设,即以用户在广告系统中的交互行为作为输入来预测用户的人口统计学属性。

我们认为这一赛题的“逆向思考”本身具有其研究价值和趣味性,此外也有实用价值和挑战
性。例如,对于缺乏用户信息的实践者来说,基于其自有系统的数据来推断用户属性,可以帮助其在更广的人群上实现智能定向或者受众保护。与此同时,参赛者需要综合运用机器学习领域的各种技术来实现更准确的预估。

具体而言,在比赛期间,我们将为参赛者提供一组用户在长度为91天(3 个月)的时间窗
口内的广告点击历史记录作为训练数据集。每条记录中包含了日期(从1到91)、用户信息(年龄,性别),被点击的广告的信息(素材 id、广告 id、产品 id、产品类目 id、广告主id、广告主行业id等),以及该用户当天点击该广告的次数。测试数据集将会是另一组用户的广告点击历史记录。提供给参赛者的测试数据集中不会包含这些用户的年龄和性别信息。

本赛题要求参赛者预测测试数据集中出现的用户的年龄和性别,并以约定的格式提交预测结果。大赛官网后台将会自动计算得分并排名。详情参见【评估方式】和【提交方式】。
初赛和复赛除了所提供的训练数据集的量级有所不同之外,其他设置均相同。

提交方式
参赛者提交的结果为一个带标题行的 submission.csv 文件,编码采用无 BOM 的 UTF-8,
具体格式如下(字段顺序以下面的描述为准,各字段用逗号分隔,中间无空格):
⚫ user_id
⚫ predicted_age: 预测的用户年龄分段,取值范围[1,10]。
⚫ predicted_gender: 预测的用户性别,取值范围[1,2]。
测试数据集中每个用户均应在submission.csv文件中对应有且仅有一行预测结果。各用户
的预测结果在该文件中的出现顺序与评估结果无关。

评估方式
大赛会根据参赛者提交的结果计算预测的准确率(accuracy)。年龄预测和性别预测将分别评估准确率,两者之和将被用作参赛者的打分。

测试数据集会和训练数据集一起提供给参赛者。大赛会将测试数据集中出现的用户划分为两组,具体的划分方式对参赛者不可见。其中一组用户将被用于初赛和复赛阶段除最后一天之外的排行榜打分计算,另一组则用于初赛和复赛阶段最后一天的排行榜打分计算,以及最后的胜出队伍选择。

2020腾讯算法大赛初赛数据集下载【提取码:46lw】

个人赛况

阶段一:score 0.89+
①3+1
descirbe() 对train训练数据描述可得 年龄age3的概率最大,性别gender1的概率最大
直接提交 预测结果age3+gender1 score就可达到0.893+

②word2vec训练参数错误
在参考了各路大佬的w2v方案后依然没有突破 0.89,一度弃赛,在某个月黑风高的夜晚,突然来了一手神来之笔,查看W2V训练后的词向量,结果发现训练出来的词向量是0-9,

阶段二:score 1.2+
word2vec+Lgb
纠正了word2vec训练的词向量之后就达到了1.2+
由于深度学习啥也不懂,还是没有达到大佬们的baseline

解题思路(代码思路)——copy的各路大佬的基本思路:
把每个点击的广告id当作一个词,把一个人90天内点击的广告id列表当作一个句子,使用word2vec来制作一个“word embedding”,把问题转化成一个NLP题目;把广告id的embedding喂入lgb——一度试图把所有的的特征组合训练wordembedding,keras内存爆炸 ,后来试了挑选三个进行组合,score反而下降了,可能组合姿势有问题

代码开源-score 1.2+

【00】数据导入TI-ONE

#安装&导入库
!pip install wget
import wget,tarfile,zipfile#压缩数据包下载
filename = wget.download("https://tesla-ap-shanghai-1256322946.cos.ap-shanghai.myqcloud.com/cephfs/tesla_common/deeplearning/dataset/algo_contest/train_preliminary.zip")
print(filename)#解压缩
zFile = zipfile.ZipFile(filename, "r")
for fileM in zFile.namelist():zFile.extract(fileM, "./")print(fileM)
zFile.close();

【01】按userid聚合(groupby)特征

#导入库
import tensorflow as tf
import pandas as pd
import numpy as np
import gc#聚合去重并计数
def get_groupby_data(data,group_zd='user_id',pj_zd='ad_id'):data_dict=dict(list(data.groupby(group_zd)))result=[]for key in data_dict.keys():result.append([key,str(data_dict[key][pj_zd].to_list())[1:-1].replace(',','')])pd_result=pd.DataFrame(result)pd_result.columns=[group_zd,pj_zd]return pd_result#设置聚合特征
# zd_list=['ad_id','product_category','advertiser_id', 'time', 'click_times']
zd_list=['creative_id']#train_data读取
train_ad=pd.read_csv("../train_preliminary/ad.csv",na_values="\\N")
train_click_log=pd.read_csv("../train_preliminary/click_log.csv",na_values="\\N")
train_user=pd.read_csv("../train_preliminary/user.csv",na_values="\\N")
data=pd.merge(pd.merge(train_ad,train_click_log),train_user)#内存清理
del train_ad,train_click_log
gc.collect()#train_data聚合
for zd in zd_list:new_data=data[[zd,'user_id']]new_data=get_groupby_data(new_data,pj_zd=zd)new_data=pd.merge(new_data,train_user)new_data.to_csv(zd+"/groupby_data/train_%s.csv"%zd,index=False)print("-"*10+zd+'汇总完成'+'-'*10)#test_data读取
test_ad=pd.read_csv("../test/ad.csv")
test_click_log=pd.read_csv("../test/click_log.csv")
test_data=pd.merge(test_ad,test_click_log)#test_data聚合
for zd in zd_list:test_data_new=test_data[[zd,'user_id']]test_data_new=get_groupby_data(test_data_new,pj_zd=zd)    test_data_new.to_csv(zd+"/groupby_data/test_%s.csv"%zd,index=False)print("-"*10+zd+'汇总完成'+'-'*10)

【02】word2vec训练

#导入库
import tensorflow as tf
import pandas as pd
import numpy as np
import os
!pip install gensim
import gc
from gensim.models.word2vec import Word2Vec# 设定词向量训练的参数
num_features = 128   # Word vector dimensionality
min_word_count = 0   # Minimum word count
num_workers = 4       # Number of threads to run in parallel
context = 10         # Context window size
model_name = '{}features_{}minwords_{}context.model'.format(num_features, min_word_count, context)#设置训练特征
# zd_list=['creative_id','ad_id','product_category','advertiser_id', 'time', 'click_times']
zd_list=['creative_id']#词向量训练
for zd in zd_list:new_data=pd.read_csv(zd+"/groupby_data/train_%s.csv"%zd,na_values="\\N")new_data2=pd.read_csv(zd+"/groupby_data/test_%s.csv"%zd,na_values="\\N")new_data3=pd.concat([new_data,new_data2])del new_data,new_data2gc.collect()#清理内存sentences_list = []#注意:需要split传入list,第一次没有split训练的词模型是0-9for line in new_data3[zd]:sentences_list.append(line.split())model = Word2Vec(sentences_list, workers=num_workers, \size=num_features, min_count = min_word_count, \window = context)model.save(os.path.join(zd, 'models', model_name))print("-"*10+zd+'训练完成'+'-'*10)

【03】数据特征化

#导入库
import tensorflow as tf
import pandas as pd
import numpy as np
import os
!pip install gensim
from gensim.models.word2vec import Word2Vecdef to_review_vector(review):global word_vecword_vec = np.zeros((1,300))for word in review.split():#word_vec = np.zeros((1,300))if word in fastmodel:word_vec += np.array([fastmodel[word]])#print (word_vec.mean(axis = 0))return pd.Series(word_vec.mean(axis = 0))#由于机器限制,数据分段特征化&存储
#zd_list=['creative_id','ad_id','product_category','advertiser_id', 'time', 'click_times']
model_name='300features_0minwords_10context.model'
# zd_list=['product_category','advertiser_id', 'time', 'click_times']
zd_list=['creative_id']
for zd in zd_list:data=pd.read_csv(zd+"/groupby_data/train_%s.csv"%zd)try:os.mkdir(zd+"/train_feature")except:passfastmodel=Word2Vec.load(zd+'/models/'+model_name)count=0mm=0for i in range(100000,len(data)+1,100000):train_data_features = data[count:i][zd].apply(to_review_vector)w2c_data=pd.concat([data[count:i][['user_id','age','gender']],train_data_features],axis=1)w2c_data.to_csv(zd+"/train_feature/w2c_data_%s%s.csv"%(zd,mm),index=False)print("---%s第 %s 段数据特征向量化完成---"%(zd,mm))mm+=1count=i

【04】lgb模型训练

#导入库
!pip install lightgbm
import lightgbm as lgb
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import tensorflow as tf
import pandas as pd
import numpy as np
import os
import gc# zd_list=['creative_id','ad_id','product_category','advertiser_id','time','click_times']
zd_list=['creative_id']#分段特征数据合并
for zd in zd_list:path=zd+"/train_feature/"wjs=os.listdir(path)data=pd.DataFrame()for wj in wjs:data_path=path+wjdata0=pd.read_csv(data_path)#.drop(zd,axis=1)data=data.append(data0)print(len(data))data.columns=[zd+'_'+cc if cc not in ['user_id', 'age', 'gender'] else cc for cc in data.columns]if zd==zd_list[0]:data1=dataelse:data1=pd.merge(data1,data)gc.collect()#清理内存print('!'*10+zd+'拼接完成')#内存清理
del data,data0
gc.collect()#age模型训练
train_x=data1[data1.columns.difference(['user_id','age','gender'])]
target=data1.age.astype(int)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(train_x, target, test_size=0.2)
del train_x,data1
gc.collect()#清理内存
print("Train data length:", len(X_train))
print("Test data length:", len(X_test))
# 转换为Dataset数据格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)# 参数
params = {'task': 'train','boosting_type': 'gbdt',  # 设置提升类型'objective': 'multiclass',  # 目标函数'num_class': 11,
#     'metric': {'l2', 'auc'},  # 评估函数'num_leaves': 31,  # 叶子节点数'learning_rate': 0.05,  # 学习速率'feature_fraction': 0.9,  # 建树的特征选择比例'bagging_fraction': 0.8,  # 建树的样本采样比例'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging'verbose': 1  # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
}# 模型训练
gbm = lgb.train(params, lgb_train, num_boost_round=1000, valid_sets=lgb_eval, early_stopping_rounds=5)
# 模型保存
gbm.save_model('model_age.txt'
# 模型加载
gbm = lgb.Booster(model_file='model_age.txt')
# 模型预测
y_prob = gbm.predict(X_test, num_iteration=gbm.best_iteration)arr=pd.DataFrame(y_prob)
arr['max_value']=arr.max(axis=1)
arr['max_index']=np.argmax(y_prob,axis=1)
y_pred1=arr['max_index']# 模型评估
print('The rmse of prediction is:', mean_squared_error(y_test,y_pred1) ** 0.5)#gender模型训练
train_x=data1[data1.columns.difference(['user_id','age','gender'])]
target=data1.gender.astype(int)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(train_x, target, test_size=0.2)
del train_x,data1
gc.collect()#清理内存
print("Train data length:", len(X_train))
print("Test data length:", len(X_test))
# 转换为Dataset数据格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)# 参数
params = {'task': 'train','boosting_type': 'gbdt',  # 设置提升类型'objective': 'multiclass',  # 目标函数'num_class': 11,
#     'metric': {'l2', 'auc'},  # 评估函数'num_leaves': 31,  # 叶子节点数'learning_rate': 0.05,  # 学习速率'feature_fraction': 0.9,  # 建树的特征选择比例'bagging_fraction': 0.8,  # 建树的样本采样比例'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging'verbose': 1  # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
}# 模型训练
gbm = lgb.train(params, lgb_train, num_boost_round=1000, valid_sets=lgb_eval, early_stopping_rounds=5)
# 模型保存
gbm.save_model('model_gender.txt')
# 模型加载
gbm = lgb.Booster(model_file='model_gender.txt')
# 模型预测
y_prob = gbm.predict(X_test, num_iteration=gbm.best_iteration)arr=pd.DataFrame(y_prob)
arr['max_value']=arr.max(axis=1)
arr['max_index']=np.argmax(y_prob,axis=1)
y_pred1=arr['max_index']# 模型评估
print('The rmse of prediction is:', mean_squared_error(y_test,y_pred1) ** 0.5)

【05】test分批次预测

#导入库
!pip install lightgbm
import lightgbm as lgb
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import tensorflow as tf
import pandas as pd
import numpy as np
import gc
import os# zd_list=['creative_id','ad_id','product_category','advertiser_id', 'time', 'click_times']
zd_list=['creative_id']
for zd in zd_list:path=zd+"/test_feature/"wjs=os.listdir(path)
#     wjs=os.listdir(path)[5:]data=pd.DataFrame()for wj in wjs:data_path=path+wjdata0=pd.read_csv(data_path).drop(zd,axis=1)data=data.append(data0)del data0gc.collect()#清理内存print(len(data))data.columns=[zd+'_'+cc if cc not in ['user_id'] else cc for cc in data.columns]
#     data.columns=[zd+'_'+cc if cc not in ['user_id', 'age', 'gender'] else cc for cc in data.columns]if zd==zd_list[0]:data1=dataelse:data1=pd.merge(data1,data)del datagc.collect()#清理内存print('!'*10+zd+'拼接完成')# data1=data1[:500000]
data1=data1[500000:]result=data1[['user_id']].reset_index(drop=True)
test_X=data1[data1.columns.difference(['user_id'])]
del data1
gc.collect()#清理内存
# 模型加载
gbm = lgb.Booster(model_file='model_age.txt')
# 模型预测
y_test = gbm.predict(test_X, num_iteration=gbm.best_iteration)
arr=pd.DataFrame(y_test)
arr['max_value']=arr.max(axis=1)
arr['max_index']=np.argmax(y_test,axis=1)
result['age']=arr['max_index']# 模型加载
gbm = lgb.Booster(model_file='model_gender.txt')
# 模型预测
y_test = gbm.predict(test_X, num_iteration=gbm.best_iteration)
arr=pd.DataFrame(y_test)
arr['max_value']=arr.max(axis=1)
arr['max_index']=np.argmax(y_test,axis=1)
result['gender']=arr['max_index']result.columns=['user_id','predicted_age','predicted_gender']
# result.to_csv('submission1.csv',index=False)
result.to_csv('submission2.csv',index=False)
print(len(result))

【06】合并和提交到COS存储桶

import pandas as pd
import numpy as np#文件合并
data1=pd.read_csv("submission1.csv")
data2=pd.read_csv("submission2.csv")
data=pd.concat([data1,data2])
print(len(data))
data.to_csv("submission.csv",index=False)from ti import session
ti_session = session.Session()
# path:结果文件的路径
# bucket:指定存储桶。
# key_prefix:存储桶下的 cos 路径
inputs = ti_session.upload_data(path="submission.csv", bucket="game-gt-1252065438", key_prefix="test")

参考资料

【00】如何使用 TI-ONE Notebook 玩转算法大赛

【01】易观性别年龄预测chizhu大佬的冠军开源

【02】2020腾讯广告算法大赛:赛题理解与解题思路

【03】2020腾讯广告算法大赛基本思路(线上1.3+)

【04】2020腾讯广告算法大赛:如何突破分数瓶颈?

【05】2020腾讯广告算法大赛:高分进阶

【06】大神干货:冠军选手分享解题思路,助你轻松突围初赛

【07】高分选手讲解:如何突破思维圈限,从NLP角度挖掘新的解题思路

【08】超值赛题分享大礼包,你的“六一”礼物来咯!

【09】【王牌选手分享】一发问鼎!鹅厂大神上分思路,助你玩转初赛!

【10】【前排选手分享】初赛尾声将至,大神带你最后一搏!

【11】【特色团队采访】1+1+1>3?看新人团队如何高效合作

特别感谢各位大佬的分享,虽然最终没进复赛,也算感受了一波算法的魅力,尤其感谢鱼佬的耐心解惑;最后还得特别感谢下腾讯智能钛机器学习 TI-ML,要不然我那渣渣机器连 数据都读不完就内存溢出了,确实挺好用的,我只用了notebook,已经集成好了tensflow环境,贼方便,还有其他机器学习操作,没玩转,对notebook比较熟!全程都是notebook,而且对于社畜而言还有个好处就是云上同步,不论在哪我都不用把代码倒腾过来倒腾过去,只要连网就可以看到你原先操作的代码,甚至于在公司点了运行,坐个地铁到家直接登陆看结果!从一开始感觉特别麻烦不习惯,到最后的”真香"!!!没人逃得掉王镜泽定律(没收鹅厂广告费 ,麻烦腾讯云看到了给打笔广告费)

2020腾讯广告算法大赛——算法小白的复盘相关推荐

  1. 2020腾讯广告算法大赛十强名单出炉!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale推荐 2020年腾讯广告算法大赛 - 决赛答辩 经过近3个月的激烈角逐,202 ...

  2. 2020 腾讯广告算法大赛:突破高分瓶颈方案分享

    写在前面 期待已久的2020腾讯广告算法大赛终于开始了,本届赛题"广告受众基础属性预估".本文将给出解题思路,以及最完备的竞赛资料,助力各位取得优异成绩!!! 报名链接:https ...

  3. 2020腾讯广告算法大赛:赛题理解与解题思路

    写在前面 期待已久的2020腾讯广告算法大赛终于开始了,本届赛题"广告受众基础属性预估".本文将给出解题思路,以及最完备的竞赛资料,助力各位取得优异成绩!!! 报名链接:https ...

  4. 百万奖池,鹅厂offer,2020腾讯广告算法大赛等你来战!

    允中 发自 凹非寺  量子位 编辑 | 公众号 QbitAI 2020腾讯广告算法大赛再度起航,即日起至5月31日,赛事正式面向全社会启动线上招募,一场算法之间的"巅峰对决"即将上 ...

  5. 【竞赛经验分享】2020腾讯广告算法大赛:如何突破分数瓶颈?

    写在前面 期待已久的2020腾讯广告算法大赛终于开始了,本届赛题"广告受众基础属性预估".本文将给出解题思路,以及最完备的竞赛资料,助力各位取得优异成绩!!! 报名链接:https ...

  6. 备战2020腾讯广告算法大赛:(2017-2019比赛开源和数据等)

    期待与各位在2020腾讯社交广告算法大赛中相遇!!! 写在前面 最近突然之间讨论腾讯广告赛的人多了不少,也有很多人加我微信讨论19年腾讯赛的方案和代码.虽然2020腾讯赛还未开始,不过大家已经提前进入 ...

  7. 最强战队出炉,2020腾讯广告算法大赛圆满落幕

    8月3日,2020腾讯广告算法大赛决赛在深圳腾讯滨海大厦顺利举行. 十强战队集结腾讯,花式解密"逆算"难题. 腾讯广告副总裁蒋杰.微众银行首席AI官杨强.科大讯飞副总裁刘鹏.腾讯数 ...

  8. 万人报名2020腾讯广告算法大赛,顶级技术争锋正式开战!

    由腾讯广告携手腾讯云.腾讯大数据.腾讯招聘及腾讯高校合作等合作伙伴举办的2020腾讯广告算法大赛,报名阶段于5月31日正式结束.自4月15日赛事开展至今,本届赛事已成功吸引2万多名技术人才高度关注.最 ...

  9. 谁与争锋,2020腾讯广告算法大赛初赛正式启动

    5月7日,2020腾讯广告算法大赛进入初赛赛段,汇聚了近万名多领域技术人才的硬核算法比拼正式开启! 为了更有效地推动产学研的交流与融合,培养技术人才.本届算法大赛通过"逆向思考"巧 ...

  10. 冠军奖金50万,2020腾讯广告算法大赛广发“英雄帖”

    由腾讯广告主办,腾讯云.腾讯大数据.腾讯招聘及腾讯高校合作等合作伙伴联袂举办的2020腾讯广告算法大赛现已启动,5月31日前皆可报名参加! 百万奖金池重磅加码,"逆算"赛题趣味竞技 ...

最新文章

  1. NotFoundError: Unsuccessful TensorSliceReader constructor: Failed to find any matching files for xxx
  2. 大战设计模式【17】—— 建造者模式
  3. Elasticsearch概述、ES概念、什么是搜索、全文检索、Elasticsearch功能,什么是distributed document store(来自网络+学习资料)
  4. SpringCloud与子项目版本兼容说明
  5. JSP常用Form表单控件
  6. SpringMVC 异步交互 AJAX 文件上传
  7. 【clickhouse】Clickhouse 查询之 Array JOIN
  8. 如何优化cocos2d/x程序的内存使用和程序大小
  9. Strut2页面传参跳转 --Struts2
  10. 汕尾python高手_每天两小时,下一个python 高手就是你!满满都是干货
  11. 电影院售票系统,电影院订票系统,电影院购票管理系统计算机毕业设计
  12. [转贴]记那对住在我隔壁储藏室的大学刚毕业的小夫妻
  13. 推荐一个文字生成图片的网站
  14. python常见运算符
  15. 【转】SLAM 论文阅读和分类整理
  16. 《计算机视觉中的数学方法》
  17. NVMe over TCP 香吗?
  18. 雅可比(Jacobi)计算特征值和特征向量
  19. 王道2021版计算机考研书勘误表
  20. eclipse链接Hadoop集群时报错Error:Call From xxx/xxx.xxx.xxx.xxx to hostname1:9000 failed on connection excep

热门文章

  1. Multisim基础 调出面包板
  2. dos命令中DATE:~0,10输出日期格式名称格式/改为-
  3. 将Windows10中的C盘desktop移到D盘
  4. SSO单点登录基本概念实现思路以及小的实例详解
  5. java中的this是什么意思
  6. DBA 小记 — 分库分表、主从、读写分离
  7. mysql dump gtid_GTID环境下mysqldump set-gtid-purged取值
  8. c语言累加和求平均数程序,c语言编程:连续输入若干个正整数,求其和及其平均值,直到输入0结束....
  9. 如何在MAC上查看系统运行信息、内存使用率等
  10. 阿里巴巴高级Java面试题(首发,70道)