📒 Android学习笔记

冥冥之中感觉今天会收到阿里电面。艾玛,没来,真是太好了,不过照时间推算,也没几天了,整理一波学习笔记。

前几次面试表现得有点糟糕,各家面试官问的问题都不一样,真是防不胜防。我以为么,一般就问问四大组件、生命周期、一两个设计模式、HashMap、RxJava操作符、并发问题,然后扯扯做过的项目,就差不多了。结果么,Handler机制、Window、TextureView、Android虚拟机、Thread方法、线程池、class加载流程、jvm内存模型…都扯出来了。艾玛,瞬间感觉自己简历写得太泛。

那就开始吧。

Android:

Android四大组件:Activity、Service、ContentProvider、BroadcastReceiver。

Activity生命周期:onCreate()创建, onStart()可见, onResume()位于前台, onPause()暂停, onStop()停止, onDestroy()销毁. 这是常规的生命周期,从创建到销毁。

从一个Activity跳转到另一个Activity再返回到当前Activity(等同于home键到桌面再返回当前activity):-> onPause(), onStop() -> onRestart()回到当前activity必然会调用, onStart(), onResume()。

在当前Activity弹窗再消失弹窗:-> onPause(), onResume()。(后注:不会触发。只有启动Dialog的Activity才会触发这种情况。)

Activity启动模式:standard, singleTop, singleTask, singleInstance.

standard:标准模式,在当前任务栈新增一个Activity实例(若无当前任务栈,那么必须在Intent里加上FLAG_ACTIVITY_NEW_TASK标记位)。

singleTop:栈顶复用模式,若当前Activity已位于当前任务栈栈顶,那么该Activity不会被重复创建,其onNewIntent()方法将被调用。

singleTask:栈内复用模式,若该Activity已位于当前任务栈,则将该Activity推到栈顶(在其之上的Activity会被移除),其onNewIntent()方法将被调用。

singleInstance():单实例模式,该Activity独占一个任务栈,只要存在就不会新建。

Fragment:Fragment可以理解为一个特定的View,其生命周期与Activity关联。

Fragment生命周期:onAttach(), onCreate(), onCreateView(), onActivityCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDetach()。其生命周期和Activity生命周期类似,也是首位对应,互为一组。此外onViewCreated()位于onCreatedView()与onActivityCreated()之间。

ViewPager与Fragment:二者常常一起使用,需要注意的是,如果当前Fragment的父容器也是Fragment,那么需用调用getChildFragmentManager()方法来获取FragmentManager;

此外,FragmentPagerAdapter管理的Fragment在页面移出缓存时不会调用Fragment的onDestroy()方法,只会调用onDestroyView()方法,这一点在ViewPager数据复用时很有用。FragmentStatePagerAdapter不同,它会连同Fragment一起移除,所以会触发Fragment的onDestroy()方法。

啊,缓一口气。真多啊,这才大概讲了Activity和Fragment。感觉Android部分至少还有三个这么多,Java相关的至少还有两个这么多,真是高估了我想一个咖啡的时间写完。

Service:

这玩意是用的真的少,我一直把它理解为一个后台Activity,一个可以在应用页面退出后长存的服务。

Service的两种启动方式:1. context.startService(intent);2. context.bindService(intent, …)。对了,这里提一下,通过context.start…启动一个Activity或者Service是跨应用的,会调用AMS的方法来唤起指定的东东,这也是为什么四大组件需要在Manifest里注册的原因(不然AMS咋知道有你?)。此外,第一种启动方式需要自己管理Service生命周期;第二种通过绑定的方式,Service会和调用者共存亡。

IntentService:适合在后台处理耗时操作(比如上传或下载大文件)。

相比Service:Service默认是不会新开线程的,IntentService相当于把这些事做了,不需要我们手动管理线程,而且任务执行完后会自动结束。

相比线程:毕竟继承自Service,属于四大组件,拥有较顽强的生命力;而线程在应用位于后台后可能被中断。

