程序员徐公

微信公众号:【徐公】

0%

刚过完年,不知道大家有没有在春节档期间,跟家人一起观看《流浪地球2》,里面的MOSS,是一款强大的智能机器人。那么当时我们就可以联想到的最近发布的ChatGPT,同样作为一款现实中的人工智能自然语言处理工具,虽说比不上电影中的MOSS,但是其功能之强大,也是令人侧目。

最近又传来一则新闻,ChatGPT通过了Google的L3工程师入职测试,拿下了谷歌120万年薪的Offer,再度将ChatGPT推上了热搜。

一、ChatGPT是什么?

是人工智能技术驱动的自然语言处理工具,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代码等任务。

img

二、ChatGpt 可以做什么

ChatGPT 可以做的事情其实挺多的

  1. 各种话题的问题,例如历史、科学、文化等。它可以提供相关的信息和细节,并且能够根据上下文作出适当的回应。
  2. 可以提供建议和帮助,例如在人类面临某些问题或困难时,它可以提供可行的解决方案。它可以理解人类的需求,并根据他们的问题提供适当的帮助
  3. 可以作为客服或人工智能助手使用,即能够与人类进行交流,并帮助他们解决问题。它可以用于提供客户服务或帮助人们完成日常任务,从而提高工作效率和满意度。

小编我昨晚第一时间进行了体验,发现 ChatGpt 是真的强大,比如我询问小米 13 的手机规格,他一下子就帮我搜索出来了。下面是我的一些使用体验图

如何年薪百万

查询手机参数

img

写一封情书

img

取个名字

img

三、要如何注册?

完整文档打开姿势:国内使用ChatGPT的方式汇总

1.注册ChatGPT账号

详情可以查看上面 保姆级教程~~

缺点:需要梯子,且香港的梯子无法使用,只能用其他国家的网络,对不会该技术的人非常不友好

优点:官方网站,直接用ChatGPT,无任何套路

2. Google浏览器插件

已知的插件有:

  • ChatGPT for Google

这款插件支持 Chrome / Edge / Firefox 等浏览器,使用也很简单,用谷歌搜索时会在右侧给出chatGPT的回答。插件直接从谷歌商店下载

优点:无需注册账号,直接可用

缺点:仍然需要访问外网的梯子

  • Awesome ChatGPT Prompts

这是ChatGPT的游戏精灵,包含了几十种“提问方式“。

  • YouTube Summarizer

这是一款非常有用的youtube插件,它有两个显著的功能,显示出视频脚本,同时可以一键复制到ChatGPT中帮你做一个总结。

对于有些视频,不太清楚它质量或者内容到底如何的,这个可以避免踩雷。

  • Promptheus

这个就更有意思了,可以直接调用话筒跟ChatGPT交流,不需要打字了。

这是我随便提问的,按住空格键就可以了。

img

四、总结

总的来说,目前各大厂商都在对接ChatGPT,或者是对接自己的类似ChatGPT的应用,比如微软发布ChatGPT版必应搜索挑战谷歌 AI加持功能,百度也开始接入ChatGPT、微软拟向企业提供定制版ChatGPT等。

完整文档打开姿势:国内使用ChatGPT的方式汇总

关注微信公众号【程序员徐师兄】,回复 gpt,领取 国内使用ChatGPT的方式汇总 文档

申明:本教程 Pycharm 破解补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版 !

PS: 本教程最新更新时间: 2023年3月25日~

image-20230326180735237

前言

笔者几乎试了网上几乎所有的 Pycharm 破解方案,废了好大气力,汇总了目前网上比较靠谱的三种破解方案(这三种都是笔者亲测成功的),小伙伴们任选其一即可:

  • 第一种【推荐】:👉激活脚本 + 激活码(全自动模式)即本文教程所写,这种方法适合最新的几个版本,具体步骤跟着本文教程一步一步来,运行一下激活脚本,一分钟即可搞定,超级简单。无图无真相,下面是我激活成功后的截图:

PS: 此方法和下面的第二种方法的补丁原理都是暴力拦截了 Pycharm 的剩余使用期网络请求,实际上等于永久激活,至于激活到哪天,在之前的 2021.3.3 2021.3.2 等老版本中是可以手动配置的,比如改成激活到 2099 年。可能是太高调了,最新的版本只能显示到 2025 年, 其实效果还是一样的, 都是永久激活,可放心食用。

image-20230326182109403

说明

  • 本教程适用于 JetBrains 全系列产品,包括 Pycharm、IDEA、WebStorm、Phpstorm、Datagrip、RubyMine、CLion、AppCode 等。
  • 本教程适用 Windows/Mac/Linux 系统,文中以 Windows 系统为例做讲解,其他系统同样参考着本教程来就行。

第一步:下载 Pycharm 安装包

访问 Pycharm 官网,下载 Pycharm 2022.3 版本的安装包,下载链接如下 :

https://www.jetbrains.com/pycharm/download/other.html

image-20230326180636779

打开页面后,点击 Download 按钮, 等待 Pycharm 专业版下载完毕。

第二步:安装 Pycharm 2022.3 版本

如果电脑之前有安装老版本 Pycharm, 需要先卸载。卸载完成后,双击刚刚下载好的 Pycharm 2022.3 版本安装包。弹框会提示选择安装路径,我这里直接选择的默认安装路径

C:\Program Files\JetBrains\IntelliJ Pycharm 2022.3 , 然后点击 Next 按钮:

安装 Pycharm 2022.3 版本

然后,勾选 Create Desktop Shortcut 创建 Pycharm 桌面快捷启动方式,以方便后面快速打开 Pycharm,再点击 Next 按钮 :

开始安装 Pycharm 2022.3 版本:创建快捷启动图标

点击 Install 按钮,开始安装:

开始安装 Pycharm 2022.3 版本:点击 Install 按钮

等待安装完成后,勾选 Run IntellJ Pycharm, 点击 Finish 按钮即运行 Pycharm :

安装 Pycharm 2022.3 版本成功

Pycharm 运行成功后,会弹出如下对号框,强制用户需要先登录 JetBrains 账户才能使用:

Pycharm 2022.3 版本提示需要先登录 JetBrains 账户

不用管登录的事,点击 Exit 按钮退出对话框,装备开始破解激活。

第四步:破解补丁下载

破解补丁我放置在了网盘中,提供了多个备用链接,以防下载失效。

提示:破解补丁的网盘链接文末获取~

补丁下载成功后,记得先解压 **, 解压后的目录如下, 本文后面所需补丁都在下面标注的这个文件夹中

Pycharm 破解补丁下载

点击【方式3】文件夹 , 进入到文件夹 /jetbra,目录如下:

Pycharm 破解补丁文件夹最底层目录

第五步:开始破解

Windows 用户

将上面图示的补丁的所属文件夹 /jetbra 复制电脑某个位置,笔者这里放置到了 D:/ 盘根目录下:

注意: 补丁所属文件夹需单独存放,且放置的路径不要有中文与空格,以免 Pycharm 读取补丁错误。

将 Pycharm 破解补丁放置到 D 盘下

点击进入 /jetbra 补丁目录,再点击进入 /scripts 文件夹,双击执行 install-current-user.vbs 破解脚本:

Pycharm 破解补丁执行脚本

注意:如果执行脚本被安全软件提示有风险拦截,允许执行即可。

Pycharm 破解脚本执行后弹框提示信息

会提示安装补丁需要等待数秒。点击【确定】按钮后,过程大概 10 - 30 秒,如看到弹框提示 Done 时,表示激活破解成功:

补丁执行成功后,提示 Done

Mac / Linux 用户

Mac / Linux 系统与上面 Windows 系统一样,需将补丁所属文件 /jetbra 复制到某个路径,且路径不能包含空格与中文

之后,打开终端,进入到 /jetbra/scripts 文件夹, 执行 install.sh 脚本, 命令如下:

1
sudo bash install.sh

看到提示 Done , 表示激活成功。

Mac/Linux 系统执行破解补丁成功后,提示 Done

部分小伙伴 Mac 系统执行脚本遇到如下错误:

Mac 执行破解脚本报错

解决方法:

可先执行如下命令,再执行脚本:

1
2
export LC_COLLATE='C'
export LC_CTYPE='C'

img

执行脚本,都干了些啥?

  • Windows 用户执行脚本后,脚本会自动在环境变量 -> 用户变量下添加了 Pycharm_VM_OPTIONS 变量,变量值为 /jetbra 文件夹下的 .vmoptions 参数文件绝对路径,如下所示:

    img

    然后,脚本自动在 pycharm.vmoptions 文件中引用了破解补丁 :

    img

    提示: 细心的小伙伴应该也发现了,本文的破解方式与文章开头《第二种 Pycharm 破解方法》的区别在于,这种方式提供了自动化脚本,脚本免去了手动引入补丁的繁琐步骤,一切都由脚本来完成了。

  • Mac / Linux 用户执行脚本后,脚本会自动在当期用户环境变量文件中添加了相关参数文件,Mac / Linux 需重启系统,以确保环境变量生效。

小伙伴们也可自行检查一下,如果没有自动添加这些参数,说明脚本执行没有成功。

第六步:重启 Pycharm

脚本执行成功后,一定要重启 Pycharm ~~

脚本执行成功后,一定要重启 Pycharm ~~

第七步:填入指定激活码完成激活

重新打开 Pycharm 后,复制下面的激活码:

EUWT4EE9X2-eyJsaWNlbnNlSWQiOiJFVVdUNEVFOVgyIiwibGljZW5zZWVOYW1lIjoic2lnbnVwIHNjb290ZXIiLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJQU0kiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQV1MiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDV01QIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfV0sIm1ldGFkYXRhIjoiMDEyMDIyMDkwMlBTQU4wMDAwMDUiLCJoYXNoIjoiVFJJQUw6MzUzOTQ0NTE3IiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-FT9l1nyyF9EyNmlelrLP9rGtugZ6sEs3CkYIKqGgSi608LIamge623nLLjI8f6O4EdbCfjJcPXLxklUe1O/5ASO3JnbPFUBYUEebCWZPgPfIdjw7hfA1PsGUdw1SBvh4BEWCMVVJWVtc9ktE+gQ8ldugYjXs0s34xaWjjfolJn2V4f4lnnCv0pikF7Ig/Bsyd/8bsySBJ54Uy9dkEsBUFJzqYSfR7Z/xsrACGFgq96ZsifnAnnOvfGbRX8Q8IIu0zDbNh7smxOwrz2odmL72UaU51A5YaOcPSXRM9uyqCnSp/ENLzkQa/B9RNO+VA7kCsj3MlJWJp5Sotn5spyV+gA==-MIIETDCCAjSgAwIBAgIBDTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTIwMTAxOTA5MDU1M1oXDTIyMTAyMTA5MDU1M1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyMDEwMTkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUlaUFc1wf+CfY9wzFWEL2euKQ5nswqb57V8QZG7d7RoR6rwYUIXseTOAFq210oMEe++LCjzKDuqwDfsyhgDNTgZBPAaC4vUU2oy+XR+Fq8nBixWIsH668HeOnRK6RRhsr0rJzRB95aZ3EAPzBuQ2qPaNGm17pAX0Rd6MPRgjp75IWwI9eA6aMEdPQEVN7uyOtM5zSsjoj79Lbu1fjShOnQZuJcsV8tqnayeFkNzv2LTOlofU/Tbx502Ro073gGjoeRzNvrynAP03pL486P3KCAyiNPhDs2z8/COMrxRlZW5mfzo0xsK0dQGNH3UoG/9RVwHG4eS8LFpMTR9oetHZBAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUJNoRIpb1hUHAk0foMSNM9MCEAv8wSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBABqRoNGxAQct9dQUFK8xqhiZaYPd30TlmCmSAaGJ0eBpvkVeqA2jGYhAQRqFiAlFC63JKvWvRZO1iRuWCEfUMkdqQ9VQPXziE/BlsOIgrL6RlJfuFcEZ8TK3syIfIGQZNCxYhLLUuet2HE6LJYPQ5c0jH4kDooRpcVZ4rBxNwddpctUO2te9UU5/FjhioZQsPvd92qOTsV+8Cyl2fvNhNKD1Uu9ff5AkVIQn4JU23ozdB/R5oUlebwaTE6WZNBs+TA/qPj+5/we9NH71WRB0hqUoLI2AKKyiPw++FtN4Su1vsdDlrAzDj9ILjpjJKA1ImuVcG329/WTYIKysZ1CWK3zATg9BeCUPAV1pQy8ToXOq+RSYen6winZ2OO93eyHv2Iw5kbn1dqfBw1BuTE29V2FJKicJSu8iEOpfoafwJISXmz1wnnWL3V/0NxTulfWsXugOoLfv0ZIBP1xH9kmf22jjQ2JiHhQZP7ZDsreRrOeIQ/c4yR8IQvMLfC0WKQqrHu5ZzXTH4NO3CwGWSlTY74kE91zXB5mwWAx1jig+UXYc2w4RkVhy0//lOmVya/PEepuuTTI4+UJwC7qbVlh5zfhj8oTNUXgN0AOc+Q0/WFPl1aw5VV/VrO8FCoB15lFVlpKaQ1Yh+DVU8ke+rt9Th0BCHXe0uZOEmH0nOnH/0onD