AsyncTask:既然聊到IntentService,那么再聊聊AsyncTask。AsyncTask适合短暂的异步操作(比如数据打点)。

特性:AsyncTask提供了非常方便的异步操作与结果回调,多个AsyncTask会在同一个线程串行执行(所以不适合长任务,同时也不需要担心线程过多而拥堵)。

ContentProvider:

这玩意是见得多,用得少。在项目targetApi设置为27以上后,各种兼容需要用到ContentProvider,譬如拍照获取图片、Glide的缓存路径自定义。此外,通过ContentProvider来获取媒体资源可谓非常高效,写过个demo,广度遍历本地所有.mp3文件,耗时50秒,用网易云耗时15秒(估计做了多线程优化),用ContentProvider直接拿来就行(耗时0.01秒)。

<coffee1 end 2018/09/05 22:48>

继续啊,ContentProvider还可以用于进程间通信,这一块比较陌生,不深聊。

BroadcastReceiver:

广播接收者。前面说到“四大组件需要在Manifest里注册”,但这里有一个例外,BroadcastReceiver除了可以在Manifest注册外还可以通过代码来注册。

广播与EventBus区别:二者类似。广播通过AMS发送和接收,成本较高,跨进程。EventBus相对来说更为轻量,采用观察者模式,只能在同进程内通信。

广播高级用法:发送者可以设置接收范围,可以发送有序广播。对应的广播接收者优先级比较高的会先收到,其可以在onReceive()方法里拦截或更改,若拦截,优先级低的接收者将不会收到该条广播。

四大组件差不多就是这样,接下来聊聊Android消息机制——Handler。

这玩意看过很多次,但总感觉有些地方还不大理解,却又说不出是哪个地方。

Handler主要用于线程间通信。假设有两个线程,线程A和线程B,线程A执行到某一步时需要通知线程B来进行某些操作。那么该怎么办呢?很简单,线程A只需调用线程B的某个handler执行post()等方法即可(post里的操作会在线程B内执行)。

怎么做到的呢?这要提到Looper与Message了。

每个线程都可以有一个Looper,调用Looper.prepare()可以为当前线程新建Looper,Looper.loop()开启Looper循环,Looper.quit()退出Looper()。

这样说,好像难以理解,还是打个比方吧。

我们用城堡来比喻线程,那么Looper即该城堡的事务官,一座城堡只能有一个事务官。城堡(Thread)里有邮箱(MessageQueue),事务官(Looper)每次从邮箱取出一封信件(Message),然后将信件里的事情吩咐给城堡执行,待执行完后,事务官继续从邮箱取出信件…如此循环,当邮箱里没有信件时,事务官会在邮箱旁一直等。那么,信件从哪里来?通过邮差(Handler)投放。拥有事务官的城堡可以雇佣邮差,每座城堡可以雇佣多个邮差。邮差归属于一座城堡,邮差可以往自己的城堡邮箱投递信件,邮差可以活动在其他城堡。这样,临冬城(线程A)就可以通过某个守夜人(线程B的Handler)向黑城堡(线程B)投递信件了。

大概原理就是这样。

还有些细节,线程默认是不开启Looper的,Android主线程ActivityThread初始化时会开启Looper。开启Looper后的线程才能创建Handler,Handler属于创建它的线程,调用Looper.loop()开启消息循环,开启消息循环后的线程在执行完run()方法后不会结束,需要手动调用Looper.quit()退出Looper后,线程才能正常结束。

Handler差不多就这些,有了RxJava后这玩意用得很少,远古时代的Handler常常被使用不当导致内存泄露,编译器会建议将自定义的Handler类修饰为static,这样可以避免乱引用导致内存无法被回收。

压力略大啊,还有好多,聊聊Window吧。

Window有三种类型:应用Window(Activity window),子Window(Dialog等),系统Window(Toast、状态栏等)。其z轴依次递增,视图都是创建在Window上的。

不大了解的就不细聊了。

SurfaceView、TextureView。