粘贴到输入框内,点击 Activate 按钮,就激活成功了。

输入 Pycharm 破解激活码

PS: 有部分小伙伴反应,重启 Pycharm 填入激活码依然无法激活,重启系统才行,如果有小伙伴遇到这种情况,不妨试试看~

激活成功后,又可以开心的 coding 了 ~

Pycharm 2022.3 版本激活破解成功

你可能会遇到的问题

一切按照教程来,输入激活码提示 Key is invalid

IDEA 输入激活码提示 key is invalid

输入激活码提示 key is invalid, 常见原因汇总到下面这篇文章了,可参考对照一下:

《JetBrains 产品输入激活码 Key is invalid 解决方案》

需要注意的问题

激活成功后,不要升级 Pycharm 版本

官方反制手段越来越严厉,这个版本能激活,新版本大概率补丁就被限制了。所以,如果打开 Pycharm 后,右下角若出现提示升级新版本,请不要升级版本。能用就行,它不香嘛!

激活成功后,补丁文件夹能不能删掉或者移动?

上文中说到,执行脚本后会添加环境变量,变量值对应了你放置补丁位置的路径,删除掉或者移动,再打开 Pycharm 就找不到对应文件了,激活也就失效了。放着吃灰就行,别动它。

激活补丁下载地址

PS: 破解补丁页面提取人数过多,导致分享的百度网盘链接容易被封:Pycharm 2022.3破解补丁分享失败蛋疼ing,为限制人数,目前暂不提供页面直接提取,改为从笔者公众号提取

需要的小伙伴,扫描下方公众号二维码,或者关注公众号: 徐公,回复关键字:Pycharm, 即可免费无套路获取激活码、破解补丁,持续更新中~。

本文首发我的微信公众号:程序员徐公,微信公众号程序员徐公回复徐公666,可以获得简历模板

前言

在平时开发过程中,我们经常需要截图和录制视频,尤其是客户端开发和测试。

可能有一些人的姿势是这样的。在电脑上开个模拟器,使用第三方工具后进行截图和录屏。还有一种最原始的方式,在手机上截图和录制视频,然后再通过 QQ 等工具发送到电脑,这多累呀。

其实,有一种很简便的方式,那就是说通过别名和 adb,一个简单命令,让你快速截图和录制视频,如 adbshot, adbrecord。下面让我们一起来看一下,怎么实现?

adb 命令和录制视频

adb 命令截图

第一种方法

1
2
3
4
#(保存到SDCard)
adb shell /system/bin/screencap -p /sdcard/screenshot.png
# 从SD卡导出到电脑,注意/Users/junxu 为电脑路径,必须存在
adb pull /sdcard/screenshot.png /Users/junxu

如果你想删除手机上的图片,那么你可以使用这个命令来删除

1
adb shell rm /sdcard/screen.png

开始录制命令:

1
adb shell screenrecord --time-limit 10 /sdcard/demo.mp4

说明:录制手机屏幕,视频格式为mp4,存放到手机sd卡里,默认录制时间为180s

mac 设置别名

1、基本语句

1
alias lts ="cd /Users/junxu/Desktop/sh"

2、修改文件

1
vi ~/.bash_profile

加入 alias lts="cd /data"

保存

3、使别名命令生效

1
source ~/.bash_profile

4、在命令行输入lts 就可以达成 cd /Users/junxu/Desktop/sh的效果

配合别名,快速截图和录屏

截图

增加截图别名

1
alias adbshot="sh /Users/junxu/Desktop/sh/shot.sh"

截图 SH 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
# Android截图,定位和预览默认开启,如果想关闭,可以注释

echo "第一个参数为:$1";

dd=`date +%Y-%m-%d-%H-%M-%S`
pwd=`pwd`
adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png
adb shell rm /sdcard/screenshot.png
mv screenshot.png $dd.png
echo "截图已保存为当前目录下的"$pwd$dd.png
# 修改图片尺寸,长或宽最大不超过960,等比缩放
echo "压缩图片..."
sips -Z 960 $pwd/$dd.png
# 定位到文件
open ./$dd.png -R
# 打开预览
open -a Preview $dd.png
# 复制到剪切板
osascript -e 'on run args' -e 'set the clipboard to POSIX file (first item of args)' -e end $pwd/$dd.png
echo "截图已复制到剪切板"

记得给 SH 脚本增加可执行权限。

1
chmod +x /Users/junxu/Desktop/sh/shot.sh

录屏

增加录屏别名

1
alias adbrecord="sh /Users/junxu/Desktop/sh/record.sh"

录屏脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
# Android录屏
time=$1

if [ ! $time ]; then
time=5
echo "IS NULL"
else
echo "NOT NULL"
fi

dd=`date +%Y-%m-%d-%H-%M-%S`"-$time"
echo "dd is $dd"
pwd=`pwd`
adb shell screenrecord --time-limit $time /sdcard/screenrecord.mp4
adb pull /sdcard/screenrecord.mp4
adb shell rm /sdcard/screenrecord.mp4
mv screenrecord.mp4 $dd.mp4
echo "$1秒视频已保存为当前目录下的"$dd.mp4
# 定位到文件
open ./$dd.mp4 -R
# 复制到剪切板
osascript -e 'on run args' -e 'set the clipboard to POSIX file (first item of args)' -e end $pwd/$dd.mp4
echo "$1秒视频已复制到剪切板"

记得给 SH 脚本增加可执行权限。

1
chmod +x /Users/junxu/Desktop/sh/record.sh

其他常用 adb 常用别名

1
2
3
alias adbtop="adb shell dumpsys activity top | grep "ACTIVITY" "
alias adbd="adb devices"
alias adbs="adb shell"

小结

写这篇文章的目的,是想告诉大家,有别名这个概念。对于开发者来说,配置一些自己常用的别名,真的是很方便,可以快速提高效率。大家如果觉得不错的话,可以关注我的微信公众号程序员徐公

  1. 公众号程序员徐公回复黑马,获取 Android 学习视频
  2. 公众号程序员徐公回复徐公666,获取简历模板,教你如何优化简历,走进大厂
  3. 公众号程序员徐公回复面试,可以获得面试常见算法,剑指 offer 题解
  4. 公众号程序员徐公回复马士兵,可以获得马士兵学习视频一份

程序员该如何写好自己的简历,一位 5 年中大厂老哥跟你聊聊

我的 5 年 Android 学习之路,那些年一起踩过的坑

Android 启动优化(七) - JetPack App Startup 使用及源码浅析

Android 启动优化(六)- 深入理解布局优化