用过TextureView。SurfaceView独立Window,多个SurfaceView不能层叠,不具备View的许多特性,包括一些位置或动画变换。TextureView几乎拥有View的全部特性。共同点是,都是独立线程绘制,都需用手动绘制每一帧的影像。

Binder就不聊了,完全陌生,那么Android就这些?好像还有个Android虚拟机,简单聊下吧,Android5.0开始使用ART虚拟机(之前用的是Dalvik,其实Android4.4就引入ART了,只不过那时需要手动开启)。ART虚拟机相对于Dalvik虚拟机的优势在于应用安装时将字节码编译成机器码,运行时速度更快(Dalvik是JIT运行时编译),不过随之占用的存储空间也更大、且安装时会慢一点,其它差不多。相较于JVM直接运行Java字节码,Dalvik会将Java字节码转换成Dalvik字节码再运行,因为Dalvik字节码是基于Java字节码的,所以很多JVM的相关特性在Dalvik中也适用(比如指令重排,尽管JVM基于栈而Dalvik基于寄存器)。

Android中每个进程都会启动一个Dalvik虚拟机(通过最原始的虚拟机fork而来),这样可以保障某个应用崩溃不会引起整个系统崩溃。

Java、Java。

Java要聊的有设计模式、JVM、多线程。相关知识点先例个提纲:

单例模式,双重校验锁,volatile。

synchronized,原子性、可见性、有序性。

HashMap实现原理与多线程引发的问题。

class加载流程,装载-(验证、准备、解析?)-初始化(触发条件?)-使用-卸载。

JVM内存模型,方法区、堆、(本地方法区、程序计数器、虚拟机栈)。

垃圾回收机制,MC、MS、CMS,永久代、新生代、老年代。

指令重排的场景,分配内存空间、初始化对象、指向内存空间。

Thread一些操作,join(), sleep(), object.wait(), yield(). LockSupport.park()。

Thread五大状态,New, Running&Runnable, Blocked, Waiting&TimedWaiting, Terminated。

就酱聊吧,好像除了提纲,并不能再深入什么。啊,先到这。

<coffee2 end 2018/09/06 18:51>

写作似乎特能使才思枯竭。很久才积累的经验或知识,在脑海中处于混沌状态,待到想要将其表述时,先理清其中的关系,补齐其中的缺漏,而后将其具化成文字,若追求优美,还得再反复调和。这一过程,亦费心思,得到的文字却少之又少。想起“世上没有免费的午餐”的来源故事,千百书籍竟化成一句话。有点这样的味道,不过当然不赞同这种做法,脱离实例的道理是没有意义的。一本厚厚的书籍,可能其全书只为诠释一个结论,但若不观赏其沿途风景必然也无法理解该结论。

有时觉得语言是一种阻碍,流畅的思绪,一化作文字便显得磕磕巴巴,远不如数学解题步骤那般行云流水。人类的语言还有很大的进步空间啊,也许是自己的文学功底还有很大的进步空间,理想状态应该是思绪与语言合一,脑中的思绪能够非常轻松地化为语言,那样,人人都是大诗人,人人都是好作家。似乎是矛盾的,不过不同语言的表达力确实大相径庭。

继续聊Java。

线程安全比较重要的三条特性:原子性、可见性、有序性。

原子性:若某个操作不可中断(要么不执行,要么连续执行完),那么该操作具备原子性。X

可见性:若某个变量被修改后,所有可以访问该变量的线程均可感知,那么该变量具备可见性。

有序性:若某个几条连续指令按先后顺序执行,那么这几条指令具备有序性。X

synchronized加锁的同步代码块具备原子性、可见性、有序性。

volatile修饰的变量具备可见性、有序性。

所以,双重校验锁实现的单例模式其单例必须加volatile修饰符。为什么?因为需要保证变量初始化时的有序性。比如a = new A(); 这条代码包含3步操作:1. 分配内存空间; 2. 初始化对象; 3. 将a指向该内存空间。默认情况下2、3步是可以颠倒次序执行的,若3在2之前执行,那么后面的线程在这时取到的a虽然不为null但是并没有初始化完成。