本文首发我的微信公众号:程序员徐公,微信公众号程序员徐公回复徐公666,可以获得简历模板

前言

大家好,我是程序员徐公,双非本科,某中大厂程序员,加上实习,恰好有 5 年的程序员生涯。

从实习到校招,中途踩过不少坑。在职场中有一些自己的心得,今天,跟大家一起来聊聊,程序员应该如何写好自己的一份简历。

前段时间,有一些粉丝私信我说,明年我想进大厂,今年想开始准备,有什么建议嘛?

我回复他的第一句话说,先整理好自己的简历,再进行下一步的计划。为什么这么说呢?

第一:整理简历的过程,其实是一次复盘总结。在这过程中,我们会知道自己哪些地方做得好的,哪些做得不好的,这样才能针对性地进行复习。

第二:挺多人,简历写不好,在筛选简历的时候,直接被 pass,连面试的机会都没有,这是很可惜的。

第三:简历写不好,没突出重点,面试官很难从短短的一个小时之内,发现你的亮点,空有一身才华,却得不到展现,多可惜呀。

下面,就让我们一起来聊一聊,对于技术人来说,怎样才算是一份好的简历?

一、突出你的亮点

一份简历,简单来说,主要分为四部分

  1. 个人基本信息
  2. 过往履历
  3. 个人技能
  4. 项目经历

而 HR,面试官在筛选简历的时候,很有可能不超过一分钟,在这短短的 60 秒时间之内,如果要脱颖而出,简历一定要突出你的亮点,让人耳目一新,彰显自己的才能。

对于程序员来说,个人亮点,我们可以从以下及方面着手,比如说。

  1. 解决了什么疑难杂症,如解决了 top crash, crash 率降低了 0.1% 等
  2. 性能上面带来了多少提升,如编译速度的提升,提升了多少,降低了多少 min等
  3. 你在这个项目作出了什么成绩,比如主导搭建了代码扫描框架,自动扫描,提高代码质量,减少 review 成本。

千里马常有,而伯乐不常有。一定要重视简历,让简历能够反映你的真实水平,先不说做到锦上添花,至少不要拖后腿。

二、展现自己的个人技能

个人技能这块,也是简历中必不可少的一部分。

第一,先说最重要的一点,按照掌握的程度分为几个等级,精通,熟悉,掌握,了解,强烈建议不要写精通,道理你懂的。

第二:不熟悉的点不要写到简历上面,否则就是给自己挖坑。

比如,你只是使用了网络库 OkHttp,你在简历上面写熟悉/掌握 Okhttp。恭喜你,兄弟,你给自己埋下了一颗定时炸弹。面试官可能会问你各种原理的,Okhttp 的设计原理是怎样,拦截器是怎样设计的,有什么优缺点,连接池等等?

说到这,想起了当年实习生面试的时候,写了某开源库,一问三不知。

第三:技能要具体,突出重点,让面试官有话可问

反例:

熟悉 Java

正例:

熟悉类加载,并使用类加载技术开发了一个模块化框架

面试其实是一个双向的选择过程,简历上面技能写得具体,面试官看到了,可能会往这个方面提问题,这是非常 nice 的,我们恰好可以展现自己的特长。

相反,如果简历上面写得不具体,面试官找不出想问的点,那可能就会往他/她擅长的方面问,这时候,对于求职者来说,是非常吃亏的。

因为每个人都有擅长和不擅长的技能,不可能面面俱到。

第四,写的技能一定要跟你应聘的岗位相关,不相关的不要写上去

比如,你应聘的是 Android 开发工程师,你在简历上面写一堆后端技能。匹配度不高,简历可能会 pass。

当然,也不是不可以写与应聘岗位不相关的技能,只是说简历要跟我们应聘的岗位匹配度高一点。这样,简历筛选通过的几率比较高。

最后,专有名词一定要写对,这体现一个人的专业素养和细心。比如 Java,不要写成 java,android 不要写成 Android

三、以项目为主体,展现自己的技术能力和项目贡献

我们可以从以下思路,以项目为主体,设计我们的简历。

如图,大概分为以下层级

  1. 项目名称,开始时间和结束时间,在项目中担任的角色
  2. 项目简介,说清楚这个项目主要是做什么的,有多少量级,尽量不要超过一行,切忌不要超过两行
  3. 项目职责,个人的建议,主要分为两大块,一个是技术职责,一个是业务职责。这样面试官能够很清楚的知道,你在项目中做了什么。

项目职责,这一块是最重要的,也是展现我们能力的时候,尤其要重视。

在写一块的时候,建议分点论述,这样显得调理清晰。

  • 比如你解决了项目的什么疑难杂症,带来了什么收益。这块在面试当中也经常被问到,项目中你有遇到什么技术难点嘛,是怎么解决的?这块回答好了,可以给我们的面试加很多分
  • 做了什么性能优化?这块可以有很多,根据自己擅长的领域和项目经历加上去即可。比如启动优化,编译速度优化,APK 瘦身等
  • 你在这个项目中作出了什么成绩?这块要结合我们项目中的情况来说,比如你推动了 MVVM 框架,组件化的落地等

量化你的项目,给出数字

量化我们的项目,给出数字化结果,可以提高简历的专业度和说服力,给面试官和 hr 留下深刻的印象。

例子一

改写前:应用 xx 技术,解决了 top N 奔溃

改写后:应用 xx 技术,解决了 top N 奔溃,crash 率降低了 0.1% 等

例子二

改写前:应用 xx 技术,减少了内存泄露的发生

改写后:应用 xx 技术,减少了内存泄露的发生,内存 top 值极少了 xxM

例子三:

改写前:结合使用 xx,实现了 app 登录和个人资料的自动填充

改写后:结合使用 xx,实现了 app 登录和个人资料的自动填充,提高了多少的转化率

四、注意事项

写简历,有一些新手会经常犯一些错误,下面简单列举一下

  1. 简历要用 PDF 格式,不要用 Word 格式,有兼容性问题,可能会乱码
  2. 简历命名,建议已这样的格式命名,昵称-应聘岗位-联系方式,这样可以一目了然
  3. 简历不要太长,尽量控制在两页之内。主要重点介绍你最近做过的项目或者你觉得自己做得比较好的项目
  4. 不要在简历中写之前的待遇和期望待遇。
  5. 如果平时有写博客,可以将博客地址写在简历上面,这是一个加分项。不过,如果你的博客上面只是单纯记流水账,就不要写上去了,反而容易减分。Github 也是同样的道理。

暂时就想起这么多了,以后记得再补充,对了,我整理了一份简历模板,想获取的话,可以在我的微信公众号程序员徐公回复徐公666

五、小结