那么矛盾来了,synchronized不是具备有序性么?为什么还需要加volatile来保证?实际上,上面对有序性的描述是错误的。这是个误区。volatile保证的有序性和synchronized保证的有序性完全不是一回事,volatile禁止了指令重排,而synchronized通过加锁的方式保证多个线程对一段代码只能排队执行(所以上面对原子性的定义也是错误的,synchronized修饰的代码块允许中断,object.wait()就是一个典型的例子,synchronized保障的不过是该代码块只能串行执行,且前面的必须执行完了后面的才能进入)。

哎,好坑。好好的用锁就能解释的东西为什么看过的资料都喜欢用XXX归纳,强行三大特性啊。所以啊,锁这一块还值得好好研究下。

聊聊线程吧。

线程,CPU调度的基本单位。 (?) 表示方法内参数可有可无。

thread.start()启动一个线程;

thread.join(?)将该线程串行到当前线程,当前线程进入等待状态;

Thread.sleep(…) 使当前线程睡眠,进入TimedWaiting状态;

Thread.yield() 轮到当前线程Running时,主动礼让,进入Runnable状态。

线程的几种状态介绍下。

New: 线程new出来了但是还没有执行start()方法;

Runnable: 可运行状态,等待CPU时间切片;

Running: 正在执行;

Blocked: 等待获取锁;synchronized

Waiting: 无期限等待;thread.join(), 获取同步锁后object.wait()

TimedWaiting: 期限等待;Thread.sleep(…), thread.join(…), 获取同步锁后object.wait(…)

Terminated: 已执行完毕。

主要聊聊Waiting状态。通过thread.join()或者object.wait()可使当前线程进入无限期等待。thread.join()需要等thread执行完成后当前线程才会回到Runnable状态。object.wait(?)必须在synchronized(object){}代码块内执行,执行后会马上释放object的同步锁。通过synchronized(object){ object.notify(); } 可以唤醒该线程进入Runnable状态。

通过object.wait()操作使线程进入等待状态并不优雅,所以有了LockSupport类,LockSupport.park()可以完美替代object.wait()且无需加锁, LockSupport.unPark()则对应object.notify()。

线程差不多就聊到这了,感觉理解得还是比较到位的。

冷啊,还有JVM相关几个机制以及Java并发包,最后再聊聊算法。

<coffee3 end 2018/09/06 22:42>

不是coffee time,也来继续更更。动物真的犯有多动症,要是一整天不玩游戏、不敲键盘、不说话,那简直是闷,大脑就容易各种瞎想。还没电面便收到阿里不合适的邮件,倒是还有点开心,整理的过程中愈加感觉实力还不够,节约一次机会也好,坏处便是有所松懈了(虚假地缓了几天)。发现自己大约两周前改的新简历真的有毒,没命中过一次。可能是从5页变成3页根本展现不了我的才华吧。严重怀疑人家问我一个问题答得不好时会怀疑我简历造假,毕竟简历上写了做过很多项目,且提到知识面也不少。妈的,5页变成3页主要是把大部分很一般的项目介绍略去了,我迷信,我要加上去。一旦人家感觉你简历有水分,那么后面就算你发挥不错,别人也会打个问号。真的,人类的通病,思维上的惯性。啊啊啊,所以我还是适合5页的简历,毕竟路途坎坷。简历长点,人家看着会觉得烦,但至少你能表达得更多,不至于一笔带过让人怀疑。这也是个取舍的问题了,需要掌握好度。好的,就这样。

应该有个这样的俗语:打肿脸装文青。文青真的是个费钱的头衔,程序员的一面根本养不起我偶尔装文青的一面,所以还是要努力提升赚钱呐。

<插曲 end 2018/09/09 21:58>

好久没来星爸爸了,氛围还是渲染得不错,喧而不吵。继续。

心绪喧嚷写出的文字也会带有焦虑。嗯呐,状态不好的时候就不要写好了。上回聊线程,还少聊了点东西——线程池。

线程池,之前一直觉得没啥需要了解的,如其名——线程池,不过是个线程缓冲的池子罢了,维持线程的最大数目,多了需要排队等候。

星爸爸戴着耳机电脑摊腿上,手摊扶手,看着线程池,跟着引进BlockingQueue,时间安然流逝。以前不喜欢看这么些无聊的源码,但现在发现,比起JVM许多枯燥的概念,这些JUC里的实现源码还是有点趣味。

Doug Lea ~

<coffee4 end 2018/09/10 22:25>

不知道我今天从哪看起,反正看着看着,看到HashMap源码去了。原理好像说起来很简单,列表+链表的方式实现,键值对进来后对key进行hash算法放到列表指定位置,若冲突则以链表形式链接后当前位置对应链表的后面,若链表过长(超过8)则将链表转换成红黑树。填充因子0.75,默认初始容量16,当前长度超过容量*填充因子后进行双倍扩容。

就这么些,实现起来却很是麻烦,洋洋洒洒算上注释2000多行代码,各种位运算,正看到resize()扩容那,待看懂中……

发现知识真的泛,Android。彷佛一个方法,里面又执行了无数方法,看线程池中,看起了BlockingQueue,到ArrayList,到HashMap,零零散散地看,待点成线。

<coffee5 end 2018/09/11 21:50>

红黑树好难理解。HashMap其他代码倒还好看懂,扩容巧妙的用了&运算符判断新高位是否为1(二进制),如果是1就往后挪半段(恰好是新增的段),这样基本可以平均的分配以前的节点又只需要很少的计算量。哈希碰撞转链表也很简单,几次判空,然后遍历next节点插入即可。链表过长(链表长度大于8且总容量大于64)转红黑树,蛋疼了,又不得不面对一个曾经碰到过几次的问题——红黑树的原理与实现。不打算绕过,虽然几乎不会问红黑树实现,不过算法作为一个职业生涯必修的课程,怎么也逃不开的,打算这次就把红黑树理解透。几天也没关系。

我们常常觉得几天做一件看起来不大的事很奢侈,常常觉得几个月完不成什么就算了。但其实,某些我们期望一天完成的东西即使最后花了10天才完成,某些我们期望三个月完成的东西最后花了一年多才完成,其结果依然也远好于一直搁置着。追求过高或许自不量力,但当目标是10分时,尽管一次次只能拿到6、7分,但也远好于无追求永远5分过。引用一句友邻引用的话:我们常常高估了一年能干的事情,却常常低估了十年能干成的事情。尽管我每次细思极恐,十年是个怎样的跨度?傲骨寒窗也才十年。二十多岁,许多行业的人已经谱写出一生中最优秀作品,作家、诗人、音乐家、歌手、画家、职业运动员、电竞选手、武将…几乎所有创作行业、竞技行业。除此之外,科学领域亦是如此,数学家、物理学家、计算机专家…所以,可以说二十多岁是最宝贵的年龄,该崭露头角的在这个年纪也该展露了。再过十年可就是三十加了,真是个悲伤的故事。

「什么都不说 像来自天空 轻如指尖的触痛」

舒适的环境、美味的食物、充分的睡眠。Big Nerd Ranch 推荐的最佳学习环境。

<coffee6 end 2018/09/12 21:54>