写好一份简历,有很多技巧,排版,量化数据等,但有一点最重要的是,自身要有底子,要有实力。不然,简历写得再好,一切都是泡沫。

十年磨一剑,铁杵磨成针。不管什么行业,想要脱颖而出,坚持是最重要的。唯有日复一日的坚持与打磨,才能走得更高更远。

以上,是我对如何写好简历的一些看法,觉得写得不错的,可以点个赞哦。微信公众号后台回复徐公666,可以获得我整理的简历模板一份。

推荐阅读

个人总结

我的 5 年 Android 学习之路,那些年一起踩过的坑

职场上这四件事,越早知道越好

今天,说三件小事

技术人的未来在哪里

致刚入职场的你 - 程序员的成长笔记

关注我的公众号程序员徐公,回复 徐公666 获取简历模板,回复 黑马 ,获取黑马视频教程。

前言

IntentService使用及源码分析

HandlerThread源码分析

AsyncTask使用及封装实践

AsyncTask源码分析

这篇博客主要是讲解AsyncTask的使用及封装实践,对于新手们还是有很大的参考意义的,尤其是AsyncTask的封装实践这部分。对于老鸟们,你们可以跳过了。同时需要声明的一点是,下面下载的例子只是进行简单的下载而已,并没有支持断点续传下载。需要的话请自行到github上面找相应的库,因为这并不是本篇博客的重点。

这篇博客主要讲解以下问题:

  • AsyncTask的简单使用
  • AsyncTask的封装使用
  • AsyncTask使用注意事项

AsyncTask的使用例子

简介

AsyncTask ,异步任务。没错,就想字面上理解的那样。它允许我们在子线程执行耗时任务,在UI 线程更新操作(如更新进度条等)。简单来说,就是帮我们做好了子线程与UI 线程的通讯,我们只需要调用响应的方法实现即可。底层是用Handler消息机制实现的。

在Android开发中,我们经常需要下载各种东西,为了给用户较好的体验,我们经常需要显示下载进度。今天我们用以这个为例子,来教大家怎样使用AsyncTak。当然,github上面有很多开源库,实现断点下载,文件重命名等。不过这些不是本篇博客的重点。

效果图

AsyncTask的主要几个方法

  • Void onPreExecute()

在task 任务开始执行的时候调用,在doInBackground(Params… params)方法之前调用,在主线程中执行

  • Result doInBackground(Params… params)

主要用来执行耗时操作,在子线程中执行,Params为我们参数的类型。而Result这个泛型,是我们返回的类型(可以是Integer,Long,String等等类型,只要不是八种基本类型就OK),同时 Result 的类型将作为 onPostExecute(Result result)的参数。

  • Void onProgressUpdate(Progress… values)

Runs on the UI thread after publishProgress(Progress…) is invoked. 当我们调用 publishProgress()方法的时候,会调用 onProgressUpdate()这个方法

  • Void onPostExecute(Result result)
    在doInBackground()方法执行完毕之后,会调用这个方法,是在主线程中执行的。但如果我们手动调用了cancelled()方法,那么这个方法将不会被调用。

  • void onCancelled()

在Task 任务取消的时候会调用

  • execute(Params… params)

Executes the task with the specified parameters.当我们调用这个方法的时候,会执行任务

  • executeOnExecutor(Executor exec, Params… params)

在指定的线程池里面执行Task

需要注意的是,Params,Progress,Result 并不是一种特定的类型,它其实是泛型,它支持除了八种基本类型之外的类型,跟普通的泛型一样。

AsyncTask使用的几个步骤

这里我们以下载一个apk为例讲解

  1. 写一个类继承AsyncTask,并传入Params,Progress,Result 。三个参数的类型。

比如我们传入的 Params,Progress,Result 的参数的类型分别为 Void, FileInfo, FileInfo,那我们可以这样写。

1
2
3
private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo>{

}

那Void, FileInfo, FileInfo,这几个参数的类型在哪里体现出来呢?

请看下面注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo> {

---

// 方法参数的类型为Void,跟我们传入的Void一致,返回类型为 FileInfo ,跟我们传入Result的类型FileInfo一致
@Override
protected FileInfo doInBackground(Void... params) {

}

// 方法参数类型为FileInfo,跟我们传入Progress的类型FileInfo一致
@Override
protected void onProgressUpdate(FileInfo... values) {

}


// 方法参数FileInfo,跟我们传入Result的类型FileInfo一致
@Override
protected void onPostExecute(FileInfo fileInfo) {


}


}
  1. 如果我们更新进度的话,需要重写 onProgressUpdate()方法,并在doInBackground()方法里面调用publishProgress()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected FileInfo doInBackground(Void... params) {

publishProgress(fileInfo);


}

@Override
protected void onProgressUpdate(FileInfo... values) {
super.onProgressUpdate(values);
refreshProgress(values[0]);
}


  1. 当我们调用execute(Params… params) 或者 executeOnExecutor(Executor exec, Params… params) 方法的时候,Task将被防盗相应的 Executor 执行。
1
2
MyDownloadTask myDownloadTask = new MyDownloadTask(mDownloadUrl, mDstPath);
myDownloadTask.execute();

完整的Task代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
private class MyDownloadTask extends AsyncTask<Void, FileInfo, FileInfo> {

String mDownLoadUrl;
String mDstPath;

public MyDownloadTask(String downloadUrl, String dstPath) {
this.mDownLoadUrl = downloadUrl;
this.mDstPath = dstPath;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
start();
}

@Override
protected FileInfo doInBackground(Void... params) {
//url字符串,检查网址是否已http:// 开头
mDownLoadUrl = (mDownLoadUrl.startsWith("http://")) ? mDownLoadUrl : "http://" +
mDownLoadUrl;
Log.d(TAG, "doInBackground: mDownLoadUrl=" + mDownLoadUrl);
Log.d(TAG, "doInBackground: mDstPath=" + mDstPath);
URL url = null;
FileInfo fileInfo = null;
int contentLength = -1;
int downloadLength = 0;
OutputStream output = null;
InputStream istream = null;
try {
url = new URL(mDownLoadUrl);
//打开到url的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
contentLength = connection.getContentLength();
Log.i(TAG, "doInBackground: contentLength=" + contentLength);
//O部分,大体来说就是先检查文件夹是否存在,不存在则创建
istream = connection.getInputStream();
String filename = mDownLoadUrl.substring(mDownLoadUrl.lastIndexOf("/") + 1);

File dir = new File(mDstPath);
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(mDstPath + filename);
// 如果存在同名文件,重命名
if (file.exists()) {
file = FileUtils.rename(file.getPath());
}


output = new FileOutputStream(file);
byte[] buffer = new byte[1024 * 4];
int count = 0;
int len = -1;
while ((len = istream.read(buffer)) != -1) {
output.write(buffer, 0, len);
downloadLength += len;

if (count == 10) {
fileInfo = new FileInfo(contentLength, downloadLength, file, file.getPath
(), file.getName());
publishProgress(fileInfo);
count = 0;
}
count++;

}
// 有可能count还没有走到10
fileInfo = new FileInfo(contentLength, downloadLength, file, file.getPath(), file
.getName());
publishProgress(fileInfo);
output.flush();
output.close();
istream.close();

} catch (Exception e) {
e.printStackTrace();
try {
IOUtils.close(output);
IOUtils.close(istream);
} catch (IOException e1) {
e1.printStackTrace();
}

} finally {
try {
IOUtils.close(output);
IOUtils.close(istream);
} catch (IOException e1) {
e1.printStackTrace();
}
}
return fileInfo;
}

@Override
protected void onProgressUpdate(FileInfo... values) {
super.onProgressUpdate(values);
refreshProgress(values[0]);
}

@Override
protected void onPostExecute(FileInfo fileInfo) {
super.onPostExecute(fileInfo);
downloadfinish(fileInfo);

}

@Override
protected void onCancelled() {
super.onCancelled();
}
}