网络上哗众取宠的内容还是太多啊。跟着大厚本《算法》看第三章——查找,从有序数组到链表再到二叉树,看到2-3树时终于对红黑树有了眉目。红黑树的本质就是2-3树,而2-3树的目的是为了构建规则简单的平衡树。2-3树在二叉树的基础上允许一个节点有两个键,而两个键的节点允许有3个子节点(左、中、右),这样以来,每次插入新键就可以通过简单的变换规则维持树的平衡。改天看完理解透了写篇博客分享下,实在受不了网上普遍对红黑树定义的“五大性质”,如同synchronized强行三大性质一样,这样的定义对于学习者毫无帮助,反而会诱导其走入一个误区。红黑树的理解,首先得知道红色节点是为了表示父节点到该节点的路径为红色(默认路径为黑色);我们将红色路径画平(目的是无视红色路径的高度,实际上等同于一个节点上有两个键的2-3树),得到的树将是一颗完全平衡的树;不能有连续两条红色路径(因为当有连续两条红色路径时,我们可以通过简单的变换规则化简路径关联的节点,这是红黑树维持插入平衡的重要原因)。

<插曲 end 2018/09/15 12:52>

so long~

刚刚收到网易电面,感觉表现挺好~日常开发相关的问题问得还挺多的,改天整理这份笔记时再加个条目:用户体验优化。想起了一本书,大概叫“50 Android hacks”,50个Android优化点。

10天未更已经不知道要聊什么了。红黑树还是没彻底吃透,要跟着HashMap的源码看看是通过什么来比较key并排序的了。前面讲到的地方有一处错误:多个AsyncTask走的是一个线程。不对,AsyncTask是通过线程池来分配线程的,从目前源码看至少有两个线程。

刚刚长了点见识,多个RecyclerView如果Item一致的话,是可以复用的,为多个RecyclerView设置同一个RecyclerViewPool即可。Keep study,该粗略看点热门库的源码了,以前看源码总是容易陷入其中,最后不了了之。秋天的室内开空调还是有点冷,外面是最舒服的。

<coffee7 end 2018/09/26 20:53>

网易二面。紧张得很。同一家咖啡馆,周五有点吵。面完一片空白,只剩不完整的片段记忆。问得比一面时深,好些没答上,面完赶紧查。面试时遇不会的我是直接说“不大了解”的,有两个不大了解的凭预判居然没说错。艾玛,感觉机会不大,好多东西需要巩固,keep study 啊。

<coffee8 end 2018/09/28 20:39>

又过了好久,2018年10月20 06:53,醒了好久了。空空的,不能再入睡,好像也找不到好吸收的精神粮食,索性将这篇续更的文章告一段落。网易二面居然过了!简直是意外+惊喜,知道自己处于前所未有的高度上(在求职这件事上),每往前一步都是突破,不敢对自己有任何期望。国庆后一天内面了第三面(技术)和第四面(HR),之前以为三面是对前两面的技术确认(毕竟电面不如现面来得实在),没想到!!三面居然问得比二面还深!对图片相关的技术问得很深,http、数据库也附带问了(虽然我答得很差,但还是感觉这两个问得有点刁钻),唯独没有涉及到JVM和算法(现在想想,要是问点算法,倒是还挺有机会,国庆还特意把快排吃透了一遍。http真是个诡异的东西,经常接触,但是日常开发中改动极少,也有主动学这方面的东西,但面试碰上就是答不上)。三面面完我知道大概率凉了,不过不到最后一刻,不会骄傲也不会放弃,让我等下HR面(虽然猜测大概率是走个流程,但还是抱有一丝幻想),中规中矩地面完,就想快点出结果。失败或者幸运降临,都能接受,我已经正常发挥了。两天后晚些时候终于收到了邮件(我知道好事往往会通过电话,而谢谢参与只会通过邮件…而我迫不及待想要知道,所以不时查看邮件)。

比较意外的是,我很沮丧。尽管我知道大概率是这样的结果,尽管我知道走到这一步已经很不错也很幸运了,就好像世界杯的克罗地亚(法克大战输也输得服气)。但我还是很沮丧。这可能是我离幻想最近的一步了,我心爱的网易云。以后再也不会有如此好运,再也不会,岁月的流逝让我愈发感概,太多美好的东西在发生的那一时刻抓不住便永远抓不住了(想起了朴树说的灵感),哀叹自己运气好的时候技术不足,太美的事情总是不会成真。

「I guess both things where, Too good or bad to be true」

hey, whale.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容