private void start() {
mTvDownloadText.setText("开始下载");
mProgressBar.setMax(100);
mProgressBar.setProgress(0);
}

private void downloadfinish(FileInfo fileInfo) {
Log.i(TAG, "onPostExecute: 下载完成=" + fileInfo.mPath);
Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
}

private void refreshProgress(FileInfo value) {
FileInfo fileInfo = value;
if (fileInfo != null) {
mProgressBar.setMax((int) fileInfo.mLength);
mProgressBar.setProgress((int) fileInfo.mDownloadLength);
mDownText = fileInfo.mFile.getName() + "下载了" + fileInfo.mDownloadLength + "总长度是" +
fileInfo.mLength;
mTvDownloadText.setText(mDownText);
}
}



AsyncTask的封装使用

前面我们讲完了AsyncTask的基本使用,不知道你有没有发现,其实代码耦合性是挺高的,

  • 我们直接在 onProgressUpdata(),onPostExecute()方法里面更新我们的界面,即我们的AsyncTask访问了我们Activity里面的控件,那如果我们修改了Activity的控件,我们岂不是又要去阅读AsyncTask的代码,去做相应的修改。
  • 下一次我们如果要下载别的东西,按照我们前面的代码,我们又要重新复制一份,这样无疑是做了很多重复的工作。

说到这样,我相信大多数人的第一感觉就是把AsyncTask提取为外部类,封装起来。是的,确实,我们就是要把AsyncTask提取为外部类。那提取为歪不累之后呢?我们要访问Activity里面的空间,要怎样访问呢?

  1. 在Activity里面定义静态方法
  2. 把需要访问的View对象通过构造函数传递进来
  3. 采用接口回调机制

前面说到的三种方法,是可以做到AsyncTask与外界进行通讯的。但第一第二中方法明显不行。原因如下:

  • 第一种方法定义静态方法,那View对象也必须定义为static变量,这static变量的级别比较高,不易被垃圾回收机制回收,易发生没存泄露。
  • 第二种方法,把需要访问的View对象通过构造函数传递进来。如果需要访问的对象少的话,勉强可以接受,如果多的话,那岂不是要定义很多成员变量。不过最致命的还算是代码耦合性太高了。还不如AsyncTask直接作为内部类。

好了,说了这么多,下面我们一起来看怎样使用接口回调机制来进行解耦。

AsyncTask 使用接口回调机制来进行解耦

  1. 使用接口回调机制,首先我们必须有一个接口
1
2
3
4
5
6
7
8
public interface DownloadListener {

void onStart();
void onProgress(FileInfo fileInfo);
void onFinish(FileInfo FileInfo);
void onPaused(FileInfo fileInfo);
void onCancled();
}
  1. 将DownLoadTask提取为一个外部类,并将需要传递的参数传递进来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class DownloadTask extends AsyncTask<Void,FileInfo,FileInfo> {

private String mDownloadUrl;
private final String mDstPath;
private final String mFileName;
private final DownloadListener mDownloadListener;

public DownloadTask(String downloadUrl, String dstPath, String fileName, DownloadListener downloadListener){
mDownloadUrl = downloadUrl;
mDstPath = dstPath;
mFileName = fileName;
mDownloadListener = downloadListener;
}
}
  1. 在相应的地方调用我们接口的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class DownloadTask extends AsyncTask<Void,FileInfo,FileInfo> {

----

@Override
protected void onPreExecute() {
super.onPreExecute();
mDownloadListener.onStart();
}

@Override
protected FileInfo doInBackground(Void... params) {

----
int len = -1;
while ((len = istream.read(buffer)) != -1) {
output.write(buffer, 0, len);
downloadLength += len;

if (count == 10) {
fileInfo = new FileInfo(contentLength, downloadLength, file, file.getPath
(), file.getName());
publishProgress(fileInfo);
count = 0;
}
count++;

}
// 有可能count还没有走到10
fileInfo = new FileInfo(contentLength, downloadLength, file, file.getPath(), file
.getName());
publishProgress(fileInfo);
output.flush();
output.close();
istream.close();



return fileInfo;
}

@Override
protected void onProgressUpdate(FileInfo... values) {
super.onProgressUpdate(values);
mDownloadListener.onProgress(values[0]);
}

@Override
protected void onPostExecute(FileInfo fileInfo) {
super.onPostExecute(fileInfo);
mDownloadListener.onFinish(fileInfo);
}

@Override
protected void onCancelled() {
super.onCancelled();
mDownloadListener.onCancled();
}
}

使用

以后我们要下载东西,只需要调用下面的方法即可。同时,如果产品再更改需求,比如,从显示一个进度条ProgressDialog对话框,改成显示一个ProgressBar,我们只需要在
onProgress()里面做相应的修改就好了,在也不用去阅读DownloadTask里面的代码呢?减少了代码的耦合性,是不是瞬间感觉世界很美好呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mDownloadTask = new DownloadTask(mDownloadUrl, mDstPath, null, new
DownloadListener() {
@Override
public void onStart() {
start();
}

@Override
public void onProgress(FileInfo fileInfo) {
refreshProgress(fileInfo);
}

@Override
public void onFinish(FileInfo fileInfo) {
downloadfinish(fileInfo);
}

@Override
public void onPaused(FileInfo fileInfo) {

}

@Override
public void onCancled() {

}
});
mDownloadTask.execute();

AsyncTask使用的注意事项

  • The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
  • The task instance must be created on the UI thread.(AsyncTask必须在UI 线程里面初始化
  • execute(Params…) must be invoked on the UI thread.
  • Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…) manually.(不要手动地调用 onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…) 这些方法)
  • The task can be executed only once (an exception will be thrown if a second execution is attempted.) (Task任务只能被执行一次,否则会抛出异常)

相关知识点推荐:

IntentService使用及源码分析

HandlerThread源码分析

AsyncTask使用及封装实践

AsyncTask源码分析

Demo下载地址

光阴似箭,日月如梭,时间真的过得飞快。
加上实习,从事 Android 开发,差不多有 5 年了,在这里,我分享一下我的经验,在 Android 的学习路上,我是站在巨人的肩膀上成长起来的。

大概分为三个部分

一、Android 职业规划
二、Android 学习路线
三、如何进入大厂
三、Android 学习资料分享

Android 成长生涯

1-3 年

前 3 年,我觉得是我们成长最快的时候。

尤其是刚开始工作的一年,刚开始接触项目,我们会接触到很多新知识,比较网络框架的封装,Android 架构 MVVN,MVC,MVP 等。

这段时期是我们进步最快的时候,因为很多东西我们都不会,我们会逼着自己去学习。

第二到第三年,也是我们成长的关键时期。这时候,在项目中,我们基本会自己独立负责需求。这时候的我们,大多数基本功能都可以自己独立实现。需要注意的是代码风格和代码思维的培养

代码风格,指的是编码习惯。比如方法命名,方法的合理拆分,适当添加注解,注释。听起来可能会很虚,但是千万别小看这些细节。反正我在组里见过一些工作五六年的,代码一坨一坨的,像 si 一样。

代码思维,有点类似于人的视野和思考方式吧。很多时候,实现某个效果,有很多种方案。我们为了应付需求,可能会随便选择一种,没有去了解其他方案。而这恰恰错过了我们成长的最佳时期。

记住,永远别给自己设限,或许在编程的路上会遇到很多问题,但是总会有解决方法的,而这取决你的态度。

3-5 年

这个时期,不出意外,我们基本都是高级工程师了。这时候大多数人会遇到瓶颈,不知道学些什么好。好像什么都会,但是不够深入。我也遇到这样的情况,现在正在深挖。

这方面我暂时也给不了太多意见,只能说,选择一个方向,静下心来,去学习,相信能收获到我们想要的。

学习方向有很多,比如 Android 性能优化(启动,卡顿, Crash 治理), JNI C++,gradle 打包,编译速度,音视频等等,这些都是大的方向。

最近写的一些文章,自我感觉还行,有兴趣的可以看看。

Android 启动优化(一) - 有向无环图

Android 启动优化(二) - 拓扑排序的原理以及解题思路

Android 启动优化(三)- AnchorTask 开源了

Android 启动优化(四)- AnchorTask 是怎么实现的

Android 启动优化(五)- AnchorTask 1.0.0 版本正式发布了

Android 启动优化(六)- 深入理解布局优化

5 年之后

技术人的四大出路,你适合哪一个

大多数技术人,一般会有以下方向。

  • 第一:成为技术大神,比如架构师,及技术专家等。
  • 第二:技术管理,比如技术总监等。
  • 第三:技术转型,如转项目管理,产品等,你牛逼的话,说不定下一个张小龙就是你(哥们,想多了,那有这么容易)。
  • 第四:自主创业,做自媒体等

我目前来说,可能会选择第一条路吧,成为一名技术专家。

在技术的路上,或许会很累,很难,可那又怎样呢

35 岁中年职业危机,很多职业都有,不仅仅局限于程序员。

从本质上面说,自身竞争力下降占很大原因。毕竟,优秀的人才从来不缺少机会。

既然选择了,便只顾风雨兼程。

为了未来有更多的选择,从现在开始,朝着自己的目标努力奋斗吧,书写属于自己的人生。


Android 学习路线

下面,说一下 Android 的学习路线,不会很具体,主要是从大的方面来说,感兴趣的可以看一下。

搭建基本的开发环境,敲下 Hello world

首先你配置好电脑开发环境。首先需要配置 Java,AndroidStudio 的开发环境。

现在的 IDE 对比几年前的,真的是方便多了,可以自动帮我们配置好环境变量。还记得当年刚开始配环境的时候,折腾了两三天。在配置变量的时候,有时候英文的逗号输成中文的,在 cmd 窗口输入 Java,一直提醒没有这个命令,一把鼻涕一行泪

依稀还记得,当配置完环境之后,敲下第一段程序 Hello world 时的那份喜悦。

掌握基本的语法和常用的数据结构

第一:你要先掌握基本的语法,可以从一些书籍开始学起。跟着书本慢慢敲,从第一个程序 Hello World 慢慢敲起,万丈高楼平地起

由于 Android 是用 java 或者 kotlin 语言开发的,建议优先掌握 java 语言。这里推荐两本书籍。

  1. java 编程思想,一本很经典的 java 书籍
  2. java 剑指 offer,面试神器。校招的时候,有很多面试题目,里面都有涉及到。

第二:掌握基本的语法之后,常用的数据结构,数组,链表,队列,栈。这些基本的概念和语法要知道。还有线程,文件 IO 操作,网络操作。

学完这些之后,Java 的基本知识你大概掌握了,这时候建议你动手写一些小项目或者 Demo,比如坦克大战,计算器等,这些网上都有代码。想跟着视频一起学的话,推荐马士兵的视频,可以在我的微信公众号 程序员徐公 回复”Java“,会将教程发给你

Android 学习入门

掌握这些之后,你可以去看一些 Android 入门的书籍或者一些视频。

书籍我推荐郭霖的第一行代码,目前出了第三版了,写得真不错。

视频的话,我推荐你可以看黑马的 Android 视频,里面会从一些基本语法讲起,接着是项目实战,会手把手教你实现简单的新闻客户端,360 手机卫士等等。

想获取黑马视频资料的话,可以去我的微信公众号程序员徐公回复”黑马“两字,会将教程发给你。

Android 进阶

学习完基本的知识之后,可以去看看任玉刚的 Android 开发艺术探索,虽然是几年前出版的,但真的是精华。

接着,可以关注一些架构,性能优化方面的。

  • MVC, MVP, MVVN
  • 内存泄露怎么检测,常见的内存泄露有哪些
  • 怎么检测 ANR,有哪些手段呢,优缺点是什么
  • 怎么捕获 Crash,Java Crash 和 native crash 有哪些不同呢
  • Android 检测启动时间,启动优化怎么做,常见的 Android 启动优化手段有哪些
  • Android gradle,是怎样打包的,怎样提高编译速度

这里推荐几篇不错的文章

Android 启动优化(一) - 有向无环图

Android 启动优化(二) - 拓扑排序的原理以及解题思路

Android 启动优化(三)- AnchorTask 开源了

Android 启动优化(四)- AnchorTask 是怎么实现的

Android 启动优化(五)- AnchorTask 1.0.0 版本正式发布了

Android 启动优化(六)- 深入理解布局优化

关注前沿技术

关注前沿技术,可以去一些论坛,公众号上面逛逛。

论坛的话,推荐掘金,CSDN

Android 技术公众号的话,推荐鸿洋,郭霖的公众号,当然还有我的公众号程序员徐公。文章的质量算是比较高的。

最后,有空的时候多去 github 或者 google 官网 看看,有什么新技术,一般第一时间会更新。

如何进入大厂

面试是一个双向选择的过程,我们要保持足够的自信。

在我看来,要进入大厂,有 4 点最重要。

  1. 编程能力,包括常用技术以及常用技术的原理,毕竟招人,是来干活的,不是来当爹的
  2. 技术深度,在大厂,分工越来越越明确,职责越来越细。很多时候,需要的是某一个技术领域的人才,而不是什么都懂一点的全才。
  3. 算法。
  4. 软技能,沟通能力等

如何学习算法

现如今,如果你想进入大厂,腾讯,阿里,头条,拼多多等,不管是社招还是校招,肯定都会面试到算法的。

相信很多人有这样的想法,面试的时候早火箭,工作的时候拧螺丝。确实,这种情况非常常见,我也认同。但没办法,谁叫我们想进入大厂呢。

不过,这种情况也可以理解。怎么在几轮面试中确定面试者的水平呢?
肯定是考察算法,基础这些,原理这些

虽然这些代表不了全部,但起码能在一定程度上代表了面试者的水平能力。要知道,编程语言其实都是想通的,编程思维和算法能力才是核心。

掌握了原理,编程思维,切换到另外一门语言其实是很快的。这也就是面试官喜欢考察算法和原理的原因。

至于要怎么学习算法,我简单归纳一下

第一:要了解基本的数据结果,数组,链表,Map,Set,二叉树等,了解他们的优缺点,时间复杂度,空间复杂度等

第二:要掌握一些常见的算法,递归,迭代,八大排序,二分查找,贪心算法等

第三:掌握一种算法,不仅要知道 what,还要知道 why(分析各种算法的优缺点),比如 topK问题,有常见的几种解决方案,排序,快排思想,海量数据堆排序

第四:刚开始学的时候,可能会比较吃力,可以先刷题,慢慢找感觉,从易到难

  • 比如,第一天,你刷这道算法题的时候看不懂,先不用着急,很多人都是这样过来的,先搜一下答案,看一下别人是怎么解决的。
  • 看懂了之后,自己用代码写一遍,跑一遍。这很重要,很多时候,你以为你自己懂了,但当你在写的时候是写不出来的,在你动手写代码时,会不断加深你的印象
  • 第二天,自己再写一遍,加深印象

第五:学好算法不是一日之功,需要长期的积累。建议的做法是每天做一两道题,题目不在多,贵在于理解。坚持一两个月,你会发现你的感觉逐渐好起来了。

https://github.com/gdutxiaoxu/Android_interview

Android 学习资料分析

黑马 52 期不加密视频

获取方式在微信公众号 “程序员徐公” 回复“黑马” 两字

01、安卓基础+JNI (14天)
02、Android应用开 发-代码版本管理和实战(1天)
03、android案例与项目_手机安全卫士(12天)
04、自定义控件与视图(2天)
05、android项目 实战_智慧北京(6天)
06、android项 目实战_谷歌应用市场(6天)
07、android进阶 高阶案例-QQ5.0特效专辑(2天)
08、android游戏开发_ 植物大战僵尸(3天)
09、android案例与项目_ 百度地图(1天_ 补充)
10、android项目实战_智能短信管理(3天_ 补充)
11、Android
_WebView&HTML5开发(1天 _补充)

Java 马士兵视频

获取方式在微信公众号 “程序员徐公” 回复“java” 两字

第一部分:J2se学习视频内容包括:

尚学堂科技_马士兵_JAVA视频教程_JDK5.0_下载-安装-配置
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第01章_JAVA简介_源代码_及重要说明
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第02章_递归补充
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第02章_基础语法
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第03章_面向对象
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第04章_异常处理
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第05章_数组
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第06章_常用类
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第07章_容器
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第08章_IO
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第09章_线程
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第10章_网络
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_第11章_GUI
尚学堂科技_马士兵_JAVA视频教程_J2SE_5.0_专题_日期处理
尚学堂科技_马士兵_JAVA视频教程_J2SE_专题_正则表达式

第二部分:j2se练习项目视频内容包括:

第二部分:j2se练习项目视频内容包括:

尚学堂科技_马士兵_在线聊天系统雏形视频教程_java_eclipse
尚学堂科技_马士兵_坦克大战视频教程_java_eclipse
尚学堂科技_马士兵_坦克大战图片版
尚学堂科技_马士兵_JAVA_坦克大战网络版视频教程
尚学堂科技_马士兵_snake_贪吃蛇内部视频

小结

以上是我这些年来, Android 学习路上的一些简单分享。在 Android 的学习路上,我是站在巨人的肩膀上成长起来的,同样,我也希望成为你们的巨人。

希望我们可以成为朋友,成长路上的忠实伙伴!

Android 黑马学习视频

目录

  • 01、安卓基础+JNI (14天)
  • 02、Android应用开 发-代码版本管理和实战(1天)
  • 03、android案 例与项目_手机安全卫士(12天)
  • 04、自定义控件与视图(2天)
  • 05、android项目实战_ 智慧北京(6天)
  • 06、android项目实战_谷歌应用市场(6天)
  • 07、android进阶高阶案例-QQ5.0特效专辑(2天)
  • 08、android游戏开发_植物大战僵尸(3天)
  • 09、android案例与项目_ .百度地图(1天_ 补充)
  • 10、android项目实战_ 智能短信管理(3天_ 补充)
  • 11、Android_ WebView&HTML5开发(1天 补充)

获取方式

百度云链接

Android 学习 + 面试指南:

如果链接过期了,可以关注我的微信公众号“程序员徐公”,回复“黑马“两字,会自动发给你

  1. 公众号程序员徐公回复黑马,获取 Android 学习视频
  2. 公众号程序员徐公回复徐公666,获取简历模板,教你如何优化简历,走进大厂
  3. 公众号程序员徐公回复面试,可以获得面试常见算法,剑指 offer 题解
  4. 公众号程序员徐公回复马士兵,可以获得马士兵学习视频一